Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/monitor.c | 90 +++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index dd101d69f3c..abe340403f4 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = user32.dll -IMPORTS = user32 gdi32 advapi32 hid +IMPORTS = user32 gdi32 advapi32 hid setupapi
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index bd348576726..de460187fbf 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -3,6 +3,7 @@ * * Copyright 2005 Huw Davies * Copyright 2008 Dmitry Timoshkov + * Copyright 2021 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,6 +29,11 @@ #include "winuser.h" #include "winreg.h" #include "winternl.h" +#include "cfgmgr32.h" +#include "initguid.h" +#include "devguid.h" +#include "ntddvdeo.h" +#include "setupapi.h" #include "ddk/d3dkmthk.h" #include "wine/heap.h" #include <stdio.h> @@ -2353,6 +2359,89 @@ static void test_display_dc(void) } }
+#define check_device_interface(a, b) _check_device_interface(__LINE__, a, b) +static void _check_device_interface(int line, const char *instance_id, const GUID *guid) +{ + SP_DEVICE_INTERFACE_DATA iface_data = {sizeof(iface_data)}; + SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + HDEVINFO devinfo; + BOOL ret; + + devinfo = SetupDiGetClassDevsA(guid, instance_id, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ret = SetupDiEnumDeviceInfo(devinfo, 0, &device_data); + ok_(__FILE__, line)(ret || broken(!ret) /* <= Win7 */, + "SetupDiEnumDeviceInfo failed, error %u.\n", GetLastError()); + if (!ret) + { + SetupDiDestroyDeviceInfoList(devinfo); + return; + } + ret = SetupDiEnumDeviceInterfaces(devinfo, &device_data, guid, 0, &iface_data); + ok_(__FILE__, line)(ret, "SetupDiEnumDeviceInterfaces failed, error %u.\n", GetLastError()); + ok_(__FILE__, line)(IsEqualGUID(&iface_data.InterfaceClassGuid, guid), + "Expected guid %s, got %s.\n", wine_dbgstr_guid(guid), + wine_dbgstr_guid(&iface_data.InterfaceClassGuid)); + + SetupDiDestroyDeviceInfoList(devinfo); +} + +static void test_display_device_interfaces(void) +{ + SP_DEVICE_INTERFACE_DATA iface_data = {sizeof(iface_data)}; + SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + char instance_id[MAX_DEVICE_ID_LEN]; + DWORD device_idx = 0, size, error; + HDEVINFO devinfo; + BOOL ret; + + /* GPUs */ + devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT); + ok(devinfo != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsW failed, error %u.\n", GetLastError()); + while ((ret = SetupDiEnumDeviceInfo(devinfo, device_idx, &device_data))) + { + ret = SetupDiGetDeviceInstanceIdA(devinfo, &device_data, instance_id, + ARRAY_SIZE(instance_id), &size); + ok(ret, "SetupDiGetDeviceInstanceIdA failed, error %u.\n", GetLastError()); + + winetest_push_context("GPU %d", device_idx); + + check_device_interface(instance_id, &GUID_DEVINTERFACE_DISPLAY_ADAPTER); + check_device_interface(instance_id, &GUID_DISPLAY_DEVICE_ARRIVAL); + + winetest_pop_context(); + ++device_idx; + } + error = GetLastError(); + ok(!ret, "SetupDiEnumDeviceInfo succeeded.\n"); + ok(error == ERROR_NO_MORE_ITEMS, "Expected error %u, got %u.\n", ERROR_NO_MORE_ITEMS, error); + ok(device_idx > 0, "Expected at least one GPU.\n"); + SetupDiDestroyDeviceInfoList(devinfo); + + /* Monitors */ + device_idx = 0; + devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, L"DISPLAY", NULL, DIGCF_PRESENT); + ok(devinfo != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsW failed, error %u.\n", GetLastError()); + while ((ret = SetupDiEnumDeviceInfo(devinfo, device_idx, &device_data))) + { + ret = SetupDiGetDeviceInstanceIdA(devinfo, &device_data, instance_id, + ARRAY_SIZE(instance_id), &size); + ok(ret, "SetupDiGetDeviceInstanceIdA failed, error %u.\n", GetLastError()); + + winetest_push_context("Monitor %d", device_idx); + + check_device_interface(instance_id, &GUID_DEVINTERFACE_MONITOR); + + winetest_pop_context(); + ++device_idx; + } + error = GetLastError(); + ok(!ret, "SetupDiEnumDeviceInfo succeeded.\n"); + ok(error == ERROR_NO_MORE_ITEMS, "Expected error %u, got %u.\n", ERROR_NO_MORE_ITEMS, error); + ok(device_idx > 0 || broken(device_idx == 0) /* w7u_2qxl TestBot */, + "Expected at least one monitor.\n"); + SetupDiDestroyDeviceInfoList(devinfo); +} + START_TEST(monitor) { init_function_pointers(); @@ -2365,4 +2454,5 @@ START_TEST(monitor) test_display_config(); test_handles(); test_display_dc(); + test_display_device_interfaces(); }