[PATCH 1/4] setupapi: Store the path to the driver key in the device key.

Zebediah Figura z.figura12 at gmail.com
Tue Jan 22 20:38:33 CST 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/setupapi/devinst.c       | 110 ++++++++++++++++++----------------
 dlls/setupapi/tests/devinst.c |  25 +++++++-
 2 files changed, 82 insertions(+), 53 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 55746562c8..c3ba9010f8 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -492,30 +492,68 @@ static HKEY SETUPDI_CreateDevKey(struct device *device)
     return key;
 }
 
-static HKEY SETUPDI_CreateDrvKey(struct device *device)
+static HKEY open_driver_key(struct device *device, REGSAM access)
 {
-    static const WCHAR slash[] = { '\\',0 };
-    WCHAR classKeyPath[MAX_PATH];
-    HKEY classKey, key = INVALID_HANDLE_VALUE;
+    HKEY class_key, key;
+    WCHAR path[50];
+    DWORD size = sizeof(path);
     LONG l;
 
-    lstrcpyW(classKeyPath, ControlClass);
-    lstrcatW(classKeyPath, slash);
-    SETUPDI_GuidToString(&device->set->ClassGuid,
-            classKeyPath + lstrlenW(classKeyPath));
-    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, classKeyPath, 0, NULL, 0,
-            KEY_ALL_ACCESS, NULL, &classKey, NULL);
-    if (!l)
+    if ((l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ControlClass, 0, NULL, 0,
+            KEY_CREATE_SUB_KEY, NULL, &class_key, NULL)))
     {
-        static const WCHAR fmt[] = { '%','0','4','u',0 };
-        WCHAR devId[10];
-
-        sprintfW(devId, fmt, device->devnode);
-        RegCreateKeyExW(classKey, devId, 0, NULL, 0, KEY_READ | KEY_WRITE,
-                NULL, &key, NULL);
-        RegCloseKey(classKey);
+        ERR("Failed to open driver class root key, error %u.\n", l);
+        SetLastError(l);
+        return INVALID_HANDLE_VALUE;
     }
-    return key;
+
+    if (!(l = RegGetValueW(device->key, NULL, Driver, RRF_RT_REG_SZ, NULL, path, &size)))
+    {
+        if (!(l = RegOpenKeyExW(class_key, path, 0, access, &key)))
+        {
+            RegCloseKey(class_key);
+            return key;
+        }
+        ERR("Failed to open driver key, error %u.\n", l);
+    }
+
+    RegCloseKey(class_key);
+    SetLastError(ERROR_KEY_DOES_NOT_EXIST);
+    return INVALID_HANDLE_VALUE;
+}
+
+static HKEY create_driver_key(struct device *device)
+{
+    static const WCHAR formatW[] = {'%','0','4','u',0};
+    static const WCHAR slash[] = { '\\',0 };
+    HKEY class_key, key;
+    WCHAR path[50];
+    LONG l;
+
+    if ((key = open_driver_key(device, KEY_READ | KEY_WRITE)) != INVALID_HANDLE_VALUE)
+        return key;
+
+    if ((l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ControlClass, 0, NULL, 0,
+            KEY_CREATE_SUB_KEY, NULL, &class_key, NULL)))
+    {
+        ERR("Failed to open driver class root key, error %u.\n", l);
+        SetLastError(l);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    SETUPDI_GuidToString(&device->class, path);
+    strcatW(path, slash);
+    sprintfW(path + strlenW(path), formatW, device->devnode);
+    if (!(l = RegCreateKeyExW(class_key, path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL)))
+    {
+        RegSetValueExW(device->key, Driver, 0, REG_SZ, (BYTE *)path, strlenW(path) * sizeof(WCHAR));
+        RegCloseKey(class_key);
+        return key;
+    }
+    ERR("Failed to create driver key, error %u.\n", l);
+    RegCloseKey(class_key);
+    SetLastError(l);
+    return INVALID_HANDLE_VALUE;
 }
 
 struct PropertyMapEntry
@@ -1367,7 +1405,7 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_da
             key = SETUPDI_CreateDevKey(device);
             break;
         case DIREG_DRV:
-            key = SETUPDI_CreateDrvKey(device);
+            key = create_driver_key(device);
             break;
         default:
             WARN("unknown KeyType %d\n", KeyType);
@@ -3358,36 +3396,6 @@ static HKEY SETUPDI_OpenDevKey(struct device *device, REGSAM samDesired)
     return key;
 }
 
-static HKEY SETUPDI_OpenDrvKey(struct device *device, REGSAM samDesired)
-{
-    static const WCHAR slash[] = { '\\',0 };
-    WCHAR classKeyPath[MAX_PATH];
-    HKEY classKey, key = INVALID_HANDLE_VALUE;
-    LONG l;
-
-    lstrcpyW(classKeyPath, ControlClass);
-    lstrcatW(classKeyPath, slash);
-    SETUPDI_GuidToString(&device->set->ClassGuid,
-            classKeyPath + lstrlenW(classKeyPath));
-    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, classKeyPath, 0, NULL, 0,
-            KEY_ALL_ACCESS, NULL, &classKey, NULL);
-    if (!l)
-    {
-        static const WCHAR fmt[] = { '%','0','4','u',0 };
-        WCHAR devId[10];
-
-        sprintfW(devId, fmt, device->devnode);
-        l = RegOpenKeyExW(classKey, devId, 0, samDesired, &key);
-        RegCloseKey(classKey);
-        if (l)
-        {
-            SetLastError(ERROR_KEY_DOES_NOT_EXIST);
-            return INVALID_HANDLE_VALUE;
-        }
-    }
-    return key;
-}
-
 /***********************************************************************
  *		SetupDiOpenDevRegKey (SETUPAPI.@)
  */
@@ -3427,7 +3435,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data,
             key = SETUPDI_OpenDevKey(device, samDesired);
             break;
         case DIREG_DRV:
-            key = SETUPDI_OpenDrvKey(device, samDesired);
+            key = open_driver_key(device, samDesired);
             break;
         default:
             WARN("unknown KeyType %d\n", KeyType);
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 4abc188ea4..6aa5a1e277 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -776,9 +776,11 @@ static void test_device_key(void)
      'E','n','u','m','\\','R','o','o','t','\\',
      'L','E','G','A','C','Y','_','B','O','G','U','S',0};
     SP_DEVINFO_DATA device = {sizeof(device)};
+    char driver_path[50], data[4];
+    HKEY class_key, key;
+    DWORD size;
     BOOL ret;
     HDEVINFO set;
-    HKEY key = NULL;
     LONG res;
 
     SetLastError(0xdeadbeef);
@@ -836,9 +838,13 @@ static void test_device_key(void)
     ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n");
     ok(GetLastError() == ERROR_KEY_DOES_NOT_EXIST, "Got unexpected error %#x.\n", GetLastError());
 
+    ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_DRIVER, NULL,
+            (BYTE *)driver_path, sizeof(driver_path), NULL);
+    ok(!ret, "Expected failure.\n");
+    ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
+
     SetLastError(0xdeadbeef);
     res = RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key);
-todo_wine
     ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
     RegCloseKey(key);
 
@@ -852,6 +858,17 @@ todo_wine
         ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key), "Key should exist.\n");
         RegCloseKey(key);
 
+        ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_DRIVER, NULL,
+                (BYTE *)driver_path, sizeof(driver_path), NULL);
+        ok(ret, "Failed to get driver property, error %#x.\n", GetLastError());
+        res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Class", &class_key);
+        ok(!res, "Failed to open class key, error %u.\n", res);
+        res = RegOpenKeyA(class_key, driver_path, &key);
+        ok(!res, "Failed to open driver key, error %u.\n", res);
+        RegSetValueExA(key, "foo", 0, REG_SZ, (BYTE *)"bar", sizeof("bar"));
+        RegCloseKey(key);
+        RegCloseKey(class_key);
+
         SetLastError(0xdeadbeef);
         key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0);
 todo_wine {
@@ -862,6 +879,10 @@ todo_wine {
 
         key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
         ok(key != INVALID_HANDLE_VALUE, "Failed to open device key, error %#x.\n", GetLastError());
+        size = sizeof(data);
+        res = RegQueryValueExA(key, "foo", NULL, NULL, (BYTE *)data, &size);
+        ok(!res, "Failed to get value, error %u.\n", res);
+        ok(!strcmp(data, "bar"), "Got wrong data %s.\n", data);
         RegCloseKey(key);
     }
 
-- 
2.17.1




More information about the wine-devel mailing list