[PATCH 3/7] user32: Use registry to query primary adapter key.

Zhiyi Zhang zzhang at codeweavers.com
Wed Mar 6 01:11:24 CST 2019


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/user32/driver.c | 63 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 47 insertions(+), 16 deletions(-)

diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 5b2929245c..548fe362af 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -41,37 +41,68 @@ static char driver_load_error[80];
 
 static BOOL CDECL nodrv_CreateWindow( HWND hwnd );
 
+/* Get the primary adapter key in the form of System\CurrentControlSet\Control\Video\{Primary adapter GUID}\0000 */
+static BOOL get_primary_adapter_key( WCHAR *key, int len )
+{
+    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 value_prefixW[] = {'\\','R','e','g','i','s','t','r','y','\\',
+                                          'M','a','c','h','i','n','e','\\',0};
+    WCHAR buffer[MAX_PATH];
+    WCHAR *substring;
+    DWORD size;
+    int length;
+    BOOL ret = FALSE;
+
+    /* Vaule data of \Device\Video0 in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
+    size = sizeof(buffer);
+    if (RegGetValueW( HKEY_LOCAL_MACHINE, video_keyW, device_video0W, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL, buffer,
+                      &size ))
+        goto fail;
+
+    /* Need to strip "\Registry\Machine\" from the value data, which starts with "\Registry\Machine\System\..." */
+    length = strlenW( value_prefixW );
+    if (strncmpiW( buffer, value_prefixW, length ))
+        goto fail;
+
+    substring = buffer + length;
+    length = strlenW( substring );
+    if (len < length + 1)
+        goto fail;
+
+    strcpyW( key, substring );
+
+    ret = TRUE;
+    TRACE( "primary adapter key %s\n", wine_dbgstr_w(key) );
+fail:
+    if (!ret)
+        ERR( "Failed to get primary adapter registry key\n" );
+    return ret;
+}
+
 static HMODULE load_desktop_driver( HWND hwnd )
 {
-    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 key_pathW[] = {
-        '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};
-    static const WCHAR displayW[] = {'}','\\','0','0','0','0',0};
     static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
     HMODULE ret = 0;
     HKEY hkey;
     DWORD size;
     WCHAR path[MAX_PATH];
-    WCHAR key[ARRAY_SIZE(key_pathW) + ARRAY_SIZE(displayW) + 40];
-    UINT guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW ));
+    WCHAR key[MAX_PATH];
+    BOOL result;
 
+    result = get_primary_adapter_key( key, ARRAY_SIZE(key) );
     USER_CheckNotLock();
 
     strcpy( driver_load_error, "The explorer process failed to start." );  /* default error */
 
-    if (!guid_atom)
+    if (!result)
     {
         SendMessageW( hwnd, WM_NULL, 0, 0 );  /* wait for the desktop process to be ready */
-        guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW ));
+        get_primary_adapter_key( key, ARRAY_SIZE(key) );
     }
-    memcpy( key, key_pathW, sizeof(key_pathW) );
-    if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0;
-    strcatW( key, displayW );
     if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
     size = sizeof(path);
     if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size ))
-- 
2.20.1





More information about the wine-devel mailing list