From: Paul Gofman pgofman@codeweavers.com
--- dlls/win32u/sysparams.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 9f0812b843e..049ff8ceea8 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -220,6 +220,7 @@ struct adapter LONG refcount; struct list entry; struct display_device dev; + LUID gpu_luid; unsigned int id; const WCHAR *config_key; unsigned int mode_count; @@ -628,6 +629,17 @@ static int mode_compare(const void *p1, const void *p2) return 0; }
+static unsigned int query_reg_subkey_value( HKEY hkey, const WCHAR *name, unsigned int name_size, + KEY_VALUE_PARTIAL_INFORMATION *value, unsigned int size ) +{ + HKEY subkey; + + if (!(subkey = reg_open_key( hkey, name, name_size ))) return 0; + size = query_reg_value( subkey, NULL, value, size ); + NtClose( subkey ); + return size; +} + static BOOL read_display_adapter_settings( unsigned int index, struct adapter *info ) { char buffer[4096]; @@ -700,6 +712,14 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i if (!(hkey = reg_open_key( enum_key, value_str, value->DataLength - sizeof(WCHAR) ))) return FALSE;
+ size = query_reg_subkey_value( hkey, devpropkey_gpu_luidW, sizeof(devpropkey_gpu_luidW), value, sizeof(buffer) ); + if (size != sizeof(info->gpu_luid)) + { + NtClose( hkey ); + return FALSE; + } + memcpy( &info->gpu_luid, value->Data, sizeof(info->gpu_luid) ); + size = query_reg_value( hkey, hardware_idW, value, sizeof(buffer) ); NtClose( hkey ); if (!size || (value->Type != REG_SZ && value->Type != REG_MULTI_SZ)) @@ -709,17 +729,6 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i return TRUE; }
-static unsigned int query_reg_subkey_value( HKEY hkey, const WCHAR *name, unsigned int name_size, - KEY_VALUE_PARTIAL_INFORMATION *value, unsigned int size ) -{ - HKEY subkey; - - if (!(subkey = reg_open_key( hkey, name, name_size ))) return 0; - size = query_reg_value( subkey, NULL, value, size ); - NtClose( subkey ); - return size; -} - static BOOL read_monitor_settings( struct adapter *adapter, DWORD index, struct monitor *monitor ) { char buffer[4096];
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/sysparams.c | 107 +------------------------------------ dlls/win32u/syscall.c | 1 + dlls/win32u/sysparams.c | 85 +++++++++++++++++++++++++++++ dlls/win32u/tests/win32u.c | 20 +++++++ dlls/win32u/win32u.spec | 2 +- dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 7 +++ include/ntuser.h | 1 + 8 files changed, 117 insertions(+), 107 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 7ebe8099419..c7bd702726a 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -1300,112 +1300,7 @@ done: */ LONG WINAPI DisplayConfigGetDeviceInfo(DISPLAYCONFIG_DEVICE_INFO_HEADER *packet) { - LONG ret = ERROR_GEN_FAILURE; - HANDLE mutex; - HDEVINFO devinfo; - SP_DEVINFO_DATA device_data = {sizeof(device_data)}; - DWORD index = 0, type; - LUID gpu_luid; - - TRACE("(%p)\n", packet); - - if (!packet || packet->size < sizeof(*packet)) - return ERROR_GEN_FAILURE; - wait_graphics_driver_ready(); - - switch (packet->type) - { - case DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME: - { - DISPLAYCONFIG_SOURCE_DEVICE_NAME *source_name = (DISPLAYCONFIG_SOURCE_DEVICE_NAME *)packet; - WCHAR device_name[CCHDEVICENAME]; - LONG source_id; - - TRACE("DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME\n"); - - if (packet->size < sizeof(*source_name)) - return ERROR_INVALID_PARAMETER; - - mutex = get_display_device_init_mutex(); - devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, L"DISPLAY", NULL, DIGCF_PRESENT); - if (devinfo == INVALID_HANDLE_VALUE) - { - release_display_device_init_mutex(mutex); - return ret; - } - - while (SetupDiEnumDeviceInfo(devinfo, index++, &device_data)) - { - if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_GPU_LUID, - &type, (BYTE *)&gpu_luid, sizeof(gpu_luid), NULL, 0)) - continue; - - if ((source_name->header.adapterId.LowPart != gpu_luid.LowPart) || - (source_name->header.adapterId.HighPart != gpu_luid.HighPart)) - continue; - - /* QueryDisplayConfig() derives the source ID from the adapter name. */ - if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, - &type, (BYTE *)device_name, sizeof(device_name), NULL, 0)) - continue; - - source_id = wcstol(device_name + lstrlenW(L"\\.\DISPLAY"), NULL, 10); - source_id--; - if (source_name->header.id != source_id) - continue; - - lstrcpyW(source_name->viewGdiDeviceName, device_name); - ret = ERROR_SUCCESS; - break; - } - SetupDiDestroyDeviceInfoList(devinfo); - release_display_device_init_mutex(mutex); - return ret; - } - case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: - { - DISPLAYCONFIG_TARGET_DEVICE_NAME *target_name = (DISPLAYCONFIG_TARGET_DEVICE_NAME *)packet; - - FIXME("DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: stub\n"); - - if (packet->size < sizeof(*target_name)) - return ERROR_INVALID_PARAMETER; - - return ERROR_NOT_SUPPORTED; - } - case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE: - { - DISPLAYCONFIG_TARGET_PREFERRED_MODE *preferred_mode = (DISPLAYCONFIG_TARGET_PREFERRED_MODE *)packet; - - FIXME("DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE: stub\n"); - - if (packet->size < sizeof(*preferred_mode)) - return ERROR_INVALID_PARAMETER; - - return ERROR_NOT_SUPPORTED; - } - case DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME: - { - DISPLAYCONFIG_ADAPTER_NAME *adapter_name = (DISPLAYCONFIG_ADAPTER_NAME *)packet; - - FIXME("DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME: stub\n"); - - if (packet->size < sizeof(*adapter_name)) - return ERROR_INVALID_PARAMETER; - - return ERROR_NOT_SUPPORTED; - } - case DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE: - case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE: - case DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION: - case DISPLAYCONFIG_DEVICE_INFO_SET_SUPPORT_VIRTUAL_RESOLUTION: - case DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO: - case DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE: - case DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL: - default: - FIXME("Unimplemented packet type: %u\n", packet->type); - return ERROR_INVALID_PARAMETER; - } + return RtlNtStatusToDosError(NtUserDisplayConfigGetDeviceInfo(packet)); }
/*********************************************************************** diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index f9e608ed0b7..ec21f7f5984 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -139,6 +139,7 @@ static void * const syscalls[] = NtUserDestroyWindow, NtUserDisableThreadIme, NtUserDispatchMessage, + NtUserDisplayConfigGetDeviceInfo, NtUserDragDetect, NtUserDrawIconEx, NtUserEmptyClipboard, diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 049ff8ceea8..25891fb30d7 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -5554,3 +5554,88 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code return 0; } } + +/*********************************************************************** + * NtUserDisplayConfigGetDeviceInfo (win32u.@) + */ +NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEADER *packet ) +{ + NTSTATUS ret = STATUS_UNSUCCESSFUL; + + TRACE( "packet %p.\n", packet ); + + if (!packet || packet->size < sizeof(*packet)) + return STATUS_UNSUCCESSFUL; + + switch (packet->type) + { + case DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME: + { + DISPLAYCONFIG_SOURCE_DEVICE_NAME *source_name = (DISPLAYCONFIG_SOURCE_DEVICE_NAME *)packet; + struct adapter *adapter; + + TRACE( "DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME.\n" ); + + if (packet->size < sizeof(*source_name)) + return STATUS_INVALID_PARAMETER; + + if (!lock_display_devices()) return STATUS_UNSUCCESSFUL; + + LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) + { + if (source_name->header.id != adapter->id) continue; + if (memcmp( &source_name->header.adapterId, &adapter->gpu_luid, sizeof(adapter->gpu_luid) )) continue; + + lstrcpyW( source_name->viewGdiDeviceName, adapter->dev.device_name ); + ret = STATUS_SUCCESS; + break; + } + + unlock_display_devices(); + return ret; + } + case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: + { + DISPLAYCONFIG_TARGET_DEVICE_NAME *target_name = (DISPLAYCONFIG_TARGET_DEVICE_NAME *)packet; + + FIXME( "DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME stub.\n" ); + + if (packet->size < sizeof(*target_name)) + return STATUS_INVALID_PARAMETER; + + return STATUS_NOT_SUPPORTED; + } + case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE: + { + DISPLAYCONFIG_TARGET_PREFERRED_MODE *preferred_mode = (DISPLAYCONFIG_TARGET_PREFERRED_MODE *)packet; + + FIXME( "DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE stub.\n" ); + + if (packet->size < sizeof(*preferred_mode)) + return STATUS_INVALID_PARAMETER; + + return STATUS_NOT_SUPPORTED; + } + case DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME: + { + DISPLAYCONFIG_ADAPTER_NAME *adapter_name = (DISPLAYCONFIG_ADAPTER_NAME *)packet; + + FIXME( "DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME stub.\n" ); + + if (packet->size < sizeof(*adapter_name)) + return STATUS_INVALID_PARAMETER; + + return STATUS_NOT_SUPPORTED; + } + case DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE: + case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE: + case DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION: + case DISPLAYCONFIG_DEVICE_INFO_SET_SUPPORT_VIRTUAL_RESOLUTION: + case DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO: + case DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE: + case DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL: + default: + FIXME( "Unimplemented packet type %u.\n", packet->type ); + return STATUS_INVALID_PARAMETER; + } +} diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 502b6b91b5a..bcfafbf13b3 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -675,6 +675,25 @@ static void test_timer(void) DestroyWindow( hwnd ); }
+static void test_NtUserDisplayConfigGetDeviceInfo(void) +{ + DISPLAYCONFIG_SOURCE_DEVICE_NAME source_name; + NTSTATUS status; + + source_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + source_name.header.size = sizeof(source_name.header); + status = NtUserDisplayConfigGetDeviceInfo(&source_name.header); + ok(status == STATUS_INVALID_PARAMETER, "got %#lx.\n", status); + + source_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + source_name.header.size = sizeof(source_name); + source_name.header.adapterId.LowPart = 0xFFFF; + source_name.header.adapterId.HighPart = 0xFFFF; + source_name.header.id = 0; + status = NtUserDisplayConfigGetDeviceInfo(&source_name.header); + ok(status == STATUS_UNSUCCESSFUL || status == STATUS_NOT_SUPPORTED, "got %#lx.\n", status); +} + START_TEST(win32u) { /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */ @@ -692,4 +711,5 @@ START_TEST(win32u) test_timer();
test_NtUserCloseWindowStation(); + test_NtUserDisplayConfigGetDeviceInfo(); } diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index df722586ded..8a3344257ed 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -840,7 +840,7 @@ @ stdcall -syscall NtUserDisableThreadIme(long) @ stub NtUserDiscardPointerFrameMessages @ stdcall -syscall NtUserDispatchMessage(ptr) -@ stub NtUserDisplayConfigGetDeviceInfo +@ stdcall -syscall NtUserDisplayConfigGetDeviceInfo(ptr) @ stub NtUserDisplayConfigSetDeviceInfo @ stub NtUserDoSoundConnect @ stub NtUserDoSoundDisconnect diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 009a457fe6e..683e7978653 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -125,6 +125,7 @@ SYSCALL_ENTRY( NtUserDestroyWindow ) \ SYSCALL_ENTRY( NtUserDisableThreadIme ) \ SYSCALL_ENTRY( NtUserDispatchMessage ) \ + SYSCALL_ENTRY( NtUserDisplayConfigGetDeviceInfo ) \ SYSCALL_ENTRY( NtUserDragDetect ) \ SYSCALL_ENTRY( NtUserDrawIconEx ) \ SYSCALL_ENTRY( NtUserEmptyClipboard ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 041285fa37f..8d15c84ac30 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -4077,3 +4077,10 @@ NTSTATUS WINAPI wow64_NtUserWindowFromPoint( UINT *args )
return HandleToUlong( NtUserWindowFromPoint( x, y )); } + +NTSTATUS WINAPI wow64_NtUserDisplayConfigGetDeviceInfo( UINT *args ) +{ + DISPLAYCONFIG_DEVICE_INFO_HEADER *packet = get_ptr( &args ); + + return NtUserDisplayConfigGetDeviceInfo( packet ); +} diff --git a/include/ntuser.h b/include/ntuser.h index d724ccad103..1ec4898dcd1 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -677,6 +677,7 @@ BOOL WINAPI NtUserDestroyMenu( HMENU menu ); BOOL WINAPI NtUserDestroyWindow( HWND hwnd ); BOOL WINAPI NtUserDisableThreadIme( DWORD thread_id ); LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ); +NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEADER *packet ); BOOL WINAPI NtUserDragDetect( HWND hwnd, int x, int y ); BOOL WINAPI NtUserDrawCaptionTemp( HWND hwnd, HDC hdc, const RECT *rect, HFONT font, HICON icon, const WCHAR *str, UINT flags );
From: Paul Gofman pgofman@codeweavers.com
--- dlls/win32u/sysparams.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 25891fb30d7..703693b6e7a 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -235,6 +235,7 @@ struct monitor HANDLE handle; unsigned int id; unsigned int flags; + unsigned int output_id; RECT rc_monitor; RECT rc_work; BOOL is_clone; @@ -777,6 +778,17 @@ static BOOL read_monitor_settings( struct adapter *adapter, DWORD index, struct } monitor->dev.state_flags = *(const DWORD *)value->Data;
+ /* Output ID */ + size = query_reg_subkey_value( hkey, devpropkey_monitor_output_idW, + sizeof(devpropkey_monitor_output_idW), + value, sizeof(buffer) ); + if (size != sizeof(monitor->output_id)) + { + NtClose( hkey ); + return FALSE; + } + monitor->output_id = *(const unsigned int *)value->Data; + /* rc_monitor, WINE_DEVPROPKEY_MONITOR_RCMONITOR */ size = query_reg_subkey_value( hkey, wine_devpropkey_monitor_rcmonitorW, sizeof(wine_devpropkey_monitor_rcmonitorW),
From: Paul Gofman pgofman@codeweavers.com
--- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/monitor.c | 63 +++++++++++++++++++++++++++++++++-- dlls/win32u/sysparams.c | 26 +++++++++++++-- 3 files changed, 85 insertions(+), 6 deletions(-)
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; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 703693b6e7a..e9af375aaf7 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -5609,13 +5609,35 @@ NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEAD case DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME: { DISPLAYCONFIG_TARGET_DEVICE_NAME *target_name = (DISPLAYCONFIG_TARGET_DEVICE_NAME *)packet; + char buffer[ARRAY_SIZE(target_name->monitorFriendlyDeviceName)]; + struct monitor *monitor;
- FIXME( "DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME stub.\n" ); + TRACE( "DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME.\n" );
if (packet->size < sizeof(*target_name)) return STATUS_INVALID_PARAMETER;
- return STATUS_NOT_SUPPORTED; + if (!lock_display_devices()) return STATUS_UNSUCCESSFUL; + + memset( &target_name->flags, 0, sizeof(*target_name) - offsetof(DISPLAYCONFIG_TARGET_DEVICE_NAME, flags) ); + + LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) + { + if (target_name->header.id != monitor->output_id) continue; + if (memcmp( &target_name->header.adapterId, &monitor->adapter->gpu_luid, + sizeof(monitor->adapter->gpu_luid) )) + continue; + + /* FIXME: get real monitor name. */ + snprintf( buffer, ARRAY_SIZE(buffer), "Display%u", monitor->output_id + 1 ); + asciiz_to_unicode( target_name->monitorFriendlyDeviceName, buffer ); + target_name->flags.friendlyNameForced = 1; + lstrcpyW( target_name->monitorDevicePath, monitor->dev.interface_name ); + ret = ERROR_SUCCESS; + } + + unlock_display_devices(); + return ret; } case 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=125381
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:2404: Test failed: Spurious WM_INPUT messages
=== w10pro64_ja (64 bit report) ===
user32: menu.c:2324: Test failed: test 18
=== w10pro64_ar (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)
=== w10pro64 (64 bit report) ===
user32: win.c:4592: Test failed: hwnd 0000000000020272/0000000000020272 message 0200 win.c:4595: Test failed: hwnd 0000000000020272/0000000000020272 message 0201
=== w10pro64_ar (64 bit report) ===
user32: win.c:189: Test failed: didn't get start_event win.c:10288: Test failed: WindowFromPoint returned 00000000000901E0, expected 0000000000000000 win.c:10298: Test failed: WindowFromPoint returned 00000000000B02D2, expected 0000000000000000 win.c:10221: Test failed: transparent window didn't get WM_NCHITTEST message
=== debian11 (32 bit report) ===
dinput: joystick8.c:3556: Test failed: joyGetPosEx returned 165 joystick8.c:3563: Test failed: joyGetDevCapsW returned 165 joystick8.c:3564: Test failed: got wMid 0 joystick8.c:3565: Test failed: got wPid 0 joystick8.c:3569: Test failed: got wXmax 0 joystick8.c:3571: Test failed: got wYmax 0 joystick8.c:3573: Test failed: got wZmax 0 joystick8.c:3574: Test failed: got wNumButtons 0 joystick8.c:3575: Test failed: got wPeriodMin 0 joystick8.c:3576: Test failed: got wPeriodMax 0 joystick8.c:3578: Test failed: got wRmax 0 joystick8.c:3580: Test failed: got wUmax 0 joystick8.c:3582: Test failed: got wVmax 0 joystick8.c:3583: Test failed: got wCaps 0 joystick8.c:3584: Test failed: got wMaxAxes 0 joystick8.c:3585: Test failed: got wNumAxes 0 joystick8.c:3586: Test failed: got wMaxButtons 0 joystick8.c:3594: Test failed: joyGetDevCapsW returned 165 joystick8.c:3615: Test failed: joyGetPosEx returned 165 joystick8.c:3618: Test failed: got dwXpos 0xcdcdcdcd joystick8.c:3619: Test failed: got dwYpos 0xcdcdcdcd joystick8.c:3620: Test failed: got dwZpos 0xcdcdcdcd joystick8.c:3621: Test failed: got dwRpos 0xcdcdcdcd joystick8.c:3622: Test failed: got dwUpos 0xcdcdcdcd joystick8.c:3623: Test failed: got dwVpos 0xcdcdcdcd joystick8.c:3624: Test failed: got dwButtons 0xcdcdcdcd joystick8.c:3625: Test failed: got dwButtonNumber 0xcdcdcdcd joystick8.c:3626: Test failed: got dwPOV 0xcdcdcdcd joystick8.c:3640: Test failed: joyGetPos returned 165 joystick8.c:3641: Test failed: got wXpos 0xcdcdcdcd joystick8.c:3642: Test failed: got wYpos 0xcdcdcdcd joystick8.c:3643: Test failed: got wZpos 0xcdcdcdcd joystick8.c:3644: Test failed: got wButtons 0xcdcdcdcd joystick8.c:3676: Test failed: joyGetPosEx returned 165 joystick8.c:3679: Test failed: got dwXpos 0xcdcdcdcd joystick8.c:3680: Test failed: got dwYpos 0xcdcdcdcd joystick8.c:3681: Test failed: got dwZpos 0xcdcdcdcd joystick8.c:3682: Test failed: got dwRpos 0xcdcdcdcd joystick8.c:3683: Test failed: got dwUpos 0xcdcdcdcd joystick8.c:3684: Test failed: got dwVpos 0xcdcdcdcd joystick8.c:3685: Test failed: got dwButtons 0xcdcdcdcd joystick8.c:3686: Test failed: got dwButtonNumber 0xcdcdcdcd joystick8.c:3687: Test failed: got dwPOV 0xcdcdcdcd joystick8.c:3698: Test failed: joyGetPosEx returned 165 joystick8.c:3701: Test failed: got dwXpos 0xcdcdcdcd joystick8.c:3702: Test failed: got dwYpos 0xcdcdcdcd joystick8.c:3703: Test failed: got dwZpos 0xcdcdcdcd joystick8.c:3704: Test failed: got dwRpos 0xcdcdcdcd joystick8.c:3705: Test failed: got dwUpos 0xcdcdcdcd joystick8.c:3706: Test failed: got dwVpos 0xcdcdcdcd joystick8.c:3707: Test failed: got dwButtons 0xcdcdcdcd joystick8.c:3708: Test failed: got dwButtonNumber 0xcdcdcdcd joystick8.c:3709: Test failed: got dwPOV 0xcdcdcdcd
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
{ struct list entry; struct display_device dev; struct adapter *adapter; HANDLE handle;
Typo in the subject line.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
memset( &target_name->flags, 0, sizeof(*target_name) - offsetof(DISPLAYCONFIG_TARGET_DEVICE_NAME, flags) );
LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry)
{
if (target_name->header.id != monitor->output_id) continue;
if (memcmp( &target_name->header.adapterId, &monitor->adapter->gpu_luid,
sizeof(monitor->adapter->gpu_luid) ))
continue;
/* FIXME: get real monitor name. */
snprintf( buffer, ARRAY_SIZE(buffer), "Display%u", monitor->output_id + 1 );
asciiz_to_unicode( target_name->monitorFriendlyDeviceName, buffer );
target_name->flags.friendlyNameForced = 1;
lstrcpyW( target_name->monitorDevicePath, monitor->dev.interface_name );
ret = ERROR_SUCCESS;
You should use STATUS_SUCCESS instead ERROR_SUCCESS.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
return STATUS_NOT_SUPPORTED;
if (!lock_display_devices()) return STATUS_UNSUCCESSFUL;
memset( &target_name->flags, 0, sizeof(*target_name) - offsetof(DISPLAYCONFIG_TARGET_DEVICE_NAME, flags) );
LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry)
{
if (target_name->header.id != monitor->output_id) continue;
if (memcmp( &target_name->header.adapterId, &monitor->adapter->gpu_luid,
sizeof(monitor->adapter->gpu_luid) ))
continue;
/* FIXME: get real monitor name. */
snprintf( buffer, ARRAY_SIZE(buffer), "Display%u", monitor->output_id + 1 );
asciiz_to_unicode( target_name->monitorFriendlyDeviceName, buffer );
target_name->flags.friendlyNameForced = 1;
According to MSDN regarding friendlyNameForced, "A UINT32 value that indicates that the target is forced with no detectable monitor attached and the monitorFriendlyDeviceName member of the DISPLAYCONFIG_TARGET_DEVICE_NAME structure is a NULL-terminated empty string.". So it seems setting friendlyNameForced to 1 is wrong.
outputTechnology is initialized to 0 and DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 is 0. Maybe use a more appropriate type? i.e., DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL?
On 10/24/22 22:07, Zhiyi Zhang (@zhiyi) wrote:
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
return STATUS_NOT_SUPPORTED;
if (!lock_display_devices()) return STATUS_UNSUCCESSFUL;
memset( &target_name->flags, 0, sizeof(*target_name) - offsetof(DISPLAYCONFIG_TARGET_DEVICE_NAME, flags) );
LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry)
{
if (target_name->header.id != monitor->output_id) continue;
if (memcmp( &target_name->header.adapterId, &monitor->adapter->gpu_luid,
sizeof(monitor->adapter->gpu_luid) ))
continue;
/* FIXME: get real monitor name. */
snprintf( buffer, ARRAY_SIZE(buffer), "Display%u", monitor->output_id + 1 );
asciiz_to_unicode( target_name->monitorFriendlyDeviceName, buffer );
target_name->flags.friendlyNameForced = 1;
According to MSDN regarding friendlyNameForced, "A UINT32 value that indicates that the target is forced with no detectable monitor attached and the monitorFriendlyDeviceName member of the DISPLAYCONFIG_TARGET_DEVICE_NAME structure is a NULL-terminated empty string.". So it seems setting friendlyNameForced to 1 is wrong.
outputTechnology is initialized to 0 and DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 is 0. Maybe use a more appropriate type? i.e., DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL?
Thanks for looking into these patches, I've update the patchset. Yes, DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL is actually what I see here on my Windows laptop so that is definitely a better value.