1/* 2 * Copyright (c) 2021 The Khronos Group Inc. 3 * Copyright (c) 2021 Valve Corporation 4 * Copyright (c) 2021 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Charles Giessen <charles@lunarg.com> 26 */ 27 28// This needs to be defined first, or else we'll get redefinitions on NTSTATUS values 29#if defined(_WIN32) 30#define UMDF_USING_NTSTATUS 31#include <ntstatus.h> 32#endif 33 34#include "shim.h" 35 36#include "detours.h" 37 38static PlatformShim platform_shim; 39 40extern "C" { 41 42static LibraryWrapper gdi32_dll; 43 44using PFN_GetSidSubAuthority = PDWORD(__stdcall *)(PSID pSid, DWORD nSubAuthority); 45static PFN_GetSidSubAuthority fpGetSidSubAuthority = GetSidSubAuthority; 46 47PDWORD __stdcall ShimGetSidSubAuthority(PSID, DWORD) { return &platform_shim.elevation_level; } 48 49static PFN_LoaderEnumAdapters2 fpEnumAdapters2 = nullptr; 50static PFN_LoaderQueryAdapterInfo fpQueryAdapterInfo = nullptr; 51 52NTSTATUS APIENTRY ShimEnumAdapters2(LoaderEnumAdapters2 *adapters) { 53 if (adapters == nullptr) { 54 return STATUS_INVALID_PARAMETER; 55 } 56 if (platform_shim.d3dkmt_adapters.size() == 0) { 57 if (adapters->adapters != nullptr) adapters->adapter_count = 0; 58 return STATUS_SUCCESS; 59 } 60 if (adapters->adapters != nullptr) { 61 for (size_t i = 0; i < platform_shim.d3dkmt_adapters.size(); i++) { 62 adapters->adapters[i].handle = platform_shim.d3dkmt_adapters[i].hAdapter; 63 adapters->adapters[i].luid = platform_shim.d3dkmt_adapters[i].adapter_luid; 64 } 65 adapters->adapter_count = static_cast<ULONG>(platform_shim.d3dkmt_adapters.size()); 66 } else { 67 adapters->adapter_count = static_cast<ULONG>(platform_shim.d3dkmt_adapters.size()); 68 } 69 return STATUS_SUCCESS; 70} 71NTSTATUS APIENTRY ShimQueryAdapterInfo(const LoaderQueryAdapterInfo *query_info) { 72 if (query_info == nullptr || query_info->private_data == nullptr) { 73 return STATUS_INVALID_PARAMETER; 74 } 75 auto handle = query_info->handle; 76 auto it = std::find_if(platform_shim.d3dkmt_adapters.begin(), platform_shim.d3dkmt_adapters.end(), 77 [handle](D3DKMT_Adapter const &adapter) { return handle == adapter.hAdapter; }); 78 if (it == platform_shim.d3dkmt_adapters.end()) { 79 return STATUS_INVALID_PARAMETER; 80 } 81 auto &adapter = *it; 82 auto *reg_info = reinterpret_cast<LoaderQueryRegistryInfo *>(query_info->private_data); 83 84 std::vector<std::wstring> *paths = nullptr; 85 if (wcsstr(reg_info->value_name, L"DriverName") != nullptr) { // looking for drivers 86 paths = &adapter.driver_paths; 87 } else if (wcsstr(reg_info->value_name, L"ImplicitLayers") != nullptr) { // looking for implicit layers 88 paths = &adapter.implicit_layer_paths; 89 } else if (wcsstr(reg_info->value_name, L"ExplicitLayers") != nullptr) { // looking for explicit layers 90 paths = &adapter.explicit_layer_paths; 91 } 92 93 reg_info->status = LOADER_QUERY_REGISTRY_STATUS_SUCCESS; 94 if (reg_info->output_value_size == 0) { 95 ULONG size = 2; // final null terminator 96 for (auto const &path : *paths) size = static_cast<ULONG>(path.length() * sizeof(wchar_t)); 97 // size in bytes, so multiply path size by two and add 2 for the null terminator 98 reg_info->output_value_size = size; 99 if (size != 2) { 100 // only want to write data if there is path data to write 101 reg_info->status = LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW; 102 } 103 } else if (reg_info->output_value_size > 2) { 104 size_t index = 0; 105 for (auto const &path : *paths) { 106 for (auto w : path) { 107 reg_info->output_string[index++] = w; 108 } 109 reg_info->output_string[index++] = L'\0'; 110 } 111 // make sure there is a null terminator 112 reg_info->output_string[index++] = L'\0'; 113 114 reg_info->status = LOADER_QUERY_REGISTRY_STATUS_SUCCESS; 115 } 116 117 return STATUS_SUCCESS; 118} 119 120// clang-format off 121static CONFIGRET(WINAPI *REAL_CM_Get_Device_ID_List_SizeW)(PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags) = CM_Get_Device_ID_List_SizeW; 122static CONFIGRET(WINAPI *REAL_CM_Get_Device_ID_ListW)(PCWSTR pszFilter, PZZWSTR Buffer, ULONG BufferLen, ULONG ulFlags) = CM_Get_Device_ID_ListW; 123static CONFIGRET(WINAPI *REAL_CM_Locate_DevNodeW)(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags) = CM_Locate_DevNodeW; 124static CONFIGRET(WINAPI *REAL_CM_Get_DevNode_Status)(PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst, ULONG ulFlags) = CM_Get_DevNode_Status; 125static CONFIGRET(WINAPI *REAL_CM_Get_Device_IDW)(DEVINST dnDevInst, PWSTR Buffer, ULONG BufferLen, ULONG ulFlags) = CM_Get_Device_IDW; 126static CONFIGRET(WINAPI *REAL_CM_Get_Child)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags) = CM_Get_Child; 127static CONFIGRET(WINAPI *REAL_CM_Get_DevNode_Registry_PropertyW)(DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType, PVOID Buffer, PULONG pulLength, ULONG ulFlags) = CM_Get_DevNode_Registry_PropertyW; 128static CONFIGRET(WINAPI *REAL_CM_Get_Sibling)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags) = CM_Get_Sibling; 129// clang-format on 130 131CONFIGRET WINAPI SHIM_CM_Get_Device_ID_List_SizeW(PULONG pulLen, [[maybe_unused]] PCWSTR pszFilter, 132 [[maybe_unused]] ULONG ulFlags) { 133 if (pulLen == nullptr) { 134 return CR_INVALID_POINTER; 135 } 136 *pulLen = static_cast<ULONG>(platform_shim.CM_device_ID_list.size()); 137 return CR_SUCCESS; 138} 139CONFIGRET WINAPI SHIM_CM_Get_Device_ID_ListW([[maybe_unused]] PCWSTR pszFilter, PZZWSTR Buffer, ULONG BufferLen, 140 [[maybe_unused]] ULONG ulFlags) { 141 if (Buffer != NULL) { 142 if (BufferLen < platform_shim.CM_device_ID_list.size()) return CR_BUFFER_SMALL; 143 for (size_t i = 0; i < BufferLen; i++) { 144 Buffer[i] = platform_shim.CM_device_ID_list[i]; 145 } 146 } 147 return CR_SUCCESS; 148} 149// TODO 150CONFIGRET WINAPI SHIM_CM_Locate_DevNodeW(PDEVINST, DEVINSTID_W, ULONG) { return CR_FAILURE; } 151// TODO 152CONFIGRET WINAPI SHIM_CM_Get_DevNode_Status(PULONG, PULONG, DEVINST, ULONG) { return CR_FAILURE; } 153// TODO 154CONFIGRET WINAPI SHIM_CM_Get_Device_IDW(DEVINST, PWSTR, ULONG, ULONG) { return CR_FAILURE; } 155// TODO 156CONFIGRET WINAPI SHIM_CM_Get_Child(PDEVINST, DEVINST, ULONG) { return CR_FAILURE; } 157// TODO 158CONFIGRET WINAPI SHIM_CM_Get_DevNode_Registry_PropertyW(DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG) { return CR_FAILURE; } 159// TODO 160CONFIGRET WINAPI SHIM_CM_Get_Sibling(PDEVINST, DEVINST, ULONG) { return CR_FAILURE; } 161 162static LibraryWrapper dxgi_module; 163typedef HRESULT(APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory); 164 165PFN_CreateDXGIFactory1 RealCreateDXGIFactory1; 166 167HRESULT __stdcall ShimGetDesc1(IDXGIAdapter1 *pAdapter, 168 /* [annotation][out] */ 169 _Out_ DXGI_ADAPTER_DESC1 *pDesc) { 170 if (pAdapter == nullptr || pDesc == nullptr) return DXGI_ERROR_INVALID_CALL; 171 172 for (const auto &[index, adapter] : platform_shim.dxgi_adapters) { 173 if (&adapter.adapter_instance == pAdapter) { 174 *pDesc = adapter.desc1; 175 return S_OK; 176 } 177 } 178 return DXGI_ERROR_INVALID_CALL; 179} 180ULONG __stdcall ShimIDXGIFactory1Release(IDXGIFactory1 *) { return S_OK; } 181ULONG __stdcall ShimIDXGIFactory6Release(IDXGIFactory6 *) { return S_OK; } 182ULONG __stdcall ShimRelease(IDXGIAdapter1 *) { return S_OK; } 183 184IDXGIAdapter1 *setup_and_get_IDXGIAdapter1(DXGIAdapter &adapter) { 185 adapter.adapter_vtbl_instance.GetDesc1 = ShimGetDesc1; 186 adapter.adapter_vtbl_instance.Release = ShimRelease; 187 adapter.adapter_instance.lpVtbl = &adapter.adapter_vtbl_instance; 188 return &adapter.adapter_instance; 189} 190 191HRESULT __stdcall ShimEnumAdapters1_1([[maybe_unused]] IDXGIFactory1 *This, 192 /* [in] */ UINT Adapter, 193 /* [annotation][out] */ 194 _COM_Outptr_ IDXGIAdapter1 **ppAdapter) { 195 if (Adapter >= platform_shim.dxgi_adapters.size()) { 196 return DXGI_ERROR_INVALID_CALL; 197 } 198 if (ppAdapter != nullptr) { 199 *ppAdapter = setup_and_get_IDXGIAdapter1(platform_shim.dxgi_adapters.at(Adapter)); 200 } 201 return S_OK; 202} 203 204HRESULT __stdcall ShimEnumAdapters1_6([[maybe_unused]] IDXGIFactory6 *This, 205 /* [in] */ UINT Adapter, 206 /* [annotation][out] */ 207 _COM_Outptr_ IDXGIAdapter1 **ppAdapter) { 208 if (Adapter >= platform_shim.dxgi_adapters.size()) { 209 return DXGI_ERROR_INVALID_CALL; 210 } 211 if (ppAdapter != nullptr) { 212 *ppAdapter = setup_and_get_IDXGIAdapter1(platform_shim.dxgi_adapters.at(Adapter)); 213 } 214 return S_OK; 215} 216 217HRESULT __stdcall ShimEnumAdapterByGpuPreference([[maybe_unused]] IDXGIFactory6 *This, _In_ UINT Adapter, 218 [[maybe_unused]] _In_ DXGI_GPU_PREFERENCE GpuPreference, 219 [[maybe_unused]] _In_ REFIID riid, _COM_Outptr_ void **ppvAdapter) { 220 if (Adapter >= platform_shim.dxgi_adapters.size()) { 221 return DXGI_ERROR_NOT_FOUND; 222 } 223 // loader always uses DXGI_GPU_PREFERENCE_UNSPECIFIED 224 // Update the shim if this isn't the case 225 assert(GpuPreference == DXGI_GPU_PREFERENCE::DXGI_GPU_PREFERENCE_UNSPECIFIED && 226 "Test shim assumes the GpuPreference is unspecified."); 227 if (ppvAdapter != nullptr) { 228 *ppvAdapter = setup_and_get_IDXGIAdapter1(platform_shim.dxgi_adapters.at(Adapter)); 229 } 230 return S_OK; 231} 232 233static IDXGIFactory1 *get_IDXGIFactory1() { 234 static IDXGIFactory1Vtbl vtbl{}; 235 vtbl.EnumAdapters1 = ShimEnumAdapters1_1; 236 vtbl.Release = ShimIDXGIFactory1Release; 237 static IDXGIFactory1 factory{}; 238 factory.lpVtbl = &vtbl; 239 return &factory; 240} 241 242static IDXGIFactory6 *get_IDXGIFactory6() { 243 static IDXGIFactory6Vtbl vtbl{}; 244 vtbl.EnumAdapters1 = ShimEnumAdapters1_6; 245 vtbl.EnumAdapterByGpuPreference = ShimEnumAdapterByGpuPreference; 246 vtbl.Release = ShimIDXGIFactory6Release; 247 static IDXGIFactory6 factory{}; 248 factory.lpVtbl = &vtbl; 249 return &factory; 250} 251 252HRESULT __stdcall ShimCreateDXGIFactory1(REFIID riid, void **ppFactory) { 253 if (riid == IID_IDXGIFactory1) { 254 auto *factory = get_IDXGIFactory1(); 255 *ppFactory = factory; 256 return S_OK; 257 } 258 if (riid == IID_IDXGIFactory6) { 259 auto *factory = get_IDXGIFactory6(); 260 *ppFactory = factory; 261 return S_OK; 262 } 263 assert(false && "new riid, update shim code to handle"); 264 return S_FALSE; 265} 266 267// Windows Registry shims 268using PFN_RegOpenKeyExA = LSTATUS(__stdcall *)(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); 269static PFN_RegOpenKeyExA fpRegOpenKeyExA = RegOpenKeyExA; 270using PFN_RegQueryValueExA = LSTATUS(__stdcall *)(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, 271 LPDWORD lpcbData); 272static PFN_RegQueryValueExA fpRegQueryValueExA = RegQueryValueExA; 273using PFN_RegEnumValueA = LSTATUS(__stdcall *)(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcchValueName, 274 LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); 275static PFN_RegEnumValueA fpRegEnumValueA = RegEnumValueA; 276 277using PFN_RegCloseKey = LSTATUS(__stdcall *)(HKEY hKey); 278static PFN_RegCloseKey fpRegCloseKey = RegCloseKey; 279 280LSTATUS __stdcall ShimRegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, [[maybe_unused]] DWORD ulOptions, 281 [[maybe_unused]] REGSAM samDesired, PHKEY phkResult) { 282 if (HKEY_LOCAL_MACHINE != hKey && HKEY_CURRENT_USER != hKey) return ERROR_BADKEY; 283 std::string hive = ""; 284 if (HKEY_LOCAL_MACHINE == hKey) 285 hive = "HKEY_LOCAL_MACHINE"; 286 else if (HKEY_CURRENT_USER == hKey) 287 hive = "HKEY_CURRENT_USER"; 288 if (hive == "") return ERROR_ACCESS_DENIED; 289 290 platform_shim.created_keys.emplace_back(platform_shim.created_key_count++, hive + "\\" + lpSubKey); 291 *phkResult = platform_shim.created_keys.back().get(); 292 return 0; 293} 294const std::string *get_path_of_created_key(HKEY hKey) { 295 for (const auto &key : platform_shim.created_keys) { 296 if (key.key == hKey) { 297 return &key.path; 298 } 299 } 300 return nullptr; 301} 302std::vector<RegistryEntry> *get_registry_vector(std::string const &path) { 303 if (path == "HKEY_LOCAL_MACHINE\\" VK_DRIVERS_INFO_REGISTRY_LOC) return &platform_shim.hkey_local_machine_drivers; 304 if (path == "HKEY_LOCAL_MACHINE\\" VK_ELAYERS_INFO_REGISTRY_LOC) return &platform_shim.hkey_local_machine_explicit_layers; 305 if (path == "HKEY_LOCAL_MACHINE\\" VK_ILAYERS_INFO_REGISTRY_LOC) return &platform_shim.hkey_local_machine_implicit_layers; 306 if (path == "HKEY_CURRENT_USER\\" VK_ELAYERS_INFO_REGISTRY_LOC) return &platform_shim.hkey_current_user_explicit_layers; 307 if (path == "HKEY_CURRENT_USER\\" VK_ILAYERS_INFO_REGISTRY_LOC) return &platform_shim.hkey_current_user_implicit_layers; 308 if (path == "HKEY_LOCAL_MACHINE\\" VK_SETTINGS_INFO_REGISTRY_LOC) return &platform_shim.hkey_local_machine_settings; 309 if (path == "HKEY_CURRENT_USER\\" VK_SETTINGS_INFO_REGISTRY_LOC) return &platform_shim.hkey_current_user_settings; 310 return nullptr; 311} 312LSTATUS __stdcall ShimRegQueryValueExA(HKEY, LPCSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD) { 313 // TODO: 314 return ERROR_SUCCESS; 315} 316LSTATUS __stdcall ShimRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcchValueName, 317 [[maybe_unused]] LPDWORD lpReserved, [[maybe_unused]] LPDWORD lpType, LPBYTE lpData, 318 LPDWORD lpcbData) { 319 const std::string *path = get_path_of_created_key(hKey); 320 if (path == nullptr) return ERROR_NO_MORE_ITEMS; 321 322 const auto *location_ptr = get_registry_vector(*path); 323 if (location_ptr == nullptr) return ERROR_NO_MORE_ITEMS; 324 const auto &location = *location_ptr; 325 if (dwIndex >= location.size()) return ERROR_NO_MORE_ITEMS; 326 327 if (*lpcchValueName < location[dwIndex].name.size()) return ERROR_NO_MORE_ITEMS; 328 for (size_t i = 0; i < location[dwIndex].name.size(); i++) { 329 lpValueName[i] = location[dwIndex].name[i]; 330 } 331 lpValueName[location[dwIndex].name.size()] = '\0'; 332 *lpcchValueName = static_cast<DWORD>(location[dwIndex].name.size() + 1); 333 if (*lpcbData < sizeof(DWORD)) return ERROR_NO_MORE_ITEMS; 334 DWORD *lpcbData_dword = reinterpret_cast<DWORD *>(lpData); 335 *lpcbData_dword = location[dwIndex].value; 336 *lpcbData = sizeof(DWORD); 337 return ERROR_SUCCESS; 338} 339LSTATUS __stdcall ShimRegCloseKey(HKEY hKey) { 340 for (size_t i = 0; i < platform_shim.created_keys.size(); i++) { 341 if (platform_shim.created_keys[i].get() == hKey) { 342 platform_shim.created_keys.erase(platform_shim.created_keys.begin() + i); 343 return ERROR_SUCCESS; 344 } 345 } 346 return ERROR_SUCCESS; 347} 348 349// Windows app package shims 350using PFN_GetPackagesByPackageFamily = LONG(WINAPI *)(PCWSTR, UINT32 *, PWSTR *, UINT32 *, WCHAR *); 351static PFN_GetPackagesByPackageFamily fpGetPackagesByPackageFamily = GetPackagesByPackageFamily; 352using PFN_GetPackagePathByFullName = LONG(WINAPI *)(PCWSTR, UINT32 *, PWSTR); 353static PFN_GetPackagePathByFullName fpGetPackagePathByFullName = GetPackagePathByFullName; 354 355static constexpr wchar_t package_full_name[] = L"ThisIsARandomStringSinceTheNameDoesn'tMatter"; 356LONG WINAPI ShimGetPackagesByPackageFamily(_In_ PCWSTR packageFamilyName, _Inout_ UINT32 *count, 357 _Out_writes_opt_(*count) PWSTR *packageFullNames, _Inout_ UINT32 *bufferLength, 358 _Out_writes_opt_(*bufferLength) WCHAR *buffer) { 359 if (!packageFamilyName || !count || !bufferLength) return ERROR_INVALID_PARAMETER; 360 if (!platform_shim.app_package_path.empty() && wcscmp(packageFamilyName, L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe") == 0) { 361 if (*count > 0 && !packageFullNames) return ERROR_INVALID_PARAMETER; 362 if (*bufferLength > 0 && !buffer) return ERROR_INVALID_PARAMETER; 363 if (*count > 1) return ERROR_INVALID_PARAMETER; 364 bool too_small = *count < 1 || *bufferLength < ARRAYSIZE(package_full_name); 365 *count = 1; 366 *bufferLength = ARRAYSIZE(package_full_name); 367 if (too_small) return ERROR_INSUFFICIENT_BUFFER; 368 369 for (size_t i = 0; i < sizeof(package_full_name) / sizeof(wchar_t); i++) { 370 if (i >= *bufferLength) { 371 break; 372 } 373 buffer[i] = package_full_name[i]; 374 } 375 *packageFullNames = buffer; 376 return 0; 377 } 378 *count = 0; 379 *bufferLength = 0; 380 return 0; 381} 382 383LONG WINAPI ShimGetPackagePathByFullName(_In_ PCWSTR packageFullName, _Inout_ UINT32 *pathLength, 384 _Out_writes_opt_(*pathLength) PWSTR path) { 385 if (!packageFullName || !pathLength) return ERROR_INVALID_PARAMETER; 386 if (*pathLength > 0 && !path) return ERROR_INVALID_PARAMETER; 387 if (wcscmp(packageFullName, package_full_name) != 0) { 388 *pathLength = 0; 389 return 0; 390 } 391 if (*pathLength < platform_shim.app_package_path.size() + 1) { 392 *pathLength = static_cast<UINT32>(platform_shim.app_package_path.size() + 1); 393 return ERROR_INSUFFICIENT_BUFFER; 394 } 395 for (size_t i = 0; i < platform_shim.app_package_path.length(); i++) { 396 if (i >= *pathLength) { 397 break; 398 } 399 path[i] = platform_shim.app_package_path.c_str()[i]; 400 } 401 return 0; 402} 403 404// Initialization 405void WINAPI DetourFunctions() { 406 if (!gdi32_dll) { 407 gdi32_dll = LibraryWrapper("gdi32.dll"); 408 fpEnumAdapters2 = gdi32_dll.get_symbol("D3DKMTEnumAdapters2"); 409 if (fpEnumAdapters2 == nullptr) { 410 std::cerr << "Failed to load D3DKMTEnumAdapters2\n"; 411 return; 412 } 413 fpQueryAdapterInfo = gdi32_dll.get_symbol("D3DKMTQueryAdapterInfo"); 414 if (fpQueryAdapterInfo == nullptr) { 415 std::cerr << "Failed to load D3DKMTQueryAdapterInfo\n"; 416 return; 417 } 418 } 419 if (!dxgi_module) { 420 TCHAR systemPath[MAX_PATH] = ""; 421 GetSystemDirectory(systemPath, MAX_PATH); 422 StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll")); 423 dxgi_module = LibraryWrapper(systemPath); 424 RealCreateDXGIFactory1 = dxgi_module.get_symbol("CreateDXGIFactory1"); 425 if (RealCreateDXGIFactory1 == nullptr) { 426 std::cerr << "Failed to load CreateDXGIFactory1\n"; 427 } 428 } 429 430 DetourRestoreAfterWith(); 431 432 DetourTransactionBegin(); 433 DetourUpdateThread(GetCurrentThread()); 434 DetourAttach(&(PVOID &)fpGetSidSubAuthority, (PVOID)ShimGetSidSubAuthority); 435 DetourAttach(&(PVOID &)fpEnumAdapters2, (PVOID)ShimEnumAdapters2); 436 DetourAttach(&(PVOID &)fpQueryAdapterInfo, (PVOID)ShimQueryAdapterInfo); 437 DetourAttach(&(PVOID &)REAL_CM_Get_Device_ID_List_SizeW, (PVOID)SHIM_CM_Get_Device_ID_List_SizeW); 438 DetourAttach(&(PVOID &)REAL_CM_Get_Device_ID_ListW, (PVOID)SHIM_CM_Get_Device_ID_ListW); 439 DetourAttach(&(PVOID &)REAL_CM_Get_Device_ID_ListW, (PVOID)SHIM_CM_Get_Device_ID_ListW); 440 DetourAttach(&(PVOID &)REAL_CM_Locate_DevNodeW, (PVOID)SHIM_CM_Locate_DevNodeW); 441 DetourAttach(&(PVOID &)REAL_CM_Get_DevNode_Status, (PVOID)SHIM_CM_Get_DevNode_Status); 442 DetourAttach(&(PVOID &)REAL_CM_Get_Device_IDW, (PVOID)SHIM_CM_Get_Device_IDW); 443 DetourAttach(&(PVOID &)REAL_CM_Get_Child, (PVOID)SHIM_CM_Get_Child); 444 DetourAttach(&(PVOID &)REAL_CM_Get_DevNode_Registry_PropertyW, (PVOID)SHIM_CM_Get_DevNode_Registry_PropertyW); 445 DetourAttach(&(PVOID &)REAL_CM_Get_Sibling, (PVOID)SHIM_CM_Get_Sibling); 446 DetourAttach(&(PVOID &)RealCreateDXGIFactory1, (PVOID)ShimCreateDXGIFactory1); 447 DetourAttach(&(PVOID &)fpRegOpenKeyExA, (PVOID)ShimRegOpenKeyExA); 448 DetourAttach(&(PVOID &)fpRegQueryValueExA, (PVOID)ShimRegQueryValueExA); 449 DetourAttach(&(PVOID &)fpRegEnumValueA, (PVOID)ShimRegEnumValueA); 450 DetourAttach(&(PVOID &)fpRegCloseKey, (PVOID)ShimRegCloseKey); 451 DetourAttach(&(PVOID &)fpGetPackagesByPackageFamily, (PVOID)ShimGetPackagesByPackageFamily); 452 DetourAttach(&(PVOID &)fpGetPackagePathByFullName, (PVOID)ShimGetPackagePathByFullName); 453 LONG error = DetourTransactionCommit(); 454 455 if (error != NO_ERROR) { 456 std::cerr << "simple" << DETOURS_STRINGIFY(DETOURS_BITS) << ".dll:" 457 << " Error detouring function(): " << error << "\n"; 458 } 459} 460 461void DetachFunctions() { 462 DetourTransactionBegin(); 463 DetourUpdateThread(GetCurrentThread()); 464 DetourDetach(&(PVOID &)fpGetSidSubAuthority, (PVOID)ShimGetSidSubAuthority); 465 DetourDetach(&(PVOID &)fpEnumAdapters2, (PVOID)ShimEnumAdapters2); 466 DetourDetach(&(PVOID &)fpQueryAdapterInfo, (PVOID)ShimQueryAdapterInfo); 467 DetourDetach(&(PVOID &)REAL_CM_Get_Device_ID_List_SizeW, (PVOID)SHIM_CM_Get_Device_ID_List_SizeW); 468 DetourDetach(&(PVOID &)REAL_CM_Get_Device_ID_ListW, (PVOID)SHIM_CM_Get_Device_ID_ListW); 469 DetourDetach(&(PVOID &)REAL_CM_Locate_DevNodeW, (PVOID)SHIM_CM_Locate_DevNodeW); 470 DetourDetach(&(PVOID &)REAL_CM_Get_DevNode_Status, (PVOID)SHIM_CM_Get_DevNode_Status); 471 DetourDetach(&(PVOID &)REAL_CM_Get_Device_IDW, (PVOID)SHIM_CM_Get_Device_IDW); 472 DetourDetach(&(PVOID &)REAL_CM_Get_Child, (PVOID)SHIM_CM_Get_Child); 473 DetourDetach(&(PVOID &)REAL_CM_Get_DevNode_Registry_PropertyW, (PVOID)SHIM_CM_Get_DevNode_Registry_PropertyW); 474 DetourDetach(&(PVOID &)REAL_CM_Get_Sibling, (PVOID)SHIM_CM_Get_Sibling); 475 DetourDetach(&(PVOID &)RealCreateDXGIFactory1, (PVOID)ShimCreateDXGIFactory1); 476 DetourDetach(&(PVOID &)fpRegOpenKeyExA, (PVOID)ShimRegOpenKeyExA); 477 DetourDetach(&(PVOID &)fpRegQueryValueExA, (PVOID)ShimRegQueryValueExA); 478 DetourDetach(&(PVOID &)fpRegEnumValueA, (PVOID)ShimRegEnumValueA); 479 DetourDetach(&(PVOID &)fpRegCloseKey, (PVOID)ShimRegCloseKey); 480 DetourDetach(&(PVOID &)fpGetPackagesByPackageFamily, (PVOID)ShimGetPackagesByPackageFamily); 481 DetourDetach(&(PVOID &)fpGetPackagePathByFullName, (PVOID)ShimGetPackagePathByFullName); 482 DetourTransactionCommit(); 483} 484 485BOOL WINAPI DllMain([[maybe_unused]] HINSTANCE hinst, DWORD dwReason, [[maybe_unused]] LPVOID reserved) { 486 if (DetourIsHelperProcess()) { 487 return TRUE; 488 } 489 490 if (dwReason == DLL_PROCESS_ATTACH) { 491 DetourFunctions(); 492 } else if (dwReason == DLL_PROCESS_DETACH) { 493 DetachFunctions(); 494 } 495 return TRUE; 496} 497FRAMEWORK_EXPORT PlatformShim *get_platform_shim(std::vector<fs::FolderManager> *folders) { 498 platform_shim = PlatformShim(folders); 499 return &platform_shim; 500} 501} 502