Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2019
- 96 participants
- 789 discussions
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/mshtml/dispex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index e637f131d0..2033e90872 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -299,7 +299,7 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
if(!info->arg_types)
return;
info->arg_info = heap_alloc_zero(sizeof(*info->arg_info) * info->argc);
- if(!info->arg_types)
+ if(!info->arg_info)
return;
for(i=0; i < info->argc; i++)
--
2.21.0
2
4
20 May '19
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/winebus.sys/bus_sdl.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index d79c2004c89..2b367e5794a 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -548,19 +548,23 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
BYTE *report_ptr;
INT i, descript_size;
+ static const int BUTTON_BIT_COUNT = CONTROLLER_NUM_BUTTONS + CONTROLLER_NUM_HATSWITCHES * 4;
+
descript_size = sizeof(REPORT_HEADER) + sizeof(REPORT_TAIL);
descript_size += sizeof(CONTROLLER_AXIS);
descript_size += sizeof(CONTROLLER_TRIGGERS);
descript_size += sizeof(CONTROLLER_BUTTONS);
descript_size += sizeof(REPORT_HATSWITCH);
descript_size += sizeof(REPORT_PADDING);
+ if (BUTTON_BIT_COUNT % 8 != 0)
+ descript_size += sizeof(REPORT_PADDING);
descript_size += test_haptic(ext);
ext->axis_start = 0;
ext->button_start = CONTROLLER_NUM_AXES * sizeof(WORD);
ext->hat_bit_offs = CONTROLLER_NUM_BUTTONS;
- ext->buffer_length = (CONTROLLER_NUM_BUTTONS + CONTROLLER_NUM_HATSWITCHES * 4 + 7) / 8
+ ext->buffer_length = (BUTTON_BIT_COUNT + 7) / 8
+ CONTROLLER_NUM_AXES * sizeof(WORD)
+ 2/* unknown constant*/;
@@ -586,6 +590,8 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
memcpy(report_ptr, CONTROLLER_BUTTONS, sizeof(CONTROLLER_BUTTONS));
report_ptr += sizeof(CONTROLLER_BUTTONS);
report_ptr = add_hatswitch(report_ptr, 1);
+ if (BUTTON_BIT_COUNT % 8 != 0)
+ report_ptr = add_padding_block(report_ptr, 8 - (BUTTON_BIT_COUNT % 8));/* unused bits between hatswitch and following constant */
report_ptr = add_padding_block(report_ptr, 16);/* unknown constant */
report_ptr += build_haptic(ext, report_ptr);
memcpy(report_ptr, REPORT_TAIL, sizeof(REPORT_TAIL));
@@ -606,8 +612,8 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
set_hat_value(ext, 0, compose_dpad_value(ext->sdl_controller));
/* unknown constant */
- ext->report_buffer[12] = 0x89;
- ext->report_buffer[13] = 0xc5;
+ ext->report_buffer[14] = 0x89;
+ ext->report_buffer[15] = 0xc5;
return TRUE;
}
--
2.21.0
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/misc.c | 223 ++++++++++++++++++++++++++++++++----
dlls/user32/tests/monitor.c | 26 ++---
2 files changed, 213 insertions(+), 36 deletions(-)
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c
index 1a03d70dde..92d8a0ea1b 100644
--- a/dlls/user32/misc.c
+++ b/dlls/user32/misc.c
@@ -29,9 +29,13 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
+#include "winreg.h"
#include "winnls.h"
#include "winternl.h"
#include "controls.h"
+#include "initguid.h"
+#include "devguid.h"
+#include "setupapi.h"
#include "user_private.h"
#include "wine/unicode.h"
@@ -39,6 +43,42 @@
WINE_DEFAULT_DEBUG_CHANNEL(win);
+/* Wine specific monitor properties */
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
+
+static const WCHAR monitor_fmtW[] =
+ {'\\','M','o','n','i','t','o','r','%','d',0};
+static const WCHAR adapter_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
+static const WCHAR displayW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
+static const WCHAR video_keyW[] =
+ {'H','A','R','D','W','A','R','E','\\',
+ 'D','E','V','I','C','E','M','A','P','\\',
+ 'V','I','D','E','O','\\',0};
+static const WCHAR video_value_fmtW[] =
+ {'\\','D','e','v','i','c','e','\\',
+ 'V','i','d','e','o','%','d',0};
+static const WCHAR nt_machine_prefixW[] =
+ {'\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\'};
+static const WCHAR monitor_interface_prefixW[] = {'\\','\\','\?','\\',0};
+static const WCHAR guid_devinterface_monitorW[] =
+ {'#','{','e','6','f','0','7','b','5','f','-','e','e','9','7','-',
+ '4','a','9','0','-','b','0','7','6','-','3','3','f','5','7','b','f','4','e','a','a','7','}',0};
+static const WCHAR backslashW[] = {'\\',0};
+static const WCHAR nt_classW[] =
+ {'\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\',
+ 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'C','l','a','s','s','\\',0};
+static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
+static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
+static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
+static const WCHAR mointor_id_value_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
+
#define IMM_INIT_MAGIC 0x19650412
static HWND (WINAPI *imm_get_ui_window)(HKL);
BOOL (WINAPI *imm_register_window)(HWND) = NULL;
@@ -243,11 +283,6 @@ DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd)
return 1;
}
-static const WCHAR primary_device_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
-static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ',
- 'S','y','s','t','e','m',0};
-static const WCHAR primary_device_deviceid[] = {'P','C','I','\\','V','E','N','_','0','0','0','0','&',
- 'D','E','V','_','0','0','0','0',0};
/***********************************************************************
* EnumDisplayDevicesA (USER32.@)
@@ -285,28 +320,170 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpD
/***********************************************************************
* EnumDisplayDevicesW (USER32.@)
*/
-BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
- DWORD dwFlags )
+BOOL WINAPI EnumDisplayDevicesW(LPCWSTR name, DWORD index, LPDISPLAY_DEVICEW display_device, DWORD flags)
{
- FIXME("(%s,%d,%p,0x%08x), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
-
- if (i)
- return FALSE;
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HDEVINFO set;
+ WCHAR key_nameW[MAX_PATH];
+ WCHAR instanceW[MAX_PATH];
+ WCHAR bufferW[1024];
+ WCHAR *next_charW;
+ DWORD size;
+ DWORD type;
+ long adapter_index;
+ BOOL ret = FALSE;
- memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
- memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
-
- lpDisplayDevice->StateFlags =
- DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
- DISPLAY_DEVICE_PRIMARY_DEVICE |
- DISPLAY_DEVICE_VGA_COMPATIBLE;
+ TRACE("%s %d %p 0x%08x\n", debugstr_w(name), index, display_device, flags);
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
- memcpy(lpDisplayDevice->DeviceID, primary_device_deviceid, sizeof(primary_device_deviceid));
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
- lpDisplayDevice->DeviceKey[0] = 0;
+ /* Find adapter */
+ if (!name)
+ {
+ sprintfW(key_nameW, video_value_fmtW, index);
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ bufferW, &size))
+ return FALSE;
+
+ /* DeviceKey */
+ if(display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(display_device->DeviceKey))
+ strcpyW(display_device->DeviceKey, bufferW);
+
+ /* DeviceName */
+ sprintfW(display_device->DeviceName, adapter_fmtW, index + 1);
+
+ /* Strip \Registry\Machine\ */
+ strcpyW(key_nameW, bufferW + ARRAY_SIZE(nt_machine_prefixW));
+
+ /* DeviceString */
+ size = sizeof(display_device->DeviceString);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, key_nameW, driver_descW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ display_device->DeviceString, &size))
+ return FALSE;
+
+ /* StateFlags */
+ size = sizeof(display_device->StateFlags);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, state_flagsW, RRF_RT_REG_DWORD | RRF_ZEROONFAILURE, NULL,
+ &display_device->StateFlags, &size))
+ return FALSE;
+
+ /* DeviceID */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(display_device->DeviceID))
+ {
+ if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
+ display_device->DeviceID[0] = 0;
+ else
+ {
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, gpu_idW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ bufferW, &size))
+ return FALSE;
+ set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
+ if (!SetupDiOpenDeviceInfoW(set, bufferW, NULL, 0, &device_data)
+ || !SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ {
+ SetupDiDestroyDeviceInfoList(set);
+ return FALSE;
+ }
+ strcpyW(display_device->DeviceID, bufferW);
+ }
+ }
- return TRUE;
+ return TRUE;
+ }
+ /* Find monitor */
+ else
+ {
+ /* Check adapter name */
+ if (strncmpiW(name, displayW, ARRAY_SIZE(displayW)))
+ return FALSE;
+
+ adapter_index = strtolW(name + ARRAY_SIZE(displayW), NULL, 10);
+ sprintfW(key_nameW, video_value_fmtW, adapter_index - 1);
+
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL, bufferW,
+ &size))
+ return FALSE;
+
+ /* DeviceName */
+ sprintfW(display_device->DeviceName, adapter_fmtW, adapter_index);
+ sprintfW(display_device->DeviceName + strlenW(display_device->DeviceName), monitor_fmtW, index);
+
+ /* Get monitor instance */
+ /* Strip \Registry\Machine\ first */
+ strcpyW(key_nameW, bufferW + ARRAY_SIZE(nt_machine_prefixW));
+ sprintfW(bufferW, mointor_id_value_fmtW, index);
+
+ size = sizeof(instanceW);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, bufferW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE,
+ NULL, instanceW, &size))
+ return FALSE;
+
+ set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL);
+ if (!SetupDiOpenDeviceInfoW(set, instanceW, NULL, 0, &device_data))
+ goto fail;
+
+ /* StateFlags */
+ if (!SetupDiGetDevicePropertyW(set, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
+ (BYTE *)&display_device->StateFlags, sizeof(display_device->StateFlags), NULL, 0))
+ goto fail;
+
+ /* DeviceString */
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DEVICEDESC, NULL,
+ (BYTE *)display_device->DeviceString,
+ sizeof(display_device->DeviceString), NULL))
+ goto fail;
+
+ /* DeviceKey */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(display_device->DeviceKey))
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcpyW(display_device->DeviceKey, nt_classW);
+ strcatW(display_device->DeviceKey, bufferW);
+ }
+
+ /* DeviceID */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(display_device->DeviceID))
+ {
+ if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
+ {
+ strcpyW(display_device->DeviceID, monitor_interface_prefixW);
+ strcatW(display_device->DeviceID, instanceW);
+ strcatW(display_device->DeviceID, guid_devinterface_monitorW);
+ /* Replace '\\' with '#' after prefix */
+ for (next_charW = display_device->DeviceID + strlenW(monitor_interface_prefixW); *next_charW;
+ next_charW++)
+ {
+ if (*next_charW == '\\')
+ *next_charW = '#';
+ }
+ }
+ else
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcpyW(display_device->DeviceID, bufferW);
+ strcatW(display_device->DeviceID, backslashW);
+
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcatW(display_device->DeviceID, bufferW);
+ }
+ }
+
+ ret = TRUE;
+ fail:
+ SetupDiDestroyDeviceInfoList(set);
+ return ret;
+ }
}
/***********************************************************************
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index bee1085a14..26ee28a122 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -115,7 +115,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
ls = RegQueryValueExA(hkey, video_name, NULL, NULL, (unsigned char *)video_value, &size);
ok(!ls, "#%d: failed to get registry value, error: %#x\n", index, ls);
RegCloseKey(hkey);
- todo_wine ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey);
+ ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey);
}
}
else
@@ -146,13 +146,13 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
* by changing the data and rerun EnumDisplayDevices. But it's difficult to find corresponding PCI device on
* userland. So here we check the expected format instead. */
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
- todo_wine ok(strlen(device->DeviceID) == 0 || /* vista+ */
+ ok(strlen(device->DeviceID) == 0 || /* vista+ */
sscanf(device->DeviceID, "PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
&vendor_id, &device_id, &subsys_id, &revision_id) == 4, /* XP/2003 ignores EDD_GET_DEVICE_INTERFACE_NAME */
"#%d: got %s\n", index, device->DeviceID);
else
{
- todo_wine ok(broken(strlen(device->DeviceID) == 0) || /* XP on Testbot returns an empty string, whereas real machine doesn't */
+ ok(broken(strlen(device->DeviceID) == 0) || /* XP on Testbot returns an empty string, whereas real machine doesn't */
sscanf(device->DeviceID, "PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X", &vendor_id, &device_id, &subsys_id,
&revision_id) == 4, "#%d: wrong DeviceID %s\n", index, device->DeviceID);
}
@@ -173,14 +173,14 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
/* DeviceName */
lstrcpyA(monitor_name, adapter_name);
sprintf(monitor_name + strlen(monitor_name), "\\Monitor%d", monitor_index);
- todo_wine ok(!strcmp(monitor_name, device->DeviceName), "#%d: expect %s, got %s\n", monitor_index, monitor_name, device->DeviceName);
+ ok(!strcmp(monitor_name, device->DeviceName), "#%d: expect %s, got %s\n", monitor_index, monitor_name, device->DeviceName);
/* DeviceString */
ok(strlen(device->DeviceString) > 0, "#%d: expect DeviceString not empty\n", monitor_index);
/* StateFlags */
if (adapter_index == 0 && monitor_index == 0)
- todo_wine ok(device->StateFlags & DISPLAY_DEVICE_ATTACHED, "#%d expect to have a primary monitor attached\n", monitor_index);
+ ok(device->StateFlags & DISPLAY_DEVICE_ATTACHED, "#%d expect to have a primary monitor attached\n", monitor_index);
else
ok(device->StateFlags <= (DISPLAY_DEVICE_ATTACHED | DISPLAY_DEVICE_ACTIVE), "#%d wrong state %#x\n", monitor_index,
device->StateFlags);
@@ -191,7 +191,7 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
{ /* HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\Default_Monitor\4&2abfaa30&0&UID0 GUID_DEVINTERFACE_MONITOR
* ^ ^ ^
* Expect format \\?\DISPLAY#Default_Monitor#4&2abfaa30&0&UID0#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} */
- todo_wine ok(strlen(device->DeviceID) == 0 || /* vista ~ win7 */
+ ok(strlen(device->DeviceID) == 0 || /* vista ~ win7 */
sscanf(device->DeviceID, "\\\\?\\DISPLAY#Default_Monitor#%[^#]#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}", buffer) == 1 || /* win8+ */
(!lstrcmpiA(buffer, device_id_prefix) &&
sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1), /* XP/2003 ignores EDD_GET_DEVICE_INTERFACE_NAME */
@@ -201,16 +201,16 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
{
/* Expect HarewareID value data + Driver value data in HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\Default_Monitor\{Instance} */
/* But we don't know which monitor instance this belongs to, so check format instead */
- todo_wine ok(!lstrcmpiA(buffer, device_id_prefix), "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
- todo_wine ok(sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1,
- "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
+ ok(!lstrcmpiA(buffer, device_id_prefix), "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
+ ok(sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1,
+ "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
}
/* DeviceKey */
lstrcpynA(buffer, device->DeviceKey, sizeof(device_key_prefix));
- todo_wine ok(!lstrcmpiA(buffer, device_key_prefix), "#%d: wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
- todo_wine ok(sscanf(device->DeviceKey + sizeof(device_key_prefix) - 1, "%04d", &number) == 1,
- "#%d wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
+ ok(!lstrcmpiA(buffer, device_key_prefix), "#%d: wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
+ ok(sscanf(device->DeviceKey + sizeof(device_key_prefix) - 1, "%04d", &number) == 1,
+ "#%d wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
}
static void test_enumdisplaydevices(void)
@@ -235,7 +235,7 @@ static void test_enumdisplaydevices(void)
/* Doesn't accept \\.\DISPLAY */
dd.cb = sizeof(dd);
ret = pEnumDisplayDevicesA("\\\\.\\DISPLAY", 0, &dd, 0);
- todo_wine ok(!ret, "Expect failure\n");
+ ok(!ret, "Expect failure\n");
/* Enumeration */
for (flag_index = 0; flag_index < ARRAY_SIZE(flags); flag_index++)
--
2.20.1
2
1
[PATCH v5 6/7] explorer: Create display device registry fallback data if necessary.
by Zhiyi Zhang 20 May '19
by Zhiyi Zhang 20 May '19
20 May '19
If user driver didn't initialize the display device registry data, create
some fallback data to at least make EnumDisplayDevice report a primary
adapter. Otherwise, report back the primary adapter GUID to store in the
desktop HWND atom, instead of creating a new one.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/desktop.c | 11 +--
dlls/user32/tests/monitor.c | 6 +-
programs/explorer/Makefile.in | 2 +-
programs/explorer/desktop.c | 167 ++++++++++++++++++++++++++++------
4 files changed, 143 insertions(+), 43 deletions(-)
diff --git a/dlls/user32/desktop.c b/dlls/user32/desktop.c
index fe6649446e..3662a68976 100644
--- a/dlls/user32/desktop.c
+++ b/dlls/user32/desktop.c
@@ -101,28 +101,21 @@ LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lP
static const WCHAR display_device_guid_propW[] = {
'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
'd','e','v','i','c','e','_','g','u','i','d',0 };
- static const WCHAR guid_formatW[] = {
- '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
- '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',0};
switch (message)
{
case WM_NCCREATE:
{
CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
- const GUID *guid = cs->lpCreateParams;
+ WCHAR *guid = cs->lpCreateParams;
if (guid)
{
ATOM atom;
- WCHAR buffer[37];
if (GetAncestor( hwnd, GA_PARENT )) return FALSE; /* refuse to create non-desktop window */
- sprintfW( buffer, guid_formatW, guid->Data1, guid->Data2, guid->Data3,
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
- atom = GlobalAddAtomW( buffer );
+ atom = GlobalAddAtomW( guid );
SetPropW( hwnd, display_device_guid_propW, ULongToHandle( atom ) );
}
return TRUE;
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index c5e6745322..bee1085a14 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -81,7 +81,7 @@ static int monitor_count = 0;
static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *device, DWORD flags)
{
- char video_name[16];
+ char video_name[32];
char video_value[128];
char buffer[128];
int number;
@@ -107,7 +107,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
{
sprintf(video_name, "\\Device\\Video%d", index);
ls = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkey);
- todo_wine ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
+ ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
if (!ls)
{
memset(video_value, 0, sizeof(video_value));
@@ -115,7 +115,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
ls = RegQueryValueExA(hkey, video_name, NULL, NULL, (unsigned char *)video_value, &size);
ok(!ls, "#%d: failed to get registry value, error: %#x\n", index, ls);
RegCloseKey(hkey);
- ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey);
+ todo_wine ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey);
}
}
else
diff --git a/programs/explorer/Makefile.in b/programs/explorer/Makefile.in
index 374c6aaebe..13b0ed3dfa 100644
--- a/programs/explorer/Makefile.in
+++ b/programs/explorer/Makefile.in
@@ -1,5 +1,5 @@
MODULE = explorer.exe
-IMPORTS = rpcrt4 user32 gdi32 advapi32
+IMPORTS = rpcrt4 user32 gdi32 advapi32 setupapi
DELAYIMPORTS = comctl32 shell32 oleaut32 ole32 shlwapi
EXTRADLLFLAGS = -mwindows -municode -mno-cygwin
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 2857fcfca9..da93f1e4ba 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -27,6 +27,11 @@
#include <rpc.h>
#include <shlobj.h>
#include <shellapi.h>
+#include <wingdi.h>
+#include <initguid.h>
+#include <devguid.h>
+#include <devpkey.h>
+#include <setupapi.h>
#include "exdisp.h"
#include "wine/debug.h"
@@ -752,24 +757,143 @@ static BOOL get_default_enable_shell( const WCHAR *name )
return result;
}
-static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
-{
- static const WCHAR device_keyW[] = {
+/* Initialize the display device registry if user driver didn't do it,
+ * and report the primary adapter guid in paramter guid_string. */
+static BOOL initialize_fallback_display_devices( const WCHAR *driver_path, WCHAR *guid_string )
+{
+ static const WCHAR video_keyW[] = {
+ 'H','A','R','D','W','A','R','E','\\',
+ 'D','E','V','I','C','E','M','A','P','\\',
+ 'V','I','D','E','O',0};
+ static const WCHAR device_video0W[] = {
+ '\\','D','e','v','i','c','e','\\',
+ 'V','i','d','e','o','0',0};
+ static const WCHAR device_video_prefixW[] = {
+ '\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\',0};
+ static const WCHAR gpu_instanceW[] = {
+ 'P','C','I','\\',
+ 'V','E','N','_','0','0','0','0','&',
+ 'D','E','V','_','0','0','0','0','&',
+ 'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
+ 'R','E','V','_','0','0','\\',
+ '0','0','0','0','0','0','0','0',0};
+ static const WCHAR gpu_hardware_idW[] = {
+ 'P','C','I','\\',
+ 'V','E','N','_','0','0','0','0','&',
+ 'D','E','V','_','0','0','0','0','&',
+ 'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
+ 'R','E','V','_','0','0',0,0};
+ static const WCHAR device_key_fmtW[] = {
'S','y','s','t','e','m','\\',
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
'C','o','n','t','r','o','l','\\',
'V','i','d','e','o','\\',
- '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
- '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
- '%','0','2','x','%','0','2','x','%','0','2','x','}','\\','0','0','0','0',0};
+ '{','%','s','}','\\',
+ '0','0','0','0',0};
+ static const WCHAR guid_formatW[] = {
+ '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
+ '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',0};
static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
+ static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
+ static const WCHAR wine_gpuW[] = {'W','i','n','e',' ','G','P','U',0};
+ static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
+ static const DWORD primary_state_flags = DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+ HDEVINFO devinfo;
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ WCHAR adapter_keyW[MAX_PATH];
+ WCHAR bufferW[MAX_PATH];
+ DWORD disposition = 0;
+ DWORD size;
+ GUID guid;
+ HKEY hkey = NULL;
+ BOOL ret = FALSE;
+
+ /* Create HKLM\HARDWARE\DEVICEMAP\VIDEO key if user drivers didn't do it */
+ RegCreateKeyExW( HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition );
+
+ /* User driver did create it. Report back primary adapter guid */
+ if (disposition != REG_CREATED_NEW_KEY)
+ {
+ size = sizeof(bufferW);
+ if (!RegQueryValueExW( hkey, device_video0W, NULL, NULL, (BYTE *)bufferW, &size ))
+ {
+ /* Skip over \Registry\Machine\System\CurrentControlSet\Control\Video\{ to get guid string */
+ memcpy( guid_string, bufferW + 58, 36 * sizeof(WCHAR) );
+ guid_string[36] = 0;
+ RegCloseKey( hkey );
+ return TRUE;
+ }
+ /* Falling through */
+ }
+
+ /* Create basic display device registry data so that functions like EnumDisplayDevice can at least report
+ * a primary adapter */
+ /* Init GPU */
+ devinfo = SetupDiCreateDeviceInfoList( &GUID_DEVCLASS_DISPLAY, NULL );
+ if (!SetupDiOpenDeviceInfoW( devinfo, gpu_instanceW, NULL, 0, &device_data ))
+ {
+ SetupDiCreateDeviceInfoW( devinfo, gpu_instanceW, &GUID_DEVCLASS_DISPLAY, NULL, NULL, 0, &device_data );
+ if (!SetupDiRegisterDeviceInfo( devinfo, &device_data, 0, NULL, NULL, NULL ))
+ goto fail;
+ }
+
+ /* Write HardwareID */
+ if (!SetupDiSetDeviceRegistryPropertyW( devinfo, &device_data, SPDRP_HARDWAREID, (const BYTE *)(gpu_hardware_idW),
+ sizeof(gpu_hardware_idW) ))
+ goto fail;
+
+ /* Init primary adapter */
+ UuidCreate( &guid );
+ swprintf( guid_string, 37, guid_formatW, guid.Data1, guid.Data2, guid.Data3,
+ guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
+ guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
+ swprintf( adapter_keyW, ARRAY_SIZE(adapter_keyW), device_key_fmtW, guid_string );
+ lstrcpyW( bufferW, device_video_prefixW );
+ lstrcatW( bufferW, adapter_keyW );
+
+ /* Write value of \Device\Video0 in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
+ if (RegSetValueExW( hkey, device_video0W, 0, REG_SZ, (const BYTE *)bufferW, (lstrlenW( bufferW ) + 1) * sizeof(WCHAR) ))
+ goto fail;
+ RegCloseKey( hkey );
+ hkey = NULL;
+
+ /* Write GraphicsDriver */
+ RegCreateKeyExW( HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL );
+ if (RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ, (const BYTE *)driver_path, (lstrlenW( driver_path ) + 1) * sizeof(WCHAR) ))
+ goto fail;
+
+ /* Write DriverDesc */
+ if (RegSetValueExW( hkey, driver_descW, 0, REG_SZ, (const BYTE *)wine_gpuW, (lstrlenW( wine_gpuW ) + 1) * sizeof(WCHAR) ))
+ goto fail;
+
+ RegCloseKey( hkey );
+ hkey = NULL;
+
+ RegCreateKeyExW( HKEY_CURRENT_CONFIG, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL );
+ /* Write StateFlags */
+ if (RegSetValueExW( hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&primary_state_flags,
+ sizeof(primary_state_flags) ))
+ goto fail;
+
+ ret = TRUE;
+fail:
+ RegCloseKey( hkey );
+ SetupDiDestroyDeviceInfoList( devinfo );
+ if (!ret)
+ ERR("Failed to initialize fallback display device registry data\n");
+ return ret;
+}
+
+/* Load graphics driver, return its module handle in hmodule and report primary adapter guid in guid */
+static void load_graphics_driver( const WCHAR *driver, HMODULE *hmodule, WCHAR *guid )
+{
static const WCHAR driversW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','r','s',0};
static const WCHAR graphicsW[] = {'G','r','a','p','h','i','c','s',0};
static const WCHAR drv_formatW[] = {'w','i','n','e','%','s','.','d','r','v',0};
WCHAR buffer[MAX_PATH], libname[32], *name, *next;
- WCHAR key[ARRAY_SIZE( device_keyW ) + 39];
HMODULE module = 0;
HKEY hkey;
char error[80];
@@ -812,27 +936,12 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
}
if (module)
- {
GetModuleFileNameW( module, buffer, MAX_PATH );
- TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) );
- }
- swprintf( key, ARRAY_SIZE(key), device_keyW, guid->Data1, guid->Data2, guid->Data3,
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
+ initialize_fallback_display_devices( buffer, guid );
+ TRACE( "display %s driver %s\n", debugstr_w(guid), debugstr_w(buffer) );
- if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
- REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL ))
- {
- if (module)
- RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ,
- (BYTE *)buffer, (lstrlenW(buffer) + 1) * sizeof(WCHAR) );
- else
- RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 );
- RegCloseKey( hkey );
- }
-
- return module;
+ *hmodule = module;
}
static void initialize_display_settings(void)
@@ -891,7 +1000,7 @@ void manage_desktop( WCHAR *arg )
{
static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
HDESK desktop = 0;
- GUID guid;
+ WCHAR guid[37] = {0};
MSG msg;
HWND hwnd;
HMODULE graphics_driver;
@@ -943,13 +1052,11 @@ void manage_desktop( WCHAR *arg )
SetThreadDesktop( desktop );
}
- UuidCreate( &guid );
- TRACE( "display guid %s\n", debugstr_guid(&guid) );
- graphics_driver = load_graphics_driver( driver, &guid );
+ load_graphics_driver( driver, &graphics_driver, guid );
/* create the desktop window */
hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
- WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid );
+ WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, guid );
if (hwnd)
{
--
2.20.1
2
1
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/desktop.c | 2 ++
dlls/winex11.drv/display.c | 7 +++++--
dlls/winex11.drv/x11drv.h | 2 +-
dlls/winex11.drv/x11drv_main.c | 2 +-
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index d478cbdcb3..c69c2122ab 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -154,6 +154,7 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height )
max_width = primary_rect.right - primary_rect.left;
max_height = primary_rect.bottom - primary_rect.top;
xinerama_init( width, height );
+ X11DRV_DisplayDevices_Init( "Xinerama", TRUE );
/* initialize the available resolutions */
dd_modes = X11DRV_Settings_SetHandlers("desktop",
@@ -303,6 +304,7 @@ void X11DRV_resize_desktop( unsigned int width, unsigned int height )
resize_data.old_virtual_rect = get_virtual_screen_rect();
xinerama_init( width, height );
+ X11DRV_DisplayDevices_Init( "Xinerama", TRUE );
resize_data.new_virtual_rect = get_virtual_screen_rect();
if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId())
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index f6be8de0e2..5bd0c3ea51 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -374,7 +374,7 @@ static void cleanup_devices(void)
SetupDiDestroyDeviceInfoList(devinfo);
}
-void X11DRV_DisplayDevices_Init(void)
+void X11DRV_DisplayDevices_Init(const char *name, BOOL force)
{
struct x11drv_gpu *gpus = NULL;
struct x11drv_adapter *adapters = NULL;
@@ -391,12 +391,15 @@ void X11DRV_DisplayDevices_Init(void)
TRACE("via %s\n", wine_dbgstr_a(handler.name));
+ if (name && strcmp(handler.name, name))
+ TRACE("Wrong handler name %s, ignoring\n", name);
+
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &video_hkey,
&disposition))
goto fail;
/* Ensure only one thread is initializing the registry and avoid unnecessary reinit */
- if (disposition != REG_CREATED_NEW_KEY)
+ if (!force && disposition != REG_CREATED_NEW_KEY)
{
success = TRUE;
goto fail;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 40392b03c0..035d7cc9ab 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -740,7 +740,7 @@ struct x11drv_display_device_handler
};
extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN;
-extern void X11DRV_DisplayDevices_Init(void) DECLSPEC_HIDDEN;
+extern void X11DRV_DisplayDevices_Init(const char *name, BOOL force) DECLSPEC_HIDDEN;
/* XIM support */
extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 69478741f1..b0fa225565 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -597,7 +597,7 @@ static BOOL process_attach(void)
X11DRV_InitKeyboard( gdi_display );
if (use_xim) use_xim = X11DRV_InitXIM( input_style );
- X11DRV_DisplayDevices_Init();
+ X11DRV_DisplayDevices_Init(NULL, FALSE);
return TRUE;
}
--
2.20.1
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/display.c | 120 +++++++++++++++++++++++++++++++++++--
1 file changed, 115 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 0dbc92846b..f6be8de0e2 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -39,11 +39,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
+/* Wine specific monitor properties */
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
+
static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0};
static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
+static const WCHAR mointor_id_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
+static const WCHAR adapter_name_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
static const WCHAR guid_fmtW[] = {
'{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
@@ -90,6 +98,13 @@ static const WCHAR device_video_fmtW[] = {
static const WCHAR machine_prefixW[] = {
'\\','R','e','g','i','s','t','r','y','\\',
'M','a','c','h','i','n','e','\\',0};
+static const WCHAR monitor_instance_fmtW[] = {
+ 'D','I','S','P','L','A','Y','\\',
+ 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','\\',
+ '%','0','4','X','&','%','0','4','X',0};
+static const WCHAR monitor_hardware_idW[] = {
+ 'M','O','N','I','T','O','R','\\',
+ 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r',0,0};
static struct x11drv_display_device_handler handler;
@@ -185,7 +200,7 @@ fail:
return ret;
}
-static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index,
+static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index, INT monitor_count,
const struct x11drv_gpu *gpu, const WCHAR *guid_string,
const WCHAR *gpu_driver, const struct x11drv_adapter *adapter)
{
@@ -195,6 +210,7 @@ static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index,
HKEY hkey = NULL;
BOOL ret = FALSE;
LSTATUS ls;
+ INT i;
sprintfW(key_nameW, device_video_fmtW, video_index);
strcpyW(bufferW, machine_prefixW);
@@ -229,6 +245,15 @@ static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index,
if (RegSetValueExW(hkey, gpu_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto fail;
+ /* Write all monitor instances paths under this adapter */
+ for (i = 0; i < monitor_count; i++)
+ {
+ sprintfW(key_nameW, mointor_id_fmtW, i);
+ sprintfW(bufferW, monitor_instance_fmtW, video_index, i);
+ if (RegSetValueExW(hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
+ goto fail;
+ }
+
/* Write StateFlags */
if (RegSetValueExW(hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&adapter->state_flags,
sizeof(adapter->state_flags)))
@@ -242,6 +267,64 @@ fail:
return ret;
}
+static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *monitor, int monitor_index,
+ int video_index)
+{
+ WCHAR bufferW[MAX_PATH];
+ SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
+ HKEY hkey = NULL;
+ BOOL ret = FALSE;
+
+ /* Create GUID_DEVCLASS_MONITOR instance */
+ sprintfW(bufferW, monitor_instance_fmtW, video_index, monitor_index);
+ SetupDiCreateDeviceInfoW(devinfo, bufferW, &GUID_DEVCLASS_MONITOR, monitor->name, NULL, 0, &device_data);
+ if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL))
+ goto fail;
+
+ /* Write HaredwareID registry property */
+ if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID,
+ (const BYTE *)monitor_hardware_idW, sizeof(monitor_hardware_idW)))
+ goto fail;
+
+ /* Open driver key */
+ hkey = SetupDiOpenDevRegKey(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
+ if (hkey == INVALID_HANDLE_VALUE)
+ hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
+
+ /* Write DriverDesc value */
+ if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)monitor->name,
+ (strlenW(monitor->name) + 1) * sizeof(WCHAR)))
+ goto fail;
+
+ /* FIXME:
+ * Following properties are Wine specific, see comments in X11DRV_InitAdapter for details */
+ /* StateFlags */
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32,
+ (const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0))
+ goto fail;
+ /* RcMonitor */
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
+ (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
+ goto fail;
+ /* RcWork */
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
+ (const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0))
+ goto fail;
+
+ sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
+ /* Adapter name */
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
+ (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR), 0))
+ goto fail;
+
+ ret = TRUE;
+fail:
+ RegCloseKey(hkey);
+ if (!ret)
+ ERR("Failed to initialize monitor\n");
+ return ret;
+}
+
static void prepare_devices(void)
{
static const BOOL not_present = FALSE;
@@ -249,8 +332,18 @@ static void prepare_devices(void)
HDEVINFO devinfo;
DWORD i = 0;
+ /* Remove all monitors */
+ devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, NULL, NULL, 0);
+ while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
+ {
+ if (!SetupDiRemoveDevice(devinfo, &device_data))
+ ERR("Failed to remove monitor\n");
+ }
+ SetupDiDestroyDeviceInfoList(devinfo);
+
/* Set all GPUs as not present. We can't simply delete them because we need to keep the GUID consistent with
* each initialization run. We clean up non present GPUs at the end of initialization */
+ i = 0;
devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0);
while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
{
@@ -285,9 +378,10 @@ void X11DRV_DisplayDevices_Init(void)
{
struct x11drv_gpu *gpus = NULL;
struct x11drv_adapter *adapters = NULL;
- INT gpu_count, adapter_count;
- INT gpu, adapter;
- HDEVINFO gpu_devinfo = NULL;
+ struct x11drv_monitor *monitors = NULL;
+ INT gpu_count, adapter_count, monitor_count;
+ INT gpu, adapter, monitor;
+ HDEVINFO gpu_devinfo = NULL, monitor_devinfo = NULL;
HKEY video_hkey = NULL;
INT video_index = 0;
DWORD disposition = 0;
@@ -316,6 +410,7 @@ void X11DRV_DisplayDevices_Init(void)
prepare_devices();
gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
+ monitor_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL);
/* Initialize GPUs */
if (!handler.pGetGpus(&gpus, &gpu_count))
@@ -332,10 +427,22 @@ void X11DRV_DisplayDevices_Init(void)
for (adapter = 0; adapter < adapter_count; adapter++)
{
- if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter,
+ if (!handler.pGetMonitors(adapters[adapter].id, &monitors, &monitor_count))
+ goto fail;
+
+ if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter, monitor_count,
&gpus[gpu], guidW, driverW, &adapters[adapter]))
goto fail;
+ /* Initialize monitors */
+ for (monitor = 0; monitor < monitor_count; monitor++)
+ {
+ if (!X11DRV_InitMonitor(monitor_devinfo, &monitors[monitor], monitor, video_index))
+ goto fail;
+ }
+
+ handler.pFreeMonitors(monitors);
+ monitors = NULL;
video_index++;
}
@@ -346,12 +453,15 @@ void X11DRV_DisplayDevices_Init(void)
success = TRUE;
fail:
cleanup_devices();
+ SetupDiDestroyDeviceInfoList(monitor_devinfo);
SetupDiDestroyDeviceInfoList(gpu_devinfo);
RegCloseKey(video_hkey);
if (gpus)
handler.pFreeGpus(gpus);
if (adapters)
handler.pFreeAdapters(adapters);
+ if (monitors)
+ handler.pFreeMonitors(monitors);
if (!success)
ERR("Failed to initialize display devices\n");
}
--
2.20.1
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/display.c | 97 +++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index d69380d8bc..0dbc92846b 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -42,6 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0};
+static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
+static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
+static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
static const WCHAR guid_fmtW[] = {
'{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
'%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};
@@ -74,6 +77,19 @@ static const WCHAR video_keyW[] = {
'H','A','R','D','W','A','R','E','\\',
'D','E','V','I','C','E','M','A','P','\\',
'V','I','D','E','O',0};
+static const WCHAR adapter_key_fmtW[] = {
+ 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'V','i','d','e','o','\\',
+ '%','s','\\',
+ '%','0','4','x',0};
+static const WCHAR device_video_fmtW[] = {
+ '\\','D','e','v','i','c','e','\\',
+ 'V','i','d','e','o','%','d',0};
+static const WCHAR machine_prefixW[] = {
+ '\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\',0};
static struct x11drv_display_device_handler handler;
@@ -169,6 +185,63 @@ fail:
return ret;
}
+static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index,
+ const struct x11drv_gpu *gpu, const WCHAR *guid_string,
+ const WCHAR *gpu_driver, const struct x11drv_adapter *adapter)
+{
+ WCHAR adapter_keyW[MAX_PATH];
+ WCHAR key_nameW[MAX_PATH];
+ WCHAR bufferW[1024];
+ HKEY hkey = NULL;
+ BOOL ret = FALSE;
+ LSTATUS ls;
+
+ sprintfW(key_nameW, device_video_fmtW, video_index);
+ strcpyW(bufferW, machine_prefixW);
+ sprintfW(adapter_keyW, adapter_key_fmtW, guid_string, adapter_index);
+ strcatW(bufferW, adapter_keyW);
+
+ /* Write value of \Device\Video? (adapter key) in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
+ if (RegSetValueExW(video_hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
+ goto fail;
+
+ /* Create HKLM\System\CurrentControlSet\Control\Video\{GPU GUID}\{Adapter Index} link to GPU driver */
+ ls = RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+ KEY_ALL_ACCESS, NULL, &hkey, NULL);
+ if (ls == ERROR_ALREADY_EXISTS)
+ RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK,
+ KEY_ALL_ACCESS, NULL, &hkey, NULL);
+ if (RegSetValueExW(hkey, symbolic_link_valueW, 0, REG_LINK, (const BYTE *)gpu_driver,
+ strlenW(gpu_driver) * sizeof(WCHAR)))
+ goto fail;
+ RegCloseKey(hkey);
+ hkey = NULL;
+
+ /* FIXME:
+ * Following information are Wine specific, they don't really exist on Windows. They are used so that we can
+ * implement EnumDisplayDevices etc by querying registry only. These information are most likely reported by the
+ * device driver on Windows */
+ RegCreateKeyExW(HKEY_CURRENT_CONFIG, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
+
+ /* Write GPU instance path so that we can find the GPU instance via adapters quickly. Another way is trying to match
+ * them via the GUID in Device Paramters/VideoID, but it would required enumrating all GPU instances */
+ sprintfW(bufferW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index);
+ if (RegSetValueExW(hkey, gpu_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
+ goto fail;
+
+ /* Write StateFlags */
+ if (RegSetValueExW(hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&adapter->state_flags,
+ sizeof(adapter->state_flags)))
+ goto fail;
+
+ ret = TRUE;
+fail:
+ RegCloseKey(hkey);
+ if (!ret)
+ ERR("Failed to initialize adapter\n");
+ return ret;
+}
+
static void prepare_devices(void)
{
static const BOOL not_present = FALSE;
@@ -211,10 +284,12 @@ static void cleanup_devices(void)
void X11DRV_DisplayDevices_Init(void)
{
struct x11drv_gpu *gpus = NULL;
- INT gpu_count;
- INT gpu;
+ struct x11drv_adapter *adapters = NULL;
+ INT gpu_count, adapter_count;
+ INT gpu, adapter;
HDEVINFO gpu_devinfo = NULL;
HKEY video_hkey = NULL;
+ INT video_index = 0;
DWORD disposition = 0;
WCHAR guidW[40];
WCHAR driverW[1024];
@@ -250,6 +325,22 @@ void X11DRV_DisplayDevices_Init(void)
{
if (!X11DRV_InitGpu(gpu_devinfo, &gpus[gpu], gpu, guidW, driverW))
goto fail;
+
+ /* Initialize adapters */
+ if (!handler.pGetAdapters(gpus[gpu].id, &adapters, &adapter_count))
+ goto fail;
+
+ for (adapter = 0; adapter < adapter_count; adapter++)
+ {
+ if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter,
+ &gpus[gpu], guidW, driverW, &adapters[adapter]))
+ goto fail;
+
+ video_index++;
+ }
+
+ handler.pFreeAdapters(adapters);
+ adapters = NULL;
}
success = TRUE;
@@ -259,6 +350,8 @@ fail:
RegCloseKey(video_hkey);
if (gpus)
handler.pFreeGpus(gpus);
+ if (adapters)
+ handler.pFreeAdapters(adapters);
if (!success)
ERR("Failed to initialize display devices\n");
}
--
2.20.1
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/Makefile.in | 2 +-
dlls/winex11.drv/display.c | 190 +++++++++++++++++++++++++++++++++++
2 files changed, 191 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in
index 9ca2fc6efe..72ab1bb77b 100644
--- a/dlls/winex11.drv/Makefile.in
+++ b/dlls/winex11.drv/Makefile.in
@@ -1,5 +1,5 @@
MODULE = winex11.drv
-IMPORTS = uuid user32 gdi32 advapi32
+IMPORTS = uuid user32 gdi32 advapi32 ntoskrnl setupapi
DELAYIMPORTS = comctl32 ole32 shell32 imm32
EXTRAINCL = $(X_CFLAGS)
EXTRALIBS = $(X_LIBS) $(X_EXTRA_LIBS)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 7d81de09ac..d69380d8bc 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -26,11 +26,50 @@
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
+#include "initguid.h"
+#include "devguid.h"
+#include "devpkey.h"
+#include "setupapi.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+#include "ddk/ntddk.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
#include "x11drv.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
+static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
+static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
+static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0};
+static const WCHAR guid_fmtW[] = {
+ '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
+ '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};
+static const WCHAR gpu_instance_fmtW[] = {
+ 'P','C','I','\\',
+ 'V','E','N','_','%','0','4','X','&',
+ 'D','E','V','_','%','0','4','X','&',
+ 'S','U','B','S','Y','S','_','%','0','8','X','&',
+ 'R','E','V','_','%','0','2','X','\\',
+ '%','0','8','X',0};
+static const WCHAR gpu_hardware_id_fmtW[] = {
+ 'P','C','I','\\',
+ 'V','E','N','_','%','0','4','X','&',
+ 'D','E','V','_','%','0','4','X','&',
+ 'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
+ 'R','E','V','_','0','0',0};
+static const WCHAR winex11_drvW[] = {
+ 'C',':','\\',
+ 'W','i','n','d','o','w','s','\\',
+ 'S','y','s','t','e','m','3','2','\\',
+ 'w','i','n','e','x','1','1','.','d','r','v',0};
+static const WCHAR nt_classW[] = {
+ '\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\',
+ 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'C','l','a','s','s','\\',0};
static const WCHAR video_keyW[] = {
'H','A','R','D','W','A','R','E','\\',
'D','E','V','I','C','E','M','A','P','\\',
@@ -47,10 +86,138 @@ void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler
}
}
+/* Initialize a GPU instance and return its GUID string in guid_string and driver value in driver parameter */
+static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct x11drv_gpu *gpu, INT gpu_index, WCHAR *guid_string,
+ WCHAR *driver)
+{
+ static const BOOL present = TRUE;
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ WCHAR instanceW[MAX_PATH];
+ WCHAR bufferW[1024];
+ HKEY hkey = NULL;
+ GUID guid;
+ INT written;
+ DWORD size;
+ BOOL ret = FALSE;
+
+ sprintfW(instanceW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index);
+ if (!SetupDiOpenDeviceInfoW(devinfo, instanceW, NULL, 0, &device_data))
+ {
+ SetupDiCreateDeviceInfoW(devinfo, instanceW, &GUID_DEVCLASS_DISPLAY, gpu->name, NULL, 0, &device_data);
+ if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL))
+ goto fail;
+ }
+
+ /* Write HaredwareID registry property */
+ written = sprintfW(bufferW, gpu_hardware_id_fmtW, gpu->vendor_id, gpu->device_id);
+ bufferW[written + 1] = 0;
+ if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID, (const BYTE *)bufferW,
+ (written + 2) * sizeof(WCHAR)))
+ goto fail;
+
+ /* Write DEVPKEY_Device_IsPresent property */
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN,
+ (const BYTE *)&present, sizeof(present), 0))
+ goto fail;
+
+ /* Open driver key.
+ * This is where HKLM\System\CurrentControlSet\Control\Video\{GPU GUID}\{Adapter Index} links to */
+ hkey = SetupDiOpenDevRegKey(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
+ if (hkey == INVALID_HANDLE_VALUE)
+ hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
+
+ /* Write GraphicsDriver value */
+ if (RegSetValueExW(hkey, graphics_driverW, 0, REG_SZ, (const BYTE *)winex11_drvW, sizeof(winex11_drvW)))
+ goto fail;
+
+ /* Write DriverDesc value */
+ if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)gpu->name,
+ (strlenW(gpu->name) + 1) * sizeof(WCHAR)))
+ goto fail;
+ RegCloseKey(hkey);
+ hkey = NULL;
+
+ /* Retrieve driver value for adapters */
+ if (!SetupDiGetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW, sizeof(bufferW),
+ NULL))
+ goto fail;
+ strcpyW(driver, nt_classW);
+ strcatW(driver, bufferW);
+
+ /* Write GUID in VideoID in .../instance/Device Parameters, reuse the GUID if it's existent */
+ hkey = SetupDiOpenDevRegKey(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS);
+ if (hkey == INVALID_HANDLE_VALUE)
+ hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL);
+
+ size = sizeof(bufferW);
+ bufferW[0] = 0;
+ if (RegQueryValueExW(hkey, video_idW, 0, NULL, (BYTE *)bufferW, &size))
+ {
+ ExUuidCreate(&guid);
+ sprintfW(bufferW, guid_fmtW, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2],
+ guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
+ if (RegSetValueExW(hkey, video_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
+ goto fail;
+ }
+ strcpyW(guid_string, bufferW);
+
+ ret = TRUE;
+fail:
+ RegCloseKey(hkey);
+ if (!ret)
+ ERR("Failed to initialize GPU\n");
+ return ret;
+}
+
+static void prepare_devices(void)
+{
+ static const BOOL not_present = FALSE;
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HDEVINFO devinfo;
+ DWORD i = 0;
+
+ /* Set all GPUs as not present. We can't simply delete them because we need to keep the GUID consistent with
+ * each initialization run. We clean up non present GPUs at the end of initialization */
+ devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0);
+ while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
+ {
+ if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN,
+ (const BYTE *)¬_present, sizeof(not_present), 0))
+ ERR("Failed to set GPU present property\n");
+ }
+ SetupDiDestroyDeviceInfoList(devinfo);
+}
+
+static void cleanup_devices(void)
+{
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HDEVINFO devinfo;
+ DWORD type;
+ DWORD i = 0;
+ BOOL present;
+
+ devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0);
+ while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
+ {
+ present = FALSE;
+ SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, &type, (BYTE *)&present,
+ sizeof(present), NULL, 0);
+ if (!present && !SetupDiRemoveDevice(devinfo, &device_data))
+ ERR("Failed to remove GPU\n");
+ }
+ SetupDiDestroyDeviceInfoList(devinfo);
+}
+
void X11DRV_DisplayDevices_Init(void)
{
+ struct x11drv_gpu *gpus = NULL;
+ INT gpu_count;
+ INT gpu;
+ HDEVINFO gpu_devinfo = NULL;
HKEY video_hkey = NULL;
DWORD disposition = 0;
+ WCHAR guidW[40];
+ WCHAR driverW[1024];
BOOL success = FALSE;
TRACE("via %s\n", wine_dbgstr_a(handler.name));
@@ -66,9 +233,32 @@ void X11DRV_DisplayDevices_Init(void)
goto fail;
}
+ /* FIXME:
+ * Currently we have no idea how to implement SetupDiGetClassDevsW with DIGCF_PRESENT properly. So we need to clean
+ * up not present devices in case application use SetupDiGetClassDevsW to enumerate devices. Wrong devices could
+ * exist in registry as a result of prefix copying or having devices unplugged. But then we couldn't simply delete
+ * GPUs because we need to retain the same GUID for the same GPU. */
+ prepare_devices();
+
+ gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
+
+ /* Initialize GPUs */
+ if (!handler.pGetGpus(&gpus, &gpu_count))
+ goto fail;
+
+ for (gpu = 0; gpu < gpu_count; gpu++)
+ {
+ if (!X11DRV_InitGpu(gpu_devinfo, &gpus[gpu], gpu, guidW, driverW))
+ goto fail;
+ }
+
success = TRUE;
fail:
+ cleanup_devices();
+ SetupDiDestroyDeviceInfoList(gpu_devinfo);
RegCloseKey(video_hkey);
+ if (gpus)
+ handler.pFreeGpus(gpus);
if (!success)
ERR("Failed to initialize display devices\n");
}
--
2.20.1
1
0
[PATCH] msxml3: Load the version 1 typelib before trying to access it.
by Zebediah Figura 20 May '19
by Zebediah Figura 20 May '19
20 May '19
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47214
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/msxml3/dispex.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/dlls/msxml3/dispex.c b/dlls/msxml3/dispex.c
index bd29a212c8..b1fb72847e 100644
--- a/dlls/msxml3/dispex.c
+++ b/dlls/msxml3/dispex.c
@@ -150,31 +150,43 @@ static inline unsigned get_libid_from_tid(tid_t tid)
return tid_ids[tid].lib;
}
-HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
+static HRESULT get_typelib(unsigned lib, ITypeLib **tl)
{
- unsigned lib = get_libid_from_tid(tid);
HRESULT hres;
if(!typelib[lib]) {
- ITypeLib *tl;
-
- hres = LoadRegTypeLib(lib_ids[lib].iid, lib_ids[lib].major, 0, LOCALE_SYSTEM_DEFAULT, &tl);
+ hres = LoadRegTypeLib(lib_ids[lib].iid, lib_ids[lib].major, 0, LOCALE_SYSTEM_DEFAULT, tl);
if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08x\n", hres);
return hres;
}
- if(InterlockedCompareExchangePointer((void**)&typelib[lib], tl, NULL))
- ITypeLib_Release(tl);
+ if (InterlockedCompareExchangePointer((void**)&typelib[lib], *tl, NULL))
+ ITypeLib_Release(*tl);
}
+ *tl = typelib[lib];
+ return S_OK;
+}
+
+HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
+{
+ unsigned lib = get_libid_from_tid(tid);
+ ITypeLib *typelib;
+ HRESULT hres;
+
+ if (FAILED(hres = get_typelib(lib, &typelib)))
+ return hres;
+
if(!typeinfos[tid]) {
ITypeInfo *ti;
- hres = ITypeLib_GetTypeInfoOfGuid(typelib[lib], get_riid_from_tid(tid), &ti);
+ hres = ITypeLib_GetTypeInfoOfGuid(typelib, get_riid_from_tid(tid), &ti);
if(FAILED(hres)) {
/* try harder with typelib from msxml.dll */
- hres = ITypeLib_GetTypeInfoOfGuid(typelib[LibXml], get_riid_from_tid(tid), &ti);
+ if (FAILED(hres = get_typelib(LibXml, &typelib)))
+ return hres;
+ hres = ITypeLib_GetTypeInfoOfGuid(typelib, get_riid_from_tid(tid), &ti);
if(FAILED(hres)) {
ERR("GetTypeInfoOfGuid failed: %08x\n", hres);
return hres;
--
2.21.0
2
1
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/misc.c | 223 ++++++++++++++++++++++++++++++++----
dlls/user32/tests/monitor.c | 26 ++---
2 files changed, 213 insertions(+), 36 deletions(-)
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c
index 1a03d70dde..92d8a0ea1b 100644
--- a/dlls/user32/misc.c
+++ b/dlls/user32/misc.c
@@ -29,9 +29,13 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
+#include "winreg.h"
#include "winnls.h"
#include "winternl.h"
#include "controls.h"
+#include "initguid.h"
+#include "devguid.h"
+#include "setupapi.h"
#include "user_private.h"
#include "wine/unicode.h"
@@ -39,6 +43,42 @@
WINE_DEFAULT_DEBUG_CHANNEL(win);
+/* Wine specific monitor properties */
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
+
+static const WCHAR monitor_fmtW[] =
+ {'\\','M','o','n','i','t','o','r','%','d',0};
+static const WCHAR adapter_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
+static const WCHAR displayW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
+static const WCHAR video_keyW[] =
+ {'H','A','R','D','W','A','R','E','\\',
+ 'D','E','V','I','C','E','M','A','P','\\',
+ 'V','I','D','E','O','\\',0};
+static const WCHAR video_value_fmtW[] =
+ {'\\','D','e','v','i','c','e','\\',
+ 'V','i','d','e','o','%','d',0};
+static const WCHAR nt_machine_prefixW[] =
+ {'\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\'};
+static const WCHAR monitor_interface_prefixW[] = {'\\','\\','\?','\\',0};
+static const WCHAR guid_devinterface_monitorW[] =
+ {'#','{','e','6','f','0','7','b','5','f','-','e','e','9','7','-',
+ '4','a','9','0','-','b','0','7','6','-','3','3','f','5','7','b','f','4','e','a','a','7','}',0};
+static const WCHAR backslashW[] = {'\\',0};
+static const WCHAR nt_classW[] =
+ {'\\','R','e','g','i','s','t','r','y','\\',
+ 'M','a','c','h','i','n','e','\\',
+ 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'C','l','a','s','s','\\',0};
+static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
+static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
+static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
+static const WCHAR mointor_id_value_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
+
#define IMM_INIT_MAGIC 0x19650412
static HWND (WINAPI *imm_get_ui_window)(HKL);
BOOL (WINAPI *imm_register_window)(HWND) = NULL;
@@ -243,11 +283,6 @@ DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd)
return 1;
}
-static const WCHAR primary_device_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
-static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ',
- 'S','y','s','t','e','m',0};
-static const WCHAR primary_device_deviceid[] = {'P','C','I','\\','V','E','N','_','0','0','0','0','&',
- 'D','E','V','_','0','0','0','0',0};
/***********************************************************************
* EnumDisplayDevicesA (USER32.@)
@@ -285,28 +320,170 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpD
/***********************************************************************
* EnumDisplayDevicesW (USER32.@)
*/
-BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
- DWORD dwFlags )
+BOOL WINAPI EnumDisplayDevicesW(LPCWSTR name, DWORD index, LPDISPLAY_DEVICEW display_device, DWORD flags)
{
- FIXME("(%s,%d,%p,0x%08x), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
-
- if (i)
- return FALSE;
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HDEVINFO set;
+ WCHAR key_nameW[MAX_PATH];
+ WCHAR instanceW[MAX_PATH];
+ WCHAR bufferW[1024];
+ WCHAR *next_charW;
+ DWORD size;
+ DWORD type;
+ long adapter_index;
+ BOOL ret = FALSE;
- memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
- memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
-
- lpDisplayDevice->StateFlags =
- DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
- DISPLAY_DEVICE_PRIMARY_DEVICE |
- DISPLAY_DEVICE_VGA_COMPATIBLE;
+ TRACE("%s %d %p 0x%08x\n", debugstr_w(name), index, display_device, flags);
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
- memcpy(lpDisplayDevice->DeviceID, primary_device_deviceid, sizeof(primary_device_deviceid));
- if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
- lpDisplayDevice->DeviceKey[0] = 0;
+ /* Find adapter */
+ if (!name)
+ {
+ sprintfW(key_nameW, video_value_fmtW, index);
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ bufferW, &size))
+ return FALSE;
+
+ /* DeviceKey */
+ if(display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(display_device->DeviceKey))
+ strcpyW(display_device->DeviceKey, bufferW);
+
+ /* DeviceName */
+ sprintfW(display_device->DeviceName, adapter_fmtW, index + 1);
+
+ /* Strip \Registry\Machine\ */
+ strcpyW(key_nameW, bufferW + ARRAY_SIZE(nt_machine_prefixW));
+
+ /* DeviceString */
+ size = sizeof(display_device->DeviceString);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, key_nameW, driver_descW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ display_device->DeviceString, &size))
+ return FALSE;
+
+ /* StateFlags */
+ size = sizeof(display_device->StateFlags);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, state_flagsW, RRF_RT_REG_DWORD | RRF_ZEROONFAILURE, NULL,
+ &display_device->StateFlags, &size))
+ return FALSE;
+
+ /* DeviceID */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(display_device->DeviceID))
+ {
+ if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
+ display_device->DeviceID[0] = 0;
+ else
+ {
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, gpu_idW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
+ bufferW, &size))
+ return FALSE;
+ set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
+ if (!SetupDiOpenDeviceInfoW(set, bufferW, NULL, 0, &device_data)
+ || !SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ {
+ SetupDiDestroyDeviceInfoList(set);
+ return FALSE;
+ }
+ strcpyW(display_device->DeviceID, bufferW);
+ }
+ }
- return TRUE;
+ return TRUE;
+ }
+ /* Find monitor */
+ else
+ {
+ /* Check adapter name */
+ if (strncmpiW(name, displayW, ARRAY_SIZE(displayW)))
+ return FALSE;
+
+ adapter_index = strtolW(name + ARRAY_SIZE(displayW), NULL, 10);
+ sprintfW(key_nameW, video_value_fmtW, adapter_index - 1);
+
+ size = sizeof(bufferW);
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL, bufferW,
+ &size))
+ return FALSE;
+
+ /* DeviceName */
+ sprintfW(display_device->DeviceName, adapter_fmtW, adapter_index);
+ sprintfW(display_device->DeviceName + strlenW(display_device->DeviceName), monitor_fmtW, index);
+
+ /* Get monitor instance */
+ /* Strip \Registry\Machine\ first */
+ strcpyW(key_nameW, bufferW + ARRAY_SIZE(nt_machine_prefixW));
+ sprintfW(bufferW, mointor_id_value_fmtW, index);
+
+ size = sizeof(instanceW);
+ if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, bufferW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE,
+ NULL, instanceW, &size))
+ return FALSE;
+
+ set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL);
+ if (!SetupDiOpenDeviceInfoW(set, instanceW, NULL, 0, &device_data))
+ goto fail;
+
+ /* StateFlags */
+ if (!SetupDiGetDevicePropertyW(set, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
+ (BYTE *)&display_device->StateFlags, sizeof(display_device->StateFlags), NULL, 0))
+ goto fail;
+
+ /* DeviceString */
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DEVICEDESC, NULL,
+ (BYTE *)display_device->DeviceString,
+ sizeof(display_device->DeviceString), NULL))
+ goto fail;
+
+ /* DeviceKey */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(display_device->DeviceKey))
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcpyW(display_device->DeviceKey, nt_classW);
+ strcatW(display_device->DeviceKey, bufferW);
+ }
+
+ /* DeviceID */
+ if (display_device->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(display_device->DeviceID))
+ {
+ if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
+ {
+ strcpyW(display_device->DeviceID, monitor_interface_prefixW);
+ strcatW(display_device->DeviceID, instanceW);
+ strcatW(display_device->DeviceID, guid_devinterface_monitorW);
+ /* Replace '\\' with '#' after prefix */
+ for (next_charW = display_device->DeviceID + strlenW(monitor_interface_prefixW); *next_charW;
+ next_charW++)
+ {
+ if (*next_charW == '\\')
+ *next_charW = '#';
+ }
+ }
+ else
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcpyW(display_device->DeviceID, bufferW);
+ strcatW(display_device->DeviceID, backslashW);
+
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
+ sizeof(bufferW), NULL))
+ goto fail;
+
+ strcatW(display_device->DeviceID, bufferW);
+ }
+ }
+
+ ret = TRUE;
+ fail:
+ SetupDiDestroyDeviceInfoList(set);
+ return ret;
+ }
}
/***********************************************************************
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index c5e6745322..4ec2e7eb0d 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -107,7 +107,7 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
{
sprintf(video_name, "\\Device\\Video%d", index);
ls = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkey);
- todo_wine ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
+ ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
if (!ls)
{
memset(video_value, 0, sizeof(video_value));
@@ -146,13 +146,13 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
* by changing the data and rerun EnumDisplayDevices. But it's difficult to find corresponding PCI device on
* userland. So here we check the expected format instead. */
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
- todo_wine ok(strlen(device->DeviceID) == 0 || /* vista+ */
+ ok(strlen(device->DeviceID) == 0 || /* vista+ */
sscanf(device->DeviceID, "PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
&vendor_id, &device_id, &subsys_id, &revision_id) == 4, /* XP/2003 ignores EDD_GET_DEVICE_INTERFACE_NAME */
"#%d: got %s\n", index, device->DeviceID);
else
{
- todo_wine ok(broken(strlen(device->DeviceID) == 0) || /* XP on Testbot returns an empty string, whereas real machine doesn't */
+ ok(broken(strlen(device->DeviceID) == 0) || /* XP on Testbot returns an empty string, whereas real machine doesn't */
sscanf(device->DeviceID, "PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X", &vendor_id, &device_id, &subsys_id,
&revision_id) == 4, "#%d: wrong DeviceID %s\n", index, device->DeviceID);
}
@@ -173,14 +173,14 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
/* DeviceName */
lstrcpyA(monitor_name, adapter_name);
sprintf(monitor_name + strlen(monitor_name), "\\Monitor%d", monitor_index);
- todo_wine ok(!strcmp(monitor_name, device->DeviceName), "#%d: expect %s, got %s\n", monitor_index, monitor_name, device->DeviceName);
+ ok(!strcmp(monitor_name, device->DeviceName), "#%d: expect %s, got %s\n", monitor_index, monitor_name, device->DeviceName);
/* DeviceString */
ok(strlen(device->DeviceString) > 0, "#%d: expect DeviceString not empty\n", monitor_index);
/* StateFlags */
if (adapter_index == 0 && monitor_index == 0)
- todo_wine ok(device->StateFlags & DISPLAY_DEVICE_ATTACHED, "#%d expect to have a primary monitor attached\n", monitor_index);
+ ok(device->StateFlags & DISPLAY_DEVICE_ATTACHED, "#%d expect to have a primary monitor attached\n", monitor_index);
else
ok(device->StateFlags <= (DISPLAY_DEVICE_ATTACHED | DISPLAY_DEVICE_ACTIVE), "#%d wrong state %#x\n", monitor_index,
device->StateFlags);
@@ -191,7 +191,7 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
{ /* HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\Default_Monitor\4&2abfaa30&0&UID0 GUID_DEVINTERFACE_MONITOR
* ^ ^ ^
* Expect format \\?\DISPLAY#Default_Monitor#4&2abfaa30&0&UID0#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} */
- todo_wine ok(strlen(device->DeviceID) == 0 || /* vista ~ win7 */
+ ok(strlen(device->DeviceID) == 0 || /* vista ~ win7 */
sscanf(device->DeviceID, "\\\\?\\DISPLAY#Default_Monitor#%[^#]#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}", buffer) == 1 || /* win8+ */
(!lstrcmpiA(buffer, device_id_prefix) &&
sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1), /* XP/2003 ignores EDD_GET_DEVICE_INTERFACE_NAME */
@@ -201,16 +201,16 @@ static void test_enumdisplaydevices_monitor(int adapter_index, int monitor_index
{
/* Expect HarewareID value data + Driver value data in HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\Default_Monitor\{Instance} */
/* But we don't know which monitor instance this belongs to, so check format instead */
- todo_wine ok(!lstrcmpiA(buffer, device_id_prefix), "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
- todo_wine ok(sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1,
- "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
+ ok(!lstrcmpiA(buffer, device_id_prefix), "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
+ ok(sscanf(device->DeviceID + sizeof(device_id_prefix) - 1, "%04d", &number) == 1,
+ "#%d wrong DeviceID : %s\n", monitor_index, device->DeviceID);
}
/* DeviceKey */
lstrcpynA(buffer, device->DeviceKey, sizeof(device_key_prefix));
- todo_wine ok(!lstrcmpiA(buffer, device_key_prefix), "#%d: wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
- todo_wine ok(sscanf(device->DeviceKey + sizeof(device_key_prefix) - 1, "%04d", &number) == 1,
- "#%d wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
+ ok(!lstrcmpiA(buffer, device_key_prefix), "#%d: wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
+ ok(sscanf(device->DeviceKey + sizeof(device_key_prefix) - 1, "%04d", &number) == 1,
+ "#%d wrong DeviceKey : %s\n", monitor_index, device->DeviceKey);
}
static void test_enumdisplaydevices(void)
@@ -235,7 +235,7 @@ static void test_enumdisplaydevices(void)
/* Doesn't accept \\.\DISPLAY */
dd.cb = sizeof(dd);
ret = pEnumDisplayDevicesA("\\\\.\\DISPLAY", 0, &dd, 0);
- todo_wine ok(!ret, "Expect failure\n");
+ ok(!ret, "Expect failure\n");
/* Enumeration */
for (flag_index = 0; flag_index < ARRAY_SIZE(flags); flag_index++)
--
2.20.1
2
1