diff --git a/patches/win32u-GPU_properties/0001-win32u-Set-DEVPKEY_Device_MatchingDeviceId-for-GPUs.patch b/patches/win32u-GPU_properties/0001-win32u-Set-DEVPKEY_Device_MatchingDeviceId-for-GPUs.patch new file mode 100644 index 00000000..b2f54a28 --- /dev/null +++ b/patches/win32u-GPU_properties/0001-win32u-Set-DEVPKEY_Device_MatchingDeviceId-for-GPUs.patch @@ -0,0 +1,125 @@ +From d59b98f9fb10a3d634541d4e538ed7500a183c77 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Mon, 20 Mar 2023 11:59:14 -0600 +Subject: [PATCH 1/3] win32u: Set DEVPKEY_Device_MatchingDeviceId for GPUs. + +--- + dlls/gdi32/tests/driver.c | 50 +++++++++++++++++++++++++++++++++++++++ + dlls/win32u/sysparams.c | 19 +++++++++++++++ + 2 files changed, 69 insertions(+) + +diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c +index 94f93d61207..092bde0e5c1 100644 +--- a/dlls/gdi32/tests/driver.c ++++ b/dlls/gdi32/tests/driver.c +@@ -32,6 +32,7 @@ + #include "initguid.h" + #include "setupapi.h" + #include "ntddvdeo.h" ++#include "devpkey.h" + + #include "wine/test.h" + +@@ -996,6 +997,54 @@ static void test_D3DKMTQueryVideoMemoryInfo(void) + ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status); + } + ++static void test_gpu_device_properties_guid(const GUID *devinterface_guid) ++{ ++ BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)]; ++ SP_DEVINFO_DATA device_data = {sizeof(device_data)}; ++ SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; ++ SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data; ++ WCHAR device_id[256]; ++ DEVPROPTYPE type; ++ unsigned int i; ++ HDEVINFO set; ++ BOOL ret; ++ ++ /* Make sure display devices are initialized. */ ++ SendMessageW(GetDesktopWindow(), WM_NULL, 0, 0); ++ ++ set = SetupDiGetClassDevsW(devinterface_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); ++ ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed, error %lu.\n", GetLastError()); ++ ++ iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer; ++ iface_data->cbSize = sizeof(*iface_data); ++ ++ i = 0; ++ while (SetupDiEnumDeviceInterfaces(set, NULL, devinterface_guid, i, &iface)) ++ { ++ ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data, ++ sizeof(iface_detail_buffer), NULL, &device_data ); ++ ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError()); ++ ++ ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_MatchingDeviceId, &type, ++ (BYTE *)device_id, sizeof(device_id), NULL, 0); ++ ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError()); ++ ok(type == DEVPROP_TYPE_STRING, "Got type %ld.\n", type); ++ ++ ++i; ++ } ++ SetupDiDestroyDeviceInfoList(set); ++} ++ ++static void test_gpu_device_properties(void) ++{ ++ winetest_push_context("GUID_DEVINTERFACE_DISPLAY_ADAPTER"); ++ test_gpu_device_properties_guid(&GUID_DEVINTERFACE_DISPLAY_ADAPTER); ++ winetest_pop_context(); ++ winetest_push_context("GUID_DISPLAY_DEVICE_ARRIVAL"); ++ test_gpu_device_properties_guid(&GUID_DISPLAY_DEVICE_ARRIVAL); ++ winetest_pop_context(); ++} ++ + START_TEST(driver) + { + HMODULE gdi32 = GetModuleHandleA("gdi32.dll"); +@@ -1025,6 +1074,7 @@ START_TEST(driver) + test_D3DKMTCheckOcclusion(); + test_D3DKMTOpenAdapterFromDeviceName(); + test_D3DKMTQueryVideoMemoryInfo(); ++ test_gpu_device_properties(); + + FreeLibrary(dwmapi); + } +diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c +index 60b12321953..a02158a17a0 100644 +--- a/dlls/win32u/sysparams.c ++++ b/dlls/win32u/sysparams.c +@@ -93,6 +93,14 @@ static const WCHAR devpropkey_gpu_luidW[] = + '\\','0','0','0','2' + }; + ++static const WCHAR devpkey_device_matching_device_id[] = ++{ ++ 'P','r','o','p','e','r','t','i','e','s', ++ '\\','{','A','8','B','8','6','5','D','D','-','2','E','3','D','-','4','0','9','4', ++ '-','A','D','9','7','-','E','5','9','3','A','7','0','C','7','5','D','6','}', ++ '\\','0','0','0','8' ++}; ++ + static const WCHAR devpropkey_device_ispresentW[] = + { + 'P','r','o','p','e','r','t','i','e','s', +@@ -1218,6 +1226,17 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param ) + bufferW[size / sizeof(WCHAR)] = 0; /* for REG_MULTI_SZ */ + set_reg_value( hkey, hardware_idW, REG_MULTI_SZ, bufferW, size + sizeof(WCHAR) ); + ++ if ((subkey = reg_create_key( hkey, devpkey_device_matching_device_id, ++ sizeof(devpkey_device_matching_device_id), 0, NULL ))) ++ { ++ if (gpu->vendor_id && gpu->device_id) ++ set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_STRING, bufferW, size ); ++ else ++ set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_STRING, bufferW, ++ asciiz_to_unicode( bufferW, "ROOT\\BasicRender" )); ++ NtClose( subkey ); ++ } ++ + desc = gpu->name; + if (!desc[0]) desc = wine_adapterW; + set_reg_value( hkey, device_descW, REG_SZ, desc, (lstrlenW( desc ) + 1) * sizeof(WCHAR) ); +-- +2.40.0 + diff --git a/patches/win32u-GPU_properties/0002-win32u-Set-DEVPKEY_Device_BusNumber-for-GPUs.patch b/patches/win32u-GPU_properties/0002-win32u-Set-DEVPKEY_Device_BusNumber-for-GPUs.patch new file mode 100644 index 00000000..cb735855 --- /dev/null +++ b/patches/win32u-GPU_properties/0002-win32u-Set-DEVPKEY_Device_BusNumber-for-GPUs.patch @@ -0,0 +1,80 @@ +From 1846ff937ff4d4c4eb1b9a2311c385b52ac864cc Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Mon, 20 Mar 2023 13:02:31 -0600 +Subject: [PATCH 2/3] win32u: Set DEVPKEY_Device_BusNumber for GPUs. + +--- + dlls/gdi32/tests/driver.c | 12 ++++++++++++ + dlls/win32u/sysparams.c | 19 +++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c +index 092bde0e5c1..eabd3ed15b8 100644 +--- a/dlls/gdi32/tests/driver.c ++++ b/dlls/gdi32/tests/driver.c +@@ -1006,6 +1006,7 @@ static void test_gpu_device_properties_guid(const GUID *devinterface_guid) + WCHAR device_id[256]; + DEVPROPTYPE type; + unsigned int i; ++ UINT32 value; + HDEVINFO set; + BOOL ret; + +@@ -1030,6 +1031,17 @@ static void test_gpu_device_properties_guid(const GUID *devinterface_guid) + ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError()); + ok(type == DEVPROP_TYPE_STRING, "Got type %ld.\n", type); + ++ ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_BusNumber, &type, ++ (BYTE *)&value, sizeof(value), NULL, 0); ++ if (!wcsicmp(device_id, L"root\\basicrender") || !wcsicmp(device_id, L"root\\basicdisplay")) ++ { ++ ok(!ret, "Found Bus Id.\n"); ++ } ++ else ++ { ++ ok(ret, "Got unexpected ret %d, GetLastError() %lu, %s.\n", ret, GetLastError(), debugstr_w(device_id)); ++ ok(type == DEVPROP_TYPE_UINT32, "Got type %ld.\n", type); ++ } + ++i; + } + SetupDiDestroyDeviceInfoList(set); +diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c +index a02158a17a0..f4e8eff98e2 100644 +--- a/dlls/win32u/sysparams.c ++++ b/dlls/win32u/sysparams.c +@@ -101,6 +101,14 @@ static const WCHAR devpkey_device_matching_device_id[] = + '\\','0','0','0','8' + }; + ++static const WCHAR devpkey_device_bus_number[] = ++{ ++ 'P','r','o','p','e','r','t','i','e','s', ++ '\\','{','A','4','5','C','2','5','4','E','-','D','F','1','C','-','4','E','F','D', ++ '-','8','0','2','0','-','6','7','D','1','4','6','A','8','5','0','E','0','}', ++ '\\','0','0','1','7' ++}; ++ + static const WCHAR devpropkey_device_ispresentW[] = + { + 'P','r','o','p','e','r','t','i','e','s', +@@ -1237,6 +1245,17 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param ) + NtClose( subkey ); + } + ++ if (gpu->vendor_id && gpu->device_id) ++ { ++ if ((subkey = reg_create_key( hkey, devpkey_device_bus_number, ++ sizeof(devpkey_device_bus_number), 0, NULL ))) ++ { ++ set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_UINT32, ++ &gpu_index, sizeof(gpu_index) ); ++ NtClose( subkey ); ++ } ++ } ++ + desc = gpu->name; + if (!desc[0]) desc = wine_adapterW; + set_reg_value( hkey, device_descW, REG_SZ, desc, (lstrlenW( desc ) + 1) * sizeof(WCHAR) ); +-- +2.40.0 + diff --git a/patches/win32u-GPU_properties/0003-win32u-Set-DEVPKEY_Device_RemovalPolicy-for-GPUs.patch b/patches/win32u-GPU_properties/0003-win32u-Set-DEVPKEY_Device_RemovalPolicy-for-GPUs.patch new file mode 100644 index 00000000..cc31104d --- /dev/null +++ b/patches/win32u-GPU_properties/0003-win32u-Set-DEVPKEY_Device_RemovalPolicy-for-GPUs.patch @@ -0,0 +1,99 @@ +From 5a493bfd785962d3b6043e6eac00712a73a81cc6 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Mon, 20 Mar 2023 13:18:26 -0600 +Subject: [PATCH 3/3] win32u: Set DEVPKEY_Device_RemovalPolicy for GPUs. + +--- + dlls/gdi32/tests/driver.c | 8 ++++++++ + dlls/win32u/sysparams.c | 19 +++++++++++++++++++ + include/cfgmgr32.h | 4 ++++ + 3 files changed, 31 insertions(+) + +diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c +index eabd3ed15b8..a618b5e51a4 100644 +--- a/dlls/gdi32/tests/driver.c ++++ b/dlls/gdi32/tests/driver.c +@@ -33,6 +33,7 @@ + #include "setupapi.h" + #include "ntddvdeo.h" + #include "devpkey.h" ++#include "cfgmgr32.h" + + #include "wine/test.h" + +@@ -1042,6 +1043,13 @@ static void test_gpu_device_properties_guid(const GUID *devinterface_guid) + ok(ret, "Got unexpected ret %d, GetLastError() %lu, %s.\n", ret, GetLastError(), debugstr_w(device_id)); + ok(type == DEVPROP_TYPE_UINT32, "Got type %ld.\n", type); + } ++ ++ ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_RemovalPolicy, &type, ++ (BYTE *)&value, sizeof(value), NULL, 0); ++ ok(ret, "Got unexpected ret %d, GetLastError() %lu, %s.\n", ret, GetLastError(), debugstr_w(device_id)); ++ ok(value == CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL || value == CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL ++ || value == CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL, "Got value %d.\n", value); ++ ok(type == DEVPROP_TYPE_UINT32, "Got type %ld.\n", type); + ++i; + } + SetupDiDestroyDeviceInfoList(set); +diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c +index f4e8eff98e2..76703d2da52 100644 +--- a/dlls/win32u/sysparams.c ++++ b/dlls/win32u/sysparams.c +@@ -32,6 +32,7 @@ + #include "ntgdi_private.h" + #include "ntuser_private.h" + #include "devpropdef.h" ++#include "cfgmgr32.h" + #include "wine/wingdi16.h" + #include "wine/server.h" + +@@ -109,6 +110,14 @@ static const WCHAR devpkey_device_bus_number[] = + '\\','0','0','1','7' + }; + ++static const WCHAR devpkey_device_removal_policy[] = ++{ ++ 'P','r','o','p','e','r','t','i','e','s', ++ '\\','{','A','4','5','C','2','5','4','E','-','D','F','1','C','-','4','E','F','D', ++ '-','8','0','2','0','-','6','7','D','1','4','6','A','8','5','0','E','0','}', ++ '\\','0','0','2','1' ++}; ++ + static const WCHAR devpropkey_device_ispresentW[] = + { + 'P','r','o','p','e','r','t','i','e','s', +@@ -1256,6 +1265,16 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param ) + } + } + ++ if ((subkey = reg_create_key( hkey, devpkey_device_removal_policy, ++ sizeof(devpkey_device_removal_policy), 0, NULL ))) ++ { ++ unsigned int removal_policy = CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL; ++ ++ set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_UINT32, ++ &removal_policy, sizeof(removal_policy) ); ++ NtClose( subkey ); ++ } ++ + desc = gpu->name; + if (!desc[0]) desc = wine_adapterW; + set_reg_value( hkey, device_descW, REG_SZ, desc, (lstrlenW( desc ) + 1) * sizeof(WCHAR) ); +diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h +index b78f118622e..04f1f80b174 100644 +--- a/include/cfgmgr32.h ++++ b/include/cfgmgr32.h +@@ -180,6 +180,10 @@ typedef DWORD CONFIGRET; + #define CM_REGISTRY_USER 0x0100 + #define CM_REGISTRY_CONFIG 0x0200 + ++#define CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL 1 ++#define CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL 2 ++#define CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL 3 ++ + typedef DWORD DEVINST, *PDEVINST; + typedef DWORD DEVNODE, *PDEVNODE; + typedef HANDLE HMACHINE, *PHMACHINE; +-- +2.40.0 + diff --git a/patches/win32u-GPU_properties/definition b/patches/win32u-GPU_properties/definition new file mode 100644 index 00000000..937b2867 --- /dev/null +++ b/patches/win32u-GPU_properties/definition @@ -0,0 +1 @@ +MR 2449: Allow Diable IV to run without reporting errors.