| 134 | } |
| 135 | |
| 136 | std::optional<int> library_bitness(const wchar_t *path) { |
| 137 | auto h_file = CreateFile(path, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr); |
| 138 | if (h_file == INVALID_HANDLE_VALUE) |
| 139 | return {}; |
| 140 | auto h_map = CreateFileMapping(h_file, nullptr, PAGE_READONLY, 0, 0, nullptr); |
| 141 | if (h_map == INVALID_HANDLE_VALUE) { |
| 142 | CloseHandle(h_file); |
| 143 | return {}; |
| 144 | } |
| 145 | void *map_addr = MapViewOfFileEx(h_map, FILE_MAP_READ, 0, 0, 0, nullptr); |
| 146 | auto pe_hdr = ImageNtHeader(map_addr); |
| 147 | auto machine = pe_hdr->FileHeader.Machine; |
| 148 | CloseHandle(h_map); |
| 149 | CloseHandle(h_file); |
| 150 | switch (machine) { |
| 151 | case IMAGE_FILE_MACHINE_I386: |
| 152 | default: |
| 153 | return 32; |
| 154 | case IMAGE_FILE_MACHINE_IA64: |
| 155 | case IMAGE_FILE_MACHINE_AMD64: |
| 156 | return 64; |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | template <typename T> static void extract_function(T &target, HMODULE handle, const char *proc_name) { |
| 161 | target = reinterpret_cast<T>(GetProcAddress(handle, proc_name)); |