-- v3: win32u: Provide more gpu device properties. setupapi/tests: Add display enum tests.
From: Bernhard Kölbl bkoelbl@codeweavers.com
--- dlls/setupapi/tests/devinst.c | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index bf5d3c2a953..d12653abfe8 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -4732,6 +4732,65 @@ static void test_driver_store(struct testsign_context *ctx) ok(ret, "Failed to destroy device list.\n"); }
+static void test_device_enum(void) +{ + SP_DEVINFO_DATA devinfodata; + DEVPROPTYPE proptype; + HDEVINFO set; + WCHAR buf[2048]; + BOOL next, ret; + DWORD i, len; + + set = SetupDiGetClassDevsExW(&GUID_DEVCLASS_DISPLAY, NULL, 0, DIGCF_PRESENT, 0, NULL, 0); + ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsExW failed with %lu.\n", GetLastError()); + + ZeroMemory(&devinfodata, sizeof(SP_DEVINFO_DATA)); + devinfodata.cbSize = sizeof(SP_DEVINFO_DATA); + + i = 0; + next = SetupDiEnumDeviceInfo(set, i, &devinfodata); + ok(next, "Failed getting at least one element from SetupDiEnumDeviceInfo with error %lu.\n", GetLastError()); + + while (next) + { + ZeroMemory(buf, sizeof(buf)); + len = 0; + ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDate, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); + todo_wine ok(ret, "getting DEVPKEY_Device_DriverDate failed with error %lu.\n", GetLastError()); + todo_wine ok(len == sizeof(LARGE_INTEGER), "got unexpected length.\n"); + + ZeroMemory(buf, sizeof(buf)); + len = 0; + ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverVersion, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); + todo_wine ok(ret, "getting DEVPKEY_Device_DriverVersion failed with error %lu.\n", GetLastError()); + todo_wine ok(len > 0, "got unexpected length.\n"); + + ZeroMemory(buf, sizeof(buf)); + len = 0; + ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDesc, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); + todo_wine ok(ret, "getting DEVPKEY_Device_DriverDesc failed with error %lu.\n", GetLastError()); + todo_wine ok(len > 0, "got unexpected length.\n"); + + ZeroMemory(buf, sizeof(buf)); + len = 0; + ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverProvider, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); + todo_wine ok(ret, "getting DEVPKEY_Device_DriverProvider failed with error %lu.\n", GetLastError()); + todo_wine ok(len > 0, "got unexpected length.\n"); + + ZeroMemory(buf, sizeof(buf)); + len = 0; + ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverCoInstallers, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); + ok(!ret, "getting DEVPKEY_Device_DriverCoInstallers failed with error %lu.\n", GetLastError()); + ok(len == 0, "got unexpected length.\n"); + + i++; + next = SetupDiEnumDeviceInfo(set, i, &devinfodata); + } + + if (set) + SetupDiDestroyDeviceInfoList(set); +} + START_TEST(devinst) { static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); @@ -4779,6 +4838,7 @@ START_TEST(devinst) test_call_class_installer(); test_get_class_devs(); test_SetupDiOpenDeviceInterface(); + test_device_enum();
if (!testsign_create_cert(&ctx)) return;
From: Bernhard Kölbl bkoelbl@codeweavers.com
--- dlls/setupapi/tests/devinst.c | 16 +++--- dlls/win32u/sysparams.c | 103 ++++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 31 deletions(-)
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index d12653abfe8..7c47486131c 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -4756,26 +4756,26 @@ static void test_device_enum(void) ZeroMemory(buf, sizeof(buf)); len = 0; ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDate, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); - todo_wine ok(ret, "getting DEVPKEY_Device_DriverDate failed with error %lu.\n", GetLastError()); - todo_wine ok(len == sizeof(LARGE_INTEGER), "got unexpected length.\n"); + ok(ret, "getting DEVPKEY_Device_DriverDate failed with error %lu.\n", GetLastError()); + ok(len == sizeof(LARGE_INTEGER), "got unexpected length.\n");
ZeroMemory(buf, sizeof(buf)); len = 0; ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverVersion, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); - todo_wine ok(ret, "getting DEVPKEY_Device_DriverVersion failed with error %lu.\n", GetLastError()); - todo_wine ok(len > 0, "got unexpected length.\n"); + ok(ret, "getting DEVPKEY_Device_DriverVersion failed with error %lu.\n", GetLastError()); + ok(len > 0, "got unexpected length.\n");
ZeroMemory(buf, sizeof(buf)); len = 0; ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDesc, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); - todo_wine ok(ret, "getting DEVPKEY_Device_DriverDesc failed with error %lu.\n", GetLastError()); - todo_wine ok(len > 0, "got unexpected length.\n"); + ok(ret, "getting DEVPKEY_Device_DriverDesc failed with error %lu.\n", GetLastError()); + ok(len > 0, "got unexpected length.\n");
ZeroMemory(buf, sizeof(buf)); len = 0; ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverProvider, &proptype, (BYTE *)buf, sizeof(buf), &len, 0); - todo_wine ok(ret, "getting DEVPKEY_Device_DriverProvider failed with error %lu.\n", GetLastError()); - todo_wine ok(len > 0, "got unexpected length.\n"); + ok(ret, "getting DEVPKEY_Device_DriverProvider failed with error %lu.\n", GetLastError()); + ok(len > 0, "got unexpected length.\n");
ZeroMemory(buf, sizeof(buf)); len = 0; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 0ea5cad76e4..55895f06d66 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -52,7 +52,11 @@ static const char config_keyA[] = "\Registry\Machine\System\CurrentControlSe
static const char devpropkey_gpu_vulkan_uuidA[] = "Properties\{233A9EF3-AFC4-4ABD-B564-C32F21F1535C}\0002"; static const char devpropkey_gpu_luidA[] = "Properties\{60B193CB-5276-4D0F-96FC-F173ABAD3EC6}\0002"; +static const char devpkey_device_driver_date[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0002"; +static const char devpkey_device_driver_version[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0003"; +static const char devpkey_device_driver_desc[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0004"; static const char devpkey_device_matching_device_id[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0008"; +static const char devpkey_device_driver_provider[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0009"; static const char devpkey_device_bus_number[] = "Properties\{A45C254E-DF1C-4EFD-8020-67D146A850E0}\0017"; static const char devpkey_device_removal_policy[] = "Properties\{A45C254E-DF1C-4EFD-8020-67D146A850E0}\0021"; static const char devpropkey_device_ispresentA[] = "Properties\{540B947E-8B40-45BC-A8A2-6A0B894CBDA2}\0005"; @@ -1083,6 +1087,54 @@ static BOOL read_gpu_from_registry( struct gpu *gpu ) return TRUE; }
+static char* driver_vendor_to_version( UINT16 vendor, char *buffer ) +{ + /* The last seven digits are the driver number. */ + switch (vendor) + { + /* Intel */ + case 0x8086: + strcpy( buffer, "32.0.101.6314" ); + break; + /* AMD */ + case 0x1002: + strcpy( buffer, "31.0.21921.1000" ); + break; + /* Nvidia */ + case 0x10de: + strcpy( buffer, "32.0.15.6094" ); + break; + /* Default value for any other vendor. */ + default: + strcpy( buffer, "31.0.10.1000" ); + break; + } + + return buffer; +} + +static char* driver_vendor_to_name( UINT16 vendor, char *buffer ) +{ + switch (vendor) + { + case 0x8086: + strcpy( buffer, "Intel Corporation" ); + break; + case 0x1002: + strcpy( buffer, "Advanced Micro Devices, Inc." ); + break; + case 0x10de: + strcpy( buffer, "NVIDIA" ); + break; + /* Default value for any other vendor. */ + default: + strcpy( buffer, "" ); + break; + } + + return buffer; +} + static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *pci, ULONGLONG memory_size ) { @@ -1145,6 +1197,33 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p NtClose( subkey ); }
+ NtQuerySystemTime( &ft ); + if ((subkey = reg_create_ascii_key( hkey, devpkey_device_driver_date, 0, NULL ))) + { + set_reg_value( subkey, NULL, REG_BINARY, &ft, sizeof(LARGE_INTEGER)); + NtClose( subkey ); + } + + if ((subkey = reg_create_ascii_key( hkey, devpkey_device_driver_version, 0, NULL ))) + { + set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_STRING, bufferW, + asciiz_to_unicode( bufferW, driver_vendor_to_version( pci->vendor, buffer ) )); + NtClose( subkey ); + } + + if ((subkey = reg_create_ascii_key( hkey, devpkey_device_driver_desc, 0, NULL ))) + { + set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_STRING, gpu->name, (wcslen( gpu->name ) + 1) * sizeof(WCHAR) ); + NtClose( subkey ); + } + + if ((subkey = reg_create_ascii_key( hkey, devpkey_device_driver_provider, 0, NULL ))) + { + set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_STRING, bufferW, + asciiz_to_unicode( bufferW, driver_vendor_to_name( pci->vendor, buffer ) )); + NtClose( subkey ); + } + if (pci->vendor && pci->device) { if ((subkey = reg_create_ascii_key( hkey, devpkey_device_bus_number, 0, NULL ))) @@ -1201,7 +1280,6 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p snprintf( buffer, sizeof(buffer), "Class\%s\%04X", guid_devclass_displayA, gpu->index ); if (!(hkey = reg_create_ascii_key( control_key, buffer, 0, NULL ))) return FALSE;
- NtQuerySystemTime( &ft ); set_reg_value( hkey, driver_dateW, REG_SZ, bufferW, format_date( bufferW, ft.QuadPart ));
set_reg_value( hkey, driver_date_dataW, REG_BINARY, &ft, sizeof(ft) ); @@ -1220,28 +1298,7 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p value = (ULONG)min( memory_size, (ULONGLONG)ULONG_MAX ); set_reg_value( hkey, memory_sizeW, REG_DWORD, &value, sizeof(value) );
- /* The last seven digits are the driver number. */ - switch (pci->vendor) - { - /* Intel */ - case 0x8086: - strcpy( buffer, "31.0.101.4576" ); - break; - /* AMD */ - case 0x1002: - strcpy( buffer, "31.0.14051.5006" ); - break; - /* Nvidia */ - case 0x10de: - strcpy( buffer, "31.0.15.3625" ); - break; - /* Default value for any other vendor. */ - default: - strcpy( buffer, "31.0.10.1000" ); - break; - } - set_reg_ascii_value( hkey, "DriverVersion", buffer ); - + set_reg_ascii_value( hkey, "DriverVersion", driver_vendor_to_version( pci->vendor, buffer ) ); NtClose( hkey );
v3: - formatting changed
Rémi Bernon (@rbernon) commented about dlls/setupapi/tests/devinst.c:
- set = SetupDiGetClassDevsExW(&GUID_DEVCLASS_DISPLAY, NULL, 0, DIGCF_PRESENT, 0, NULL, 0);
- ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsExW failed with %lu.\n", GetLastError());
- ZeroMemory(&devinfodata, sizeof(SP_DEVINFO_DATA));
- devinfodata.cbSize = sizeof(SP_DEVINFO_DATA);
- i = 0;
- next = SetupDiEnumDeviceInfo(set, i, &devinfodata);
- ok(next, "Failed getting at least one element from SetupDiEnumDeviceInfo with error %lu.\n", GetLastError());
- while (next)
- {
ZeroMemory(buf, sizeof(buf));
len = 0;
ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDate, &proptype, (BYTE *)buf, sizeof(buf), &len, 0);
todo_wine ok(ret, "getting DEVPKEY_Device_DriverDate failed with error %lu.\n", GetLastError());
You could add `proptype` checks too, would show that this property should be of type `DEVPROP_TYPE_FILETIME` (in this MR it's DEVPROP_TYPE_BYTE), and that other props should be DEVPROP_TYPE_STRING.
Rémi Bernon (@rbernon) commented about dlls/setupapi/tests/devinst.c:
- ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsExW failed with %lu.\n", GetLastError());
- ZeroMemory(&devinfodata, sizeof(SP_DEVINFO_DATA));
- devinfodata.cbSize = sizeof(SP_DEVINFO_DATA);
- i = 0;
- next = SetupDiEnumDeviceInfo(set, i, &devinfodata);
- ok(next, "Failed getting at least one element from SetupDiEnumDeviceInfo with error %lu.\n", GetLastError());
- while (next)
- {
ZeroMemory(buf, sizeof(buf));
len = 0;
ret = SetupDiGetDevicePropertyW(set, &devinfodata, &DEVPKEY_Device_DriverDate, &proptype, (BYTE *)buf, sizeof(buf), &len, 0);
todo_wine ok(ret, "getting DEVPKEY_Device_DriverDate failed with error %lu.\n", GetLastError());
todo_wine ok(len == sizeof(LARGE_INTEGER), "got unexpected length.\n");
You could also check that the value is a FILETIME (100-ns since 01/01/1601) value that only contains date and no time, ie: `(value % 864000000000) == 0`.
Rémi Bernon (@rbernon) commented about dlls/win32u/sysparams.c:
break;
- /* AMD */
- case 0x1002:
strcpy( buffer, "31.0.21921.1000" );
break;
- /* Nvidia */
- case 0x10de:
strcpy( buffer, "32.0.15.6094" );
break;
- /* Default value for any other vendor. */
- default:
strcpy( buffer, "31.0.10.1000" );
break;
- }
- return buffer;
```suggestion:-21+0 switch (vendor) { case 0x8086 /* Intel */: return "32.0.101.6314"; case 0x1002 /* AMD */: return "31.0.21921.1000"; case 0x10de /* Nvidia */: return "32.0.15.6094"; default: return "31.0.10.1000"; } ```
Doesn't seem very useful to have a buffer to return static strings.
Rémi Bernon (@rbernon) commented about dlls/win32u/sysparams.c:
- case 0x8086:
strcpy( buffer, "Intel Corporation" );
break;
- case 0x1002:
strcpy( buffer, "Advanced Micro Devices, Inc." );
break;
- case 0x10de:
strcpy( buffer, "NVIDIA" );
break;
- /* Default value for any other vendor. */
- default:
strcpy( buffer, "" );
break;
- }
- return buffer;
```suggestion:-17+0 switch (vendor) { case 0x8086: return "Intel Corporation"; case 0x1002: return "Advanced Micro Devices, Inc."; case 0x10de: return "NVIDIA"; default: return ""; } ```
Same here, lets just return static strings.