Zebediah Figura : setupapi: Add helper functions to get the path of the device instance keys.
Alexandre Julliard
julliard at winehq.org
Thu Aug 16 13:42:49 CDT 2018
Module: wine
Branch: master
Commit: ad9e1883ef558886607037592f48e6c5d216d4e1
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ad9e1883ef558886607037592f48e6c5d216d4e1
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Sun Jul 29 20:26:26 2018 -0500
setupapi: Add helper functions to get the path of the device instance keys.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/setupapi/devinst.c | 106 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 96 insertions(+), 10 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index a845290..2e4ff3a 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -201,8 +201,75 @@ static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
}
+static WCHAR *get_iface_key_path(SP_DEVICE_INTERFACE_DATA *iface)
+{
+ const WCHAR slashW[] = {'\\',0};
+ struct InterfaceInfo *info = (struct InterfaceInfo *)iface->Reserved;
+ WCHAR *path, *ptr;
+ size_t len = strlenW(DeviceClasses) + 1 + 38 + 1 + strlenW(info->symbolicLink);
+
+ if (!(path = heap_alloc((len + 1) * sizeof(WCHAR))))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ strcpyW(path, DeviceClasses);
+ strcatW(path, slashW);
+ SETUPDI_GuidToString(&iface->InterfaceClassGuid, path + strlenW(path));
+ strcatW(path, slashW);
+ ptr = path + strlenW(path);
+ strcatW(path, info->symbolicLink);
+ if (strlenW(info->symbolicLink) > 3)
+ ptr[0] = ptr[1] = ptr[3] = '#';
+
+ ptr = strchrW(ptr, '\\');
+ if (ptr) *ptr = 0;
+
+ return path;
+}
+
+static WCHAR *get_refstr_key_path(SP_DEVICE_INTERFACE_DATA *iface)
+{
+ const WCHAR hashW[] = {'#',0};
+ const WCHAR slashW[] = {'\\',0};
+ struct InterfaceInfo *info = (struct InterfaceInfo *)iface->Reserved;
+ WCHAR *path, *ptr;
+ size_t len = strlenW(DeviceClasses) + 1 + 38 + 1 + strlenW(info->symbolicLink) + 1 + 1;
+
+ if (info->referenceString)
+ len += strlenW(info->referenceString);
+
+ if (!(path = heap_alloc((len + 1) * sizeof(WCHAR))))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ strcpyW(path, DeviceClasses);
+ strcatW(path, slashW);
+ SETUPDI_GuidToString(&iface->InterfaceClassGuid, path + strlenW(path));
+ strcatW(path, slashW);
+ ptr = path + strlenW(path);
+ strcatW(path, info->symbolicLink);
+ if (strlenW(info->symbolicLink) > 3)
+ ptr[0] = ptr[1] = ptr[3] = '#';
+
+ ptr = strchrW(ptr, '\\');
+ if (ptr) *ptr = 0;
+
+ strcatW(path, slashW);
+ strcatW(path, hashW);
+
+ if (info->referenceString)
+ strcatW(path, info->referenceString);
+
+ return path;
+}
+
static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances)
{
+ WCHAR *path;
DWORD i;
for (i = 0; i < instances->cInstances; i++)
@@ -212,8 +279,11 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances)
if (ifaceInfo->device && ifaceInfo->device->phantom)
{
- SetupDiDeleteDeviceInterfaceRegKey(ifaceInfo->device->set,
- &instances->instances[i], 0);
+ if ((path = get_refstr_key_path(&instances->instances[i])))
+ {
+ RegDeleteKeyW(HKEY_LOCAL_MACHINE, path);
+ heap_free(path);
+ }
}
HeapFree(GetProcessHeap(), 0, ifaceInfo->referenceString);
HeapFree(GetProcessHeap(), 0, ifaceInfo->symbolicLink);
@@ -399,6 +469,7 @@ static BOOL SETUPDI_AddInterfaceInstance(struct device *devInfo,
ifaceInfo->referenceString = NULL;
if (ret)
{
+ WCHAR *path;
HKEY key;
iface->cInstances++;
@@ -409,15 +480,30 @@ static BOOL SETUPDI_AddInterfaceInstance(struct device *devInfo,
instance->Reserved = (ULONG_PTR)ifaceInfo;
if (newInterface)
iface->guid = *InterfaceClassGuid;
- key = SetupDiCreateDeviceInterfaceRegKeyW(devInfo->set,
- instance, 0, KEY_WRITE, NULL, NULL);
- if (key != INVALID_HANDLE_VALUE)
+
+ if ((path = get_iface_key_path(instance)))
{
- RegSetValueExW(key, SymbolicLink, 0, REG_SZ,
- (BYTE *)ifaceInfo->symbolicLink,
- lstrlenW(ifaceInfo->symbolicLink) *
- sizeof(WCHAR));
- RegCloseKey(key);
+ if (!RegCreateKeyW(HKEY_LOCAL_MACHINE, path, &key))
+ {
+ RegSetValueExW(key, DeviceInstance, 0, REG_SZ,
+ (BYTE *)devInfo->instanceId,
+ lstrlenW(devInfo->instanceId) * sizeof(WCHAR));
+ RegCloseKey(key);
+ }
+ heap_free(path);
+ }
+
+ if ((path = get_refstr_key_path(instance)))
+ {
+ if (!RegCreateKeyW(HKEY_LOCAL_MACHINE, path, &key))
+ {
+ RegSetValueExW(key, SymbolicLink, 0, REG_SZ,
+ (BYTE *)ifaceInfo->symbolicLink,
+ lstrlenW(ifaceInfo->symbolicLink) *
+ sizeof(WCHAR));
+ RegCloseKey(key);
+ }
+ heap_free(path);
}
if (ifaceData)
*ifaceData = instance;
More information about the wine-cvs
mailing list