Zebediah Figura : setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().
Alexandre Julliard
julliard at winehq.org
Thu Aug 16 13:42:49 CDT 2018
Module: wine
Branch: master
Commit: 1d17352ce275492554bb2fc06a227060017876e5
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1d17352ce275492554bb2fc06a227060017876e5
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Sun Jul 29 20:26:28 2018 -0500
setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().
This family of functions manipulates the "Device Parameters" subkey, not its
parent.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/setupapi/devinst.c | 123 +++++++++++++-----------------------------
dlls/setupapi/tests/devinst.c | 57 ++++++++++++++++++++
2 files changed, 95 insertions(+), 85 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 8b97eb5..44d2cb9 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -76,6 +76,7 @@ static const WCHAR Enum[] = {'S','y','s','t','e','m','\\',
'E','n','u','m',0};
static const WCHAR DeviceDesc[] = {'D','e','v','i','c','e','D','e','s','c',0};
static const WCHAR DeviceInstance[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
+static const WCHAR DeviceParameters[] = {'D','e','v','i','c','e',' ','P','a','r','a','m','e','t','e','r','s',0};
static const WCHAR HardwareId[] = {'H','a','r','d','w','a','r','e','I','D',0};
static const WCHAR CompatibleIDs[] = {'C','o','m','p','a','t','i','b','l','e','I','d','s',0};
static const WCHAR Service[] = {'S','e','r','v','i','c','e',0};
@@ -2559,111 +2560,63 @@ static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface)
/***********************************************************************
* SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
*/
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- DWORD Reserved,
- REGSAM samDesired,
- HINF InfHandle,
- PCWSTR InfSectionName)
+HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo,
+ SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved, REGSAM access,
+ HINF hinf, const WCHAR *section)
{
- struct DeviceInfoSet *set = DeviceInfoSet;
- HKEY key = INVALID_HANDLE_VALUE, interfacesKey;
- LONG l;
+ struct DeviceInfoSet *set = devinfo;
+ struct device_iface *iface;
+ HKEY refstr_key, params_key;
+ WCHAR *path;
+ LONG ret;
- TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
- samDesired, InfHandle, InfSectionName);
+ TRACE("%p %p %d %#x %p %s\n", devinfo, iface_data, reserved, access, hinf,
+ debugstr_w(section));
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
+ if (!devinfo || devinfo == INVALID_HANDLE_VALUE ||
set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
{
SetLastError(ERROR_INVALID_HANDLE);
return INVALID_HANDLE_VALUE;
}
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
- !DeviceInterfaceData->Reserved)
+ if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
+ !iface_data->Reserved)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
- if (InfHandle && !InfSectionName)
+ if (hinf && !section)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
- if (!(l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, DeviceClasses, 0, NULL, 0,
- samDesired, NULL, &interfacesKey, NULL)))
- {
- HKEY parent;
- WCHAR bracedGuidString[39];
- SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid,
- bracedGuidString);
- if (!(l = RegCreateKeyExW(interfacesKey, bracedGuidString, 0, NULL, 0,
- samDesired, NULL, &parent, NULL)))
- {
- struct device_iface *ifaceInfo =
- (struct device_iface *)DeviceInterfaceData->Reserved;
- PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo);
- PWSTR interfKeyName = HeapAlloc(GetProcessHeap(), 0,
- (lstrlenW(ifaceInfo->symlink) + 1) * sizeof(WCHAR));
- HKEY interfKey;
- WCHAR *ptr;
-
- lstrcpyW(interfKeyName, ifaceInfo->symlink);
- if (lstrlenW(ifaceInfo->symlink) > 3)
- {
- interfKeyName[0] = '#';
- interfKeyName[1] = '#';
- interfKeyName[3] = '#';
- }
- ptr = strchrW(interfKeyName, '\\');
- if (ptr)
- *ptr = 0;
- l = RegCreateKeyExW(parent, interfKeyName, 0, NULL, 0,
- samDesired, NULL, &interfKey, NULL);
- if (!l)
- {
- struct device *device = ifaceInfo->device;
+ iface = (struct device_iface *)iface_data->Reserved;
+ if (!(path = get_refstr_key_path(iface)))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return INVALID_HANDLE_VALUE;
+ }
- l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ,
- (BYTE *)device->instanceId,
- (lstrlenW(device->instanceId) + 1) * sizeof(WCHAR));
- if (!l)
- {
- if (instancePath)
- {
- LONG l;
+ ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL,
+ &refstr_key, NULL);
+ heap_free(path);
+ if (ret)
+ {
+ SetLastError(ret);
+ return INVALID_HANDLE_VALUE;
+ }
- l = RegCreateKeyExW(interfKey, instancePath, 0, NULL, 0,
- samDesired, NULL, &key, NULL);
- if (l)
- {
- SetLastError(l);
- key = INVALID_HANDLE_VALUE;
- }
- else if (InfHandle)
- FIXME("INF section installation unsupported\n");
- }
- }
- else
- SetLastError(l);
- RegCloseKey(interfKey);
- }
- else
- SetLastError(l);
- HeapFree(GetProcessHeap(), 0, interfKeyName);
- HeapFree(GetProcessHeap(), 0, instancePath);
- RegCloseKey(parent);
- }
- else
- SetLastError(l);
- RegCloseKey(interfacesKey);
+ ret = RegCreateKeyExW(refstr_key, DeviceParameters, 0, NULL, 0, access,
+ NULL, ¶ms_key, NULL);
+ RegCloseKey(refstr_key);
+ if (ret)
+ {
+ SetLastError(ret);
+ return INVALID_HANDLE_VALUE;
}
- else
- SetLastError(l);
- return key;
+
+ return params_key;
}
/***********************************************************************
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 2bb8027..95d0dc4 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -1376,6 +1376,62 @@ static void test_devnode(void)
SetupDiDestroyDeviceInfoList(set);
}
+static void test_device_interface_key(void)
+{
+ const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\"
+ "{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"
+ "##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
+ SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
+ SP_DEVINFO_DATA devinfo = { sizeof(devinfo) };
+ HKEY parent, key, dikey;
+ char buffer[5];
+ HDEVINFO set;
+ LONG sz, ret;
+
+ set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES);
+ ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
+
+ ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo);
+ ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
+
+ ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface);
+ ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError());
+
+ ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent);
+ ok(!ret, "failed to open device parent key: %u\n", ret);
+
+ ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+ ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
+
+ dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL);
+ ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
+
+ ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+ ok(!ret, "key should exist: %u\n", ret);
+
+ ret = RegSetValueA(key, NULL, REG_SZ, "test", 5);
+ sz = sizeof(buffer);
+ ret = RegQueryValueA(dikey, NULL, buffer, &sz);
+ ok(!ret, "RegQueryValue failed: %u\n", ret);
+ ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer);
+
+ RegCloseKey(dikey);
+ RegCloseKey(key);
+
+ ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0);
+todo_wine
+ ok(ret, "got error %u\n", GetLastError());
+
+ ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+todo_wine
+ ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
+
+ RegCloseKey(parent);
+ SetupDiRemoveDeviceInterface(set, &iface);
+ SetupDiRemoveDevice(set, &devinfo);
+ SetupDiDestroyDeviceInfoList(set);
+}
+
START_TEST(devinst)
{
HKEY hkey;
@@ -1414,4 +1470,5 @@ START_TEST(devinst)
testDeviceRegistryPropertyW();
testSetupDiGetINFClassA();
test_devnode();
+ test_device_interface_key();
}
More information about the wine-cvs
mailing list