[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