From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/sysparams.c | 56 +++++++++++++++++++++++++++++-- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/monitor.c | 63 +++++++++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 7ebe8099419..ec78fb21c36 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -39,6 +39,7 @@ #include "d3dkmdt.h" #include "devguid.h" #include "setupapi.h" +#include "ntddvdeo.h" #include "controls.h" #include "user_private.h" #include "wine/asm.h" @@ -1365,13 +1366,64 @@ LONG WINAPI DisplayConfigGetDeviceInfo(DISPLAYCONFIG_DEVICE_INFO_HEADER *packet) case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: { DISPLAYCONFIG_TARGET_DEVICE_NAME *target_name = (DISPLAYCONFIG_TARGET_DEVICE_NAME *)packet; + BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)]; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data; + UINT32 output_id;
- FIXME("DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: stub\n"); + TRACE("DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME.\n");
if (packet->size < sizeof(*target_name)) return ERROR_INVALID_PARAMETER;
- return ERROR_NOT_SUPPORTED; + mutex = get_display_device_init_mutex(); + + devinfo = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MONITOR, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + if (devinfo == INVALID_HANDLE_VALUE) + { + release_display_device_init_mutex(mutex); + return ret; + } + + iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer; + iface_data->cbSize = sizeof(*iface_data); + + memset(&target_name->flags, 0, sizeof(*target_name) - offsetof(DISPLAYCONFIG_TARGET_DEVICE_NAME, flags)); + while (SetupDiEnumDeviceInterfaces(devinfo, NULL, &GUID_DEVINTERFACE_MONITOR, index++, &iface)) + { + if (!SetupDiGetDeviceInterfaceDetailW(devinfo, &iface, iface_data, + sizeof(iface_detail_buffer), NULL, &device_data)) + continue; + + if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_GPU_LUID, + &type, (BYTE *)&gpu_luid, sizeof(gpu_luid), NULL, 0)) + continue; + + if ((target_name->header.adapterId.LowPart != gpu_luid.LowPart) || + (target_name->header.adapterId.HighPart != gpu_luid.HighPart)) + continue; + + if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_OUTPUT_ID, + &type, (BYTE *)&output_id, sizeof(output_id), NULL, 0)) + continue; + + if (target_name->header.id != output_id) + continue; + + /* FIXME: get real monitor name. */ + swprintf(target_name->monitorFriendlyDeviceName, sizeof(target_name->monitorFriendlyDeviceName), + L"Display%u.\n", output_id); + target_name->flags.friendlyNameForced = 1; + wcscpy(target_name->monitorDevicePath, iface_data->DevicePath); + ret = ERROR_SUCCESS; + break; + } + + SetupDiDestroyDeviceInfoList(devinfo); + release_display_device_init_mutex(mutex); + if (ret) + WARN("DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME error %ld.\n", ret); + return ret; } case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE: { diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 344a3b66d2b..33c7f13f12d 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 imm32 +IMPORTS = user32 gdi32 advapi32 hid imm32 setupapi
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 4b774037508..1dff85b9621 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -23,6 +23,8 @@ #include "ntstatus.h" #define WIN32_NO_STATUS
+#include "initguid.h" + #include "wine/test.h" #include "winbase.h" #include "wingdi.h" @@ -30,9 +32,14 @@ #include "winreg.h" #include "winternl.h" #include "ddk/d3dkmthk.h" +#include "setupapi.h" +#include "ntddvdeo.h" #include "wine/heap.h" #include <stdio.h>
+DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_GPU_LUID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 1); +DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 2); + static LONG (WINAPI *pGetDisplayConfigBufferSizes)(UINT32,UINT32*,UINT32*); static BOOL (WINAPI *pGetDpiForMonitorInternal)(HMONITOR,UINT,UINT*,UINT*); static LONG (WINAPI *pQueryDisplayConfig)(UINT32,UINT32*,DISPLAYCONFIG_PATH_INFO*,UINT32*, @@ -1624,6 +1631,58 @@ static void test_EnumDisplayMonitors(void) ok(ret, "CloseWindowStation failed, error %#lx.\n", GetLastError()); }
+static void check_device_path(const WCHAR *device_path, const LUID *adapter_id, DWORD id) +{ + 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; + BOOL ret, found = FALSE; + DEVPROPTYPE type; + DWORD output_id; + unsigned int i; + HDEVINFO set; + LUID luid; + + iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer; + iface_data->cbSize = sizeof(*iface_data); + + set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MONITOR, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "Got error %lu.\n", GetLastError()); + + i = 0; + while (SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_MONITOR, 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, &DEVPROPKEY_MONITOR_GPU_LUID, &type, + (BYTE *)&luid, sizeof(luid), NULL, 0); + ok(ret || broken(GetLastError() == ERROR_NOT_FOUND) /* before Win10 1809 */, + "Got error %lu.\n", GetLastError()); + if (!ret) + { + win_skip("DEVPROPKEY_MONITOR_GPU_LUID is not found, skipping device path check.\n"); + SetupDiDestroyDeviceInfoList(set); + return; + } + ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPROPKEY_MONITOR_OUTPUT_ID, + &type, (BYTE *)&output_id, sizeof(output_id), NULL, 0); + ok(ret, "Got error %lu.\n", GetLastError()); + + if (output_id == id && RtlEqualLuid(&luid, adapter_id) && !wcsicmp(device_path, iface_data->DevicePath)) + { + found = TRUE; + break; + } + ++i; + } + ok(found, "device_path %s not found, luid %04lx:%04lx.\n", debugstr_w(device_path), adapter_id->HighPart, + adapter_id->LowPart); + SetupDiDestroyDeviceInfoList(set); +} + static void test_QueryDisplayConfig_result(UINT32 flags, UINT32 paths, const DISPLAYCONFIG_PATH_INFO *pi, UINT32 modes, const DISPLAYCONFIG_MODE_INFO *mi) { @@ -1654,7 +1713,6 @@ static void test_QueryDisplayConfig_result(UINT32 flags, ret = pDisplayConfigGetDeviceInfo(&source_name.header); ok(ret == ERROR_GEN_FAILURE, "Expected GEN_FAILURE, got %ld\n", ret);
- todo_wine { target_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; target_name.header.size = sizeof(target_name); target_name.header.adapterId = pi[i].targetInfo.adapterId; @@ -1662,8 +1720,7 @@ static void test_QueryDisplayConfig_result(UINT32 flags, target_name.monitorDevicePath[0] = '\0'; ret = pDisplayConfigGetDeviceInfo(&target_name.header); ok(!ret, "Expected 0, got %ld\n", ret); - ok(target_name.monitorDevicePath[0] != '\0', "Expected monitor device path, got empty string\n"); - } + check_device_path(target_name.monitorDevicePath, &target_name.header.adapterId, target_name.header.id);
todo_wine { preferred_mode.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125265
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
user32: input.c:746: Test failed: 0 (a4/0): 00 from 00 -> 80 unexpected input.c:746: Test failed: 0 (a4/0): 41 from 01 -> 00 unexpected
=== w7u_el (32 bit report) ===
user32: input.c:4551: Test failed: SendInput triggered unexpected message 0xc042
=== w10pro64_en_AE_u8 (64 bit report) ===
user32: msg.c:13063: Test failed: coords not changed: (101 101) (101 101) msg.c:13081: Test failed: coords not changed: (101 101) (101 101)
=== w864 (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
=== debian11 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report