Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 4a852da..ea69dea 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -3092,7 +3092,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyA( struct DeviceInfoSet *set = DeviceInfoSet; struct DeviceInfo *devInfo;
- TRACE("%04x %p %d %p %p %d %p\n", (DWORD)DeviceInfoSet, DeviceInfoData, + TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize);
@@ -3155,7 +3155,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW( struct DeviceInfoSet *set = DeviceInfoSet; struct DeviceInfo *devInfo;
- TRACE("%04x %p %d %p %p %d %p\n", (DWORD)DeviceInfoSet, DeviceInfoData, + TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize);
The size of DEVINST is DWORD, so using the pointer directly won't work on 64-bit.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 108 +++++++++++++++++++++++++-------------- dlls/setupapi/setupapi_private.h | 5 ++ dlls/setupapi/tests/devinst.c | 22 ++++++++ 3 files changed, 96 insertions(+), 39 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index ea69dea..8c63298 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -33,6 +33,7 @@ #include "winnls.h" #include "setupapi.h" #include "wine/debug.h" +#include "wine/heap.h" #include "wine/list.h" #include "wine/unicode.h" #include "cfgmgr32.h" @@ -140,6 +141,52 @@ struct DeviceInfo struct list interfaces; };
+static struct DeviceInfo **devnode_table; +static unsigned int devnode_table_size; + +static DEVINST alloc_devnode(struct DeviceInfo *device) +{ + unsigned int i; + + for (i = 0; i < devnode_table_size; ++i) + { + if (!devnode_table[i]) + break; + } + + if (i == devnode_table_size) + { + if (devnode_table) + { + devnode_table_size *= 2; + devnode_table = heap_realloc_zero(devnode_table, + devnode_table_size * sizeof(*devnode_table)); + } + else + { + devnode_table_size = 256; + devnode_table = heap_alloc_zero(devnode_table_size * sizeof(*devnode_table)); + } + } + + devnode_table[i] = device; + return i; +} + +static void free_devnode(DEVINST devnode) +{ + devnode_table[devnode] = NULL; +} + +static struct DeviceInfo *get_devnode_device(DEVINST devnode) +{ + if (devnode < devnode_table_size) + return devnode_table[devnode]; + + WARN("device node %u not found\n", devnode); + return NULL; +} + static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr) { static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-', @@ -460,15 +507,12 @@ static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo) static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set, DWORD devId, LPCWSTR instanceId, BOOL phantom) { - struct DeviceInfo *devInfo = NULL; - HANDLE devInst = GlobalAlloc(GMEM_FIXED, sizeof(struct DeviceInfo)); - if (devInst) - devInfo = GlobalLock(devInst); + struct DeviceInfo *devInfo = heap_alloc(sizeof(*devInfo));
if (devInfo) { devInfo->set = set; - devInfo->devId = (DWORD)devInst; + devInfo->devId = alloc_devnode(devInfo);
devInfo->instanceId = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(instanceId) + 1) * sizeof(WCHAR)); @@ -486,12 +530,10 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set, (LPBYTE)&phantom, sizeof(phantom)); } list_init(&devInfo->interfaces); - GlobalUnlock(devInst); } else { - GlobalUnlock(devInst); - GlobalFree(devInst); + heap_free(devInfo); devInfo = NULL; } } @@ -525,7 +567,8 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo) SETUPDI_FreeInterfaceInstances(iface); HeapFree(GetProcessHeap(), 0, iface); } - GlobalFree((HANDLE)devInfo->devId); + free_devnode(devInfo->devId); + heap_free(devInfo); }
/* Adds a device with GUID guid and identifier devInst to set. Allocates a @@ -3979,63 +4022,50 @@ BOOL WINAPI SetupDiDeleteDevRegKey( /*********************************************************************** * CM_Get_Device_IDA (SETUPAPI.@) */ -CONFIGRET WINAPI CM_Get_Device_IDA( DEVINST dnDevInst, PSTR Buffer, - ULONG BufferLen, ULONG ulFlags) +CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULONG flags) { - struct DeviceInfo *devInfo = GlobalLock((HANDLE)dnDevInst); + struct DeviceInfo *device = get_devnode_device(devnode);
- TRACE("%x->%p, %p, %u %u\n", dnDevInst, devInfo, Buffer, BufferLen, ulFlags); + TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
- if (!devInfo) + if (!device) return CR_NO_SUCH_DEVINST;
- WideCharToMultiByte(CP_ACP, 0, devInfo->instanceId, -1, Buffer, BufferLen, 0, 0); - TRACE("Returning %s\n", debugstr_a(Buffer)); + WideCharToMultiByte(CP_ACP, 0, device->instanceId, -1, buffer, len, 0, 0); + TRACE("Returning %s\n", debugstr_a(buffer)); return CR_SUCCESS; }
/*********************************************************************** * CM_Get_Device_IDW (SETUPAPI.@) */ -CONFIGRET WINAPI CM_Get_Device_IDW( DEVINST dnDevInst, LPWSTR Buffer, - ULONG BufferLen, ULONG ulFlags) +CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, ULONG flags) { - struct DeviceInfo *devInfo = GlobalLock((HANDLE)dnDevInst); + struct DeviceInfo *device = get_devnode_device(devnode);
- TRACE("%x->%p, %p, %u %u\n", dnDevInst, devInfo, Buffer, BufferLen, ulFlags); + TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
- if (!devInfo) - { - WARN("dev instance %d not found!\n", dnDevInst); + if (!device) return CR_NO_SUCH_DEVINST; - }
- lstrcpynW(Buffer, devInfo->instanceId, BufferLen); - TRACE("Returning %s\n", debugstr_w(Buffer)); - GlobalUnlock((HANDLE)dnDevInst); + lstrcpynW(buffer, device->instanceId, len); + TRACE("Returning %s\n", debugstr_w(buffer)); return CR_SUCCESS; }
- - /*********************************************************************** * CM_Get_Device_ID_Size (SETUPAPI.@) */ -CONFIGRET WINAPI CM_Get_Device_ID_Size( PULONG pulLen, DEVINST dnDevInst, - ULONG ulFlags) +CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) { - struct DeviceInfo *ppdevInfo = GlobalLock((HANDLE)dnDevInst); + struct DeviceInfo *device = get_devnode_device(devnode);
- TRACE("%x->%p, %p, %u\n", dnDevInst, ppdevInfo, pulLen, ulFlags); + TRACE("%p, %u, %#x\n", len, devnode, flags);
- if (!ppdevInfo) - { - WARN("dev instance %d not found!\n", dnDevInst); + if (!device) return CR_NO_SUCH_DEVINST; - }
- *pulLen = lstrlenW(ppdevInfo->instanceId); - GlobalUnlock((HANDLE)dnDevInst); + *len = lstrlenW(device->instanceId); return CR_SUCCESS; }
diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h index 5cdedb6..1df96b1 100644 --- a/dlls/setupapi/setupapi_private.h +++ b/dlls/setupapi/setupapi_private.h @@ -45,6 +45,11 @@
extern HINSTANCE SETUPAPI_hInstance DECLSPEC_HIDDEN;
+static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero(void *mem, size_t len) +{ + return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len); +} + static inline WCHAR *strdupW( const WCHAR *str ) { WCHAR *ret = NULL; diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 420c65a..2bb8027 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -28,6 +28,7 @@ #include "winreg.h" #include "guiddef.h" #include "setupapi.h" +#include "cfgmgr32.h"
#include "wine/test.h"
@@ -1355,6 +1356,26 @@ static void testSetupDiGetINFClassA(void) } }
+static void test_devnode(void) +{ + HDEVINFO set; + SP_DEVINFO_DATA device = { sizeof(SP_DEVINFO_DATA) }; + char buffer[50]; + DWORD ret; + + set = SetupDiGetClassDevsA(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError()); + ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0000", &guid, NULL, + NULL, 0, &device); + ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError()); + + ret = CM_Get_Device_IDA(device.DevInst, buffer, sizeof(buffer), 0); + ok(!ret, "got %#x\n", ret); + ok(!strcmp(buffer, "ROOT\LEGACY_BOGUS\0000"), "got %s\n", buffer); + + SetupDiDestroyDeviceInfoList(set); +} + START_TEST(devinst) { HKEY hkey; @@ -1392,4 +1413,5 @@ START_TEST(devinst) testDeviceRegistryPropertyA(); testDeviceRegistryPropertyW(); testSetupDiGetINFClassA(); + test_devnode(); }
This essentially follows the model used in MSI. The next patch makes use of this helper.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 111 ++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 56 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 8c63298..1a4d4dd 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -504,6 +504,50 @@ static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo) return key; }
+struct PropertyMapEntry +{ + DWORD regType; + LPCSTR nameA; + LPCWSTR nameW; +}; + +static const struct PropertyMapEntry PropertyMap[] = { + { REG_SZ, "DeviceDesc", DeviceDesc }, + { REG_MULTI_SZ, "HardwareId", HardwareId }, + { REG_MULTI_SZ, "CompatibleIDs", CompatibleIDs }, + { 0, NULL, NULL }, /* SPDRP_UNUSED0 */ + { REG_SZ, "Service", Service }, + { 0, NULL, NULL }, /* SPDRP_UNUSED1 */ + { 0, NULL, NULL }, /* SPDRP_UNUSED2 */ + { REG_SZ, "Class", Class }, + { REG_SZ, "ClassGUID", ClassGUID }, + { REG_SZ, "Driver", Driver }, + { REG_DWORD, "ConfigFlags", ConfigFlags }, + { REG_SZ, "Mfg", Mfg }, + { REG_SZ, "FriendlyName", FriendlyName }, + { REG_SZ, "LocationInformation", LocationInformation }, + { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */ + { REG_DWORD, "Capabilities", Capabilities }, + { REG_DWORD, "UINumber", UINumber }, + { REG_MULTI_SZ, "UpperFilters", UpperFilters }, + { REG_MULTI_SZ, "LowerFilters", LowerFilters }, +}; + +static BOOL SETUPDI_SetDeviceRegistryPropertyW(struct DeviceInfo *device, + DWORD prop, const BYTE *buffer, DWORD size) +{ + if (prop < ARRAY_SIZE(PropertyMap) && PropertyMap[prop].nameW) + { + LONG ret = RegSetValueExW(device->key, PropertyMap[prop].nameW, 0, + PropertyMap[prop].regType, buffer, size); + if (!ret) + return TRUE; + + SetLastError(ret); + } + return FALSE; +} + static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set, DWORD devId, LPCWSTR instanceId, BOOL phantom) { @@ -3090,35 +3134,6 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( return ret; }
-struct PropertyMapEntry -{ - DWORD regType; - LPCSTR nameA; - LPCWSTR nameW; -}; - -static const struct PropertyMapEntry PropertyMap[] = { - { REG_SZ, "DeviceDesc", DeviceDesc }, - { REG_MULTI_SZ, "HardwareId", HardwareId }, - { REG_MULTI_SZ, "CompatibleIDs", CompatibleIDs }, - { 0, NULL, NULL }, /* SPDRP_UNUSED0 */ - { REG_SZ, "Service", Service }, - { 0, NULL, NULL }, /* SPDRP_UNUSED1 */ - { 0, NULL, NULL }, /* SPDRP_UNUSED2 */ - { REG_SZ, "Class", Class }, - { REG_SZ, "ClassGUID", ClassGUID }, - { REG_SZ, "Driver", Driver }, - { REG_DWORD, "ConfigFlags", ConfigFlags }, - { REG_SZ, "Mfg", Mfg }, - { REG_SZ, "FriendlyName", FriendlyName }, - { REG_SZ, "LocationInformation", LocationInformation }, - { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */ - { REG_DWORD, "Capabilities", Capabilities }, - { REG_DWORD, "UINumber", UINumber }, - { REG_MULTI_SZ, "UpperFilters", UpperFilters }, - { REG_MULTI_SZ, "LowerFilters", LowerFilters }, -}; - /*********************************************************************** * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@) */ @@ -3296,21 +3311,15 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyA( /*********************************************************************** * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@) */ -BOOL WINAPI SetupDiSetDeviceRegistryPropertyW( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Property, - const BYTE *PropertyBuffer, - DWORD PropertyBufferSize) +BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO devinfo, + SP_DEVINFO_DATA *device_data, DWORD prop, const BYTE *buffer, DWORD size) { - BOOL ret = FALSE; - struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct DeviceInfoSet *set = devinfo; + struct DeviceInfo *device;
- TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property, - PropertyBuffer, PropertyBufferSize); + TRACE("%p %p %d %p %d\n", devinfo, device_data, prop, buffer, size);
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) + if (!devinfo || devinfo == INVALID_HANDLE_VALUE) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -3320,25 +3329,15 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW( SetLastError(ERROR_INVALID_HANDLE); return FALSE; } - if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) - || !DeviceInfoData->Reserved) + if (!device_data || device_data->cbSize != sizeof(SP_DEVINFO_DATA) + || !device_data->Reserved) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0]) - && PropertyMap[Property].nameW) - { - LONG l = RegSetValueExW(devInfo->key, PropertyMap[Property].nameW, 0, - PropertyMap[Property].regType, PropertyBuffer, - PropertyBufferSize); - if (!l) - ret = TRUE; - else - SetLastError(l); - } - return ret; + + device = (struct DeviceInfo *)device_data->Reserved; + return SETUPDI_SetDeviceRegistryPropertyW(device, prop, buffer, size); }
/***********************************************************************
These are two different representations of the same underlying object; there's no reason to keep them separate.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- MSDN uses the terms "device instance" and "device information" apparently interchangeably; see e.g. https://docs.microsoft.com/en-gb/windows/desktop/api/setupapi/nf-setupapi-se...
dlls/setupapi/devinst.c | 376 ++++++++++++++++++++---------------------------- 1 file changed, 156 insertions(+), 220 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 1a4d4dd..336c548 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -104,10 +104,15 @@ struct DeviceInfoSet struct list devices; };
-struct DeviceInstance +struct device { - struct list entry; - SP_DEVINFO_DATA data; + struct DeviceInfoSet *set; + HKEY key; + BOOL phantom; + WCHAR *instanceId; + struct list interfaces; + SP_DEVINFO_DATA data; + struct list entry; };
/* Pointed to by SP_DEVICE_INTERFACE_DATA's Reserved member */ @@ -130,21 +135,10 @@ struct InterfaceInstances struct list entry; };
-/* Pointed to by SP_DEVINFO_DATA's Reserved member */ -struct DeviceInfo -{ - struct DeviceInfoSet *set; - HKEY key; - BOOL phantom; - DWORD devId; - LPWSTR instanceId; - struct list interfaces; -}; - -static struct DeviceInfo **devnode_table; +static struct device **devnode_table; static unsigned int devnode_table_size;
-static DEVINST alloc_devnode(struct DeviceInfo *device) +static DEVINST alloc_devnode(struct device *device) { unsigned int i;
@@ -178,7 +172,7 @@ static void free_devnode(DEVINST devnode) devnode_table[devnode] = NULL; }
-static struct DeviceInfo *get_devnode_device(DEVINST devnode) +static struct device *get_devnode_device(DEVINST devnode) { if (devnode < devnode_table_size) return devnode_table[devnode]; @@ -210,11 +204,10 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances)
if (ifaceInfo->device && ifaceInfo->device->Reserved) { - struct DeviceInfo *devInfo = - (struct DeviceInfo *)ifaceInfo->device->Reserved; + struct device *device = (struct device *)ifaceInfo->device->Reserved;
- if (devInfo->phantom) - SetupDiDeleteDeviceInterfaceRegKey(devInfo->set, + if (device->phantom) + SetupDiDeleteDeviceInterfaceRegKey(device->set, &instances->instances[i], 0); } HeapFree(GetProcessHeap(), 0, ifaceInfo->referenceString); @@ -229,7 +222,7 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances) * interfaces member where the given interface was found. * Returns FALSE if not found. */ -static BOOL SETUPDI_FindInterface(const struct DeviceInfo *devInfo, +static BOOL SETUPDI_FindInterface(const struct device *device, const GUID *InterfaceClassGuid, struct InterfaceInstances **iface_ret) { BOOL found = FALSE; @@ -237,7 +230,7 @@ static BOOL SETUPDI_FindInterface(const struct DeviceInfo *devInfo,
TRACE("%s\n", debugstr_guid(InterfaceClassGuid));
- LIST_FOR_EACH_ENTRY(iface, &devInfo->interfaces, struct InterfaceInstances, + LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct InterfaceInstances, entry) { if (IsEqualGUID(&iface->guid, InterfaceClassGuid)) @@ -330,7 +323,7 @@ static BOOL SETUPDI_AddInterfaceInstance(PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, LPCWSTR ReferenceString, SP_DEVICE_INTERFACE_DATA **ifaceData) { - struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + struct device *devInfo = (struct device *)DeviceInfoData->Reserved; BOOL newInterface = FALSE, ret; struct InterfaceInstances *iface = NULL;
@@ -382,7 +375,7 @@ static BOOL SETUPDI_AddInterfaceInstance(PSP_DEVINFO_DATA DeviceInfoData, if (ifaceInfo) { ret = TRUE; - ifaceInfo->device = DeviceInfoData; + ifaceInfo->device = &devInfo->data; ifaceInfo->symbolicLink = SETUPDI_CreateSymbolicLinkPath( devInfo->instanceId, InterfaceClassGuid, ReferenceString); @@ -462,7 +455,7 @@ static BOOL SETUPDI_SetInterfaceSymbolicLink(SP_DEVICE_INTERFACE_DATA *iface, return ret; }
-static HKEY SETUPDI_CreateDevKey(struct DeviceInfo *devInfo) +static HKEY SETUPDI_CreateDevKey(struct device *device) { HKEY enumKey, key = INVALID_HANDLE_VALUE; LONG l; @@ -471,14 +464,14 @@ static HKEY SETUPDI_CreateDevKey(struct DeviceInfo *devInfo) NULL, &enumKey, NULL); if (!l) { - RegCreateKeyExW(enumKey, devInfo->instanceId, 0, NULL, 0, + RegCreateKeyExW(enumKey, device->instanceId, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL); RegCloseKey(enumKey); } return key; }
-static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo) +static HKEY SETUPDI_CreateDrvKey(struct device *device) { static const WCHAR slash[] = { '\',0 }; WCHAR classKeyPath[MAX_PATH]; @@ -487,7 +480,7 @@ static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo)
lstrcpyW(classKeyPath, ControlClass); lstrcatW(classKeyPath, slash); - SETUPDI_GuidToString(&devInfo->set->ClassGuid, + SETUPDI_GuidToString(&device->set->ClassGuid, classKeyPath + lstrlenW(classKeyPath)); l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, classKeyPath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classKey, NULL); @@ -496,7 +489,7 @@ static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, devInfo->devId); + sprintfW(devId, fmt, device->data.DevInst); RegCreateKeyExW(classKey, devId, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL); RegCloseKey(classKey); @@ -533,7 +526,7 @@ static const struct PropertyMapEntry PropertyMap[] = { { REG_MULTI_SZ, "LowerFilters", LowerFilters }, };
-static BOOL SETUPDI_SetDeviceRegistryPropertyW(struct DeviceInfo *device, +static BOOL SETUPDI_SetDeviceRegistryPropertyW(struct device *device, DWORD prop, const BYTE *buffer, DWORD size) { if (prop < ARRAY_SIZE(PropertyMap) && PropertyMap[prop].nameW) @@ -548,49 +541,13 @@ static BOOL SETUPDI_SetDeviceRegistryPropertyW(struct DeviceInfo *device, return FALSE; }
-static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set, - DWORD devId, LPCWSTR instanceId, BOOL phantom) -{ - struct DeviceInfo *devInfo = heap_alloc(sizeof(*devInfo)); - - if (devInfo) - { - devInfo->set = set; - devInfo->devId = alloc_devnode(devInfo); - - devInfo->instanceId = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(instanceId) + 1) * sizeof(WCHAR)); - if (devInfo->instanceId) - { - devInfo->key = INVALID_HANDLE_VALUE; - devInfo->phantom = phantom; - lstrcpyW(devInfo->instanceId, instanceId); - struprW(devInfo->instanceId); - devInfo->key = SETUPDI_CreateDevKey(devInfo); - if (devInfo->key != INVALID_HANDLE_VALUE) - { - if (phantom) - RegSetValueExW(devInfo->key, Phantom, 0, REG_DWORD, - (LPBYTE)&phantom, sizeof(phantom)); - } - list_init(&devInfo->interfaces); - } - else - { - heap_free(devInfo); - devInfo = NULL; - } - } - return devInfo; -} - -static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo) +static void SETUPDI_RemoveDevice(struct device *device) { struct InterfaceInstances *iface, *next;
- if (devInfo->key != INVALID_HANDLE_VALUE) - RegCloseKey(devInfo->key); - if (devInfo->phantom) + if (device->key != INVALID_HANDLE_VALUE) + RegCloseKey(device->key); + if (device->phantom) { HKEY enumKey; LONG l; @@ -599,70 +556,61 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo) KEY_ALL_ACCESS, NULL, &enumKey, NULL); if (!l) { - RegDeleteTreeW(enumKey, devInfo->instanceId); + RegDeleteTreeW(enumKey, device->instanceId); RegCloseKey(enumKey); } } - HeapFree(GetProcessHeap(), 0, devInfo->instanceId); - LIST_FOR_EACH_ENTRY_SAFE(iface, next, &devInfo->interfaces, + heap_free(device->instanceId); + LIST_FOR_EACH_ENTRY_SAFE(iface, next, &device->interfaces, struct InterfaceInstances, entry) { list_remove(&iface->entry); SETUPDI_FreeInterfaceInstances(iface); HeapFree(GetProcessHeap(), 0, iface); } - free_devnode(devInfo->devId); - heap_free(devInfo); + free_devnode(device->data.DevInst); + list_remove(&device->entry); + heap_free(device); }
-/* Adds a device with GUID guid and identifier devInst to set. Allocates a - * struct DeviceInfo, and points the returned device info's Reserved member - * to it. "Phantom" devices are deleted from the registry when closed. - * Returns a pointer to the newly allocated device info. - */ -static BOOL SETUPDI_AddDeviceToSet(struct DeviceInfoSet *set, - const GUID *guid, - DWORD dev_inst, - LPCWSTR instanceId, - BOOL phantom, - SP_DEVINFO_DATA **dev) +static SP_DEVINFO_DATA *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, + const GUID *class, const WCHAR *instanceid, BOOL phantom) { - BOOL ret = FALSE; - struct DeviceInfo *devInfo = SETUPDI_AllocateDeviceInfo(set, set->cDevices, - instanceId, phantom); + struct device *device; + WCHAR guidstr[39];
- TRACE("%p, %s, %d, %s, %d\n", set, debugstr_guid(guid), dev_inst, - debugstr_w(instanceId), phantom); + TRACE("%p, %s, %s, %d\n", set, debugstr_guid(class), + debugstr_w(instanceid), phantom);
- if (devInfo) + if (!(device = heap_alloc(sizeof(*device)))) { - struct DeviceInstance *devInst = - HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInstance)); - - if (devInst) - { - WCHAR classGuidStr[39]; - - list_add_tail(&set->devices, &devInst->entry); - set->cDevices++; - devInst->data.cbSize = sizeof(SP_DEVINFO_DATA); - devInst->data.ClassGuid = *guid; - devInst->data.DevInst = devInfo->devId; - devInst->data.Reserved = (ULONG_PTR)devInfo; - SETUPDI_GuidToString(guid, classGuidStr); - SetupDiSetDeviceRegistryPropertyW(set, &devInst->data, - SPDRP_CLASSGUID, (const BYTE *)classGuidStr, - lstrlenW(classGuidStr) * sizeof(WCHAR)); - if (dev) *dev = &devInst->data; - ret = TRUE; - } - else - { - HeapFree(GetProcessHeap(), 0, devInfo); - SetLastError(ERROR_OUTOFMEMORY); - } + SetLastError(ERROR_OUTOFMEMORY); + return NULL; } - return ret; + + if (!(device->instanceId = strdupW(instanceid))) + { + SetLastError(ERROR_OUTOFMEMORY); + heap_free(device); + return NULL; + } + + struprW(device->instanceId); + device->set = set; + device->key = SETUPDI_CreateDevKey(device); + device->phantom = phantom; + list_init(&device->interfaces); + device->data.cbSize = sizeof(SP_DEVINFO_DATA); + device->data.ClassGuid = *class; + device->data.DevInst = alloc_devnode(device); + device->data.Reserved = (ULONG_PTR)device; + list_add_tail(&set->devices, &device->entry); + set->cDevices++; + + SETUPDI_GuidToString(class, guidstr); + SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_CLASSGUID, + (const BYTE *)guidstr, sizeof(guidstr)); + return &device->data; }
/*********************************************************************** @@ -1332,7 +1280,7 @@ HKEY WINAPI SetupDiCreateDevRegKeyW( PCWSTR InfSectionName) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device; HKEY key = INVALID_HANDLE_VALUE;
TRACE("%p %p %d %d %d %p %s\n", DeviceInfoSet, DeviceInfoData, Scope, @@ -1354,8 +1302,8 @@ HKEY WINAPI SetupDiCreateDevRegKeyW( SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; @@ -1370,7 +1318,7 @@ HKEY WINAPI SetupDiCreateDevRegKeyW( SetLastError(ERROR_INVALID_FLAGS); return INVALID_HANDLE_VALUE; } - if (devInfo->phantom) + if (device->phantom) { SetLastError(ERROR_DEVINFO_NOT_REGISTERED); return INVALID_HANDLE_VALUE; @@ -1380,10 +1328,10 @@ HKEY WINAPI SetupDiCreateDevRegKeyW( switch (KeyType) { case DIREG_DEV: - key = SETUPDI_CreateDevKey(devInfo); + key = SETUPDI_CreateDevKey(device); break; case DIREG_DRV: - key = SETUPDI_CreateDrvKey(devInfo); + key = SETUPDI_CreateDrvKey(device); break; default: WARN("unknown KeyType %d\n", KeyType); @@ -1507,18 +1455,17 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, if (set->cDevices) { DWORD highestDevID = 0; - struct DeviceInstance *devInst; + struct device *device;
- LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry) + LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { - struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved; - LPCWSTR devName = strrchrW(devInfo->instanceId, '\'); + const WCHAR *devName = strrchrW(device->instanceId, '\'); DWORD id;
if (devName) devName++; else - devName = devInfo->instanceId; + devName = device->instanceId; id = SETUPDI_DevNameToDevID(devName); if (id != 0xffffffff && id > highestDevID) highestDevID = id; @@ -1543,15 +1490,13 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, } else { - struct DeviceInstance *devInst; + struct device *device;
ret = TRUE; instanceId = DeviceName; - LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry) + LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { - struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved; - - if (!lstrcmpiW(DeviceName, devInfo->instanceId)) + if (!lstrcmpiW(DeviceName, device->instanceId)) { SetLastError(ERROR_DEVINST_ALREADY_EXISTS); ret = FALSE; @@ -1562,9 +1507,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, { SP_DEVINFO_DATA *dev = NULL;
- ret = SETUPDI_AddDeviceToSet(set, ClassGuid, 0 /* FIXME: DevInst */, - instanceId, TRUE, &dev); - if (ret) + if ((dev = SETUPDI_CreateDeviceInfo(set, ClassGuid, instanceId, TRUE))) { if (DeviceDescription) SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, @@ -1600,7 +1543,7 @@ BOOL WINAPI SetupDiRegisterDeviceInfo( PSP_DEVINFO_DATA DupDeviceInfoData) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device;
TRACE("%p %p %08x %p %p %p\n", DeviceInfoSet, DeviceInfoData, Flags, CompareProc, CompareContext, DupDeviceInfoData); @@ -1621,16 +1564,16 @@ BOOL WINAPI SetupDiRegisterDeviceInfo( SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (devInfo->phantom) + if (device->phantom) { - devInfo->phantom = FALSE; - RegDeleteValueW(devInfo->key, Phantom); + device->phantom = FALSE; + RegDeleteValueW(device->key, Phantom); } return TRUE; } @@ -1683,15 +1626,14 @@ BOOL WINAPI SetupDiEnumDeviceInfo( { if (info->cbSize == sizeof(SP_DEVINFO_DATA)) { - struct DeviceInstance *devInst; + struct device *device; DWORD i = 0;
- LIST_FOR_EACH_ENTRY(devInst, &list->devices, - struct DeviceInstance, entry) + LIST_FOR_EACH_ENTRY(device, &list->devices, struct device, entry) { if (i++ == index) { - *info = devInst->data; + *info = device->data; break; } } @@ -1778,7 +1720,7 @@ BOOL WINAPI SetupDiGetDeviceInstanceIdW( PDWORD RequiredSize) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device;
TRACE("%p %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstanceId, DeviceInstanceIdSize, RequiredSize); @@ -1799,23 +1741,23 @@ BOOL WINAPI SetupDiGetDeviceInstanceIdW( SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - TRACE("instance ID: %s\n", debugstr_w(devInfo->instanceId)); - if (DeviceInstanceIdSize < strlenW(devInfo->instanceId) + 1) + TRACE("instance ID: %s\n", debugstr_w(device->instanceId)); + if (DeviceInstanceIdSize < strlenW(device->instanceId) + 1) { SetLastError(ERROR_INSUFFICIENT_BUFFER); if (RequiredSize) - *RequiredSize = lstrlenW(devInfo->instanceId) + 1; + *RequiredSize = lstrlenW(device->instanceId) + 1; return FALSE; } - lstrcpyW(DeviceInstanceId, devInfo->instanceId); + lstrcpyW(DeviceInstanceId, device->instanceId); if (RequiredSize) - *RequiredSize = lstrlenW(devInfo->instanceId) + 1; + *RequiredSize = lstrlenW(device->instanceId) + 1; return TRUE; }
@@ -2178,9 +2120,8 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet, deviceClassStr[37] = 0; UuidFromStringW(&deviceClassStr[1], &deviceClass); - if (SETUPDI_AddDeviceToSet(set, &deviceClass, - 0 /* FIXME: DevInst */, deviceInst, - FALSE, &dev)) + if ((dev = SETUPDI_CreateDeviceInfo(set, + &deviceClass, deviceInst, FALSE))) SETUPDI_AddDeviceInterfaces(dev, subKey, guid); } RegCloseKey(deviceKey); @@ -2305,9 +2246,8 @@ static void SETUPDI_EnumerateMatchingDeviceInstances(struct DeviceInfoSet *set, { sprintfW(instanceId, fmt, enumerator, deviceName, deviceInstance); - SETUPDI_AddDeviceToSet(set, &deviceClass, - 0 /* FIXME: DevInst */, instanceId, - FALSE, NULL); + SETUPDI_CreateDeviceInfo(set, &deviceClass, + instanceId, FALSE); HeapFree(GetProcessHeap(), 0, instanceId); } } @@ -2569,7 +2509,7 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device; SP_DEVICE_INTERFACE_DATA *iface = NULL; BOOL ret;
@@ -2593,8 +2533,8 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -2751,12 +2691,12 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( samDesired, NULL, &interfKey, NULL); if (!l) { - struct DeviceInfo *devInfo = - (struct DeviceInfo *)ifaceInfo->device->Reserved; + struct device *device = + (struct device *)ifaceInfo->device->Reserved;
l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ, - (BYTE *)devInfo->instanceId, - (lstrlenW(devInfo->instanceId) + 1) * sizeof(WCHAR)); + (BYTE *)device->instanceId, + (lstrlenW(device->instanceId) + 1) * sizeof(WCHAR)); if (!l) { if (instancePath) @@ -2901,11 +2841,10 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA
if (DeviceInfoData) { - struct DeviceInfo *devInfo = - (struct DeviceInfo *)DeviceInfoData->Reserved; + struct device *device = (struct device *)DeviceInfoData->Reserved; struct InterfaceInstances *iface;
- if ((ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface))) + if ((ret = SETUPDI_FindInterface(device, InterfaceClassGuid, &iface))) { if (MemberIndex < iface->cInstances) *DeviceInterfaceData = iface->instances[MemberIndex]; @@ -2920,18 +2859,17 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA } else { - struct DeviceInstance *devInst; + struct device *device; DWORD cEnumerated = 0; BOOL found = FALSE;
- LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry) + LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { - struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved; struct InterfaceInstances *iface;
if (found || cEnumerated >= MemberIndex + 1) break; - if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface)) + if (SETUPDI_FindInterface(device, InterfaceClassGuid, &iface)) { if (cEnumerated + iface->cInstances < MemberIndex + 1) cEnumerated += iface->cInstances; @@ -2975,14 +2913,12 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) { - struct DeviceInstance *devInst, *devInst2; + struct device *device, *device2;
- LIST_FOR_EACH_ENTRY_SAFE(devInst, devInst2, &list->devices, - struct DeviceInstance, entry) + LIST_FOR_EACH_ENTRY_SAFE(device, device2, &list->devices, + struct device, entry) { - SETUPDI_FreeDeviceInfo( (struct DeviceInfo *)devInst->data.Reserved ); - list_remove(&devInst->entry); - HeapFree(GetProcessHeap(), 0, devInst); + SETUPDI_RemoveDevice(device); } HeapFree(GetProcessHeap(), 0, list); ret = TRUE; @@ -3148,7 +3084,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyA( { BOOL ret = FALSE; struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device;
TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, @@ -3175,12 +3111,12 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyA( SetLastError(ERROR_INVALID_DATA); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + device = (struct device *)DeviceInfoData->Reserved; if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0]) && PropertyMap[Property].nameA) { DWORD size = PropertyBufferSize; - LONG l = RegQueryValueExA(devInfo->key, PropertyMap[Property].nameA, + LONG l = RegQueryValueExA(device->key, PropertyMap[Property].nameA, NULL, PropertyRegDataType, PropertyBuffer, &size);
if (l == ERROR_FILE_NOT_FOUND) @@ -3211,7 +3147,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW( { BOOL ret = FALSE; struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device;
TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, @@ -3238,12 +3174,12 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW( SetLastError(ERROR_INVALID_DATA); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + device = (struct device *)DeviceInfoData->Reserved; if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0]) && PropertyMap[Property].nameW) { DWORD size = PropertyBufferSize; - LONG l = RegQueryValueExW(devInfo->key, PropertyMap[Property].nameW, + LONG l = RegQueryValueExW(device->key, PropertyMap[Property].nameW, NULL, PropertyRegDataType, PropertyBuffer, &size);
if (l == ERROR_FILE_NOT_FOUND) @@ -3272,7 +3208,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyA( { BOOL ret = FALSE; struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device;
TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property, PropertyBuffer, PropertyBufferSize); @@ -3293,11 +3229,11 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyA( SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + device = (struct device *)DeviceInfoData->Reserved; if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0]) && PropertyMap[Property].nameA) { - LONG l = RegSetValueExA(devInfo->key, PropertyMap[Property].nameA, 0, + LONG l = RegSetValueExA(device->key, PropertyMap[Property].nameA, 0, PropertyMap[Property].regType, PropertyBuffer, PropertyBufferSize); if (!l) @@ -3315,7 +3251,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, DWORD prop, const BYTE *buffer, DWORD size) { struct DeviceInfoSet *set = devinfo; - struct DeviceInfo *device; + struct device *device;
TRACE("%p %p %d %p %d\n", devinfo, device_data, prop, buffer, size);
@@ -3336,7 +3272,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO devinfo, return FALSE; }
- device = (struct DeviceInfo *)device_data->Reserved; + device = (struct device *)device_data->Reserved; return SETUPDI_SetDeviceRegistryPropertyW(device, prop, buffer, size); }
@@ -3781,7 +3717,7 @@ BOOL WINAPI SetupDiSetDeviceInstallParamsW( return TRUE; }
-static HKEY SETUPDI_OpenDevKey(struct DeviceInfo *devInfo, REGSAM samDesired) +static HKEY SETUPDI_OpenDevKey(struct device *device, REGSAM samDesired) { HKEY enumKey, key = INVALID_HANDLE_VALUE; LONG l; @@ -3790,13 +3726,13 @@ static HKEY SETUPDI_OpenDevKey(struct DeviceInfo *devInfo, REGSAM samDesired) NULL, &enumKey, NULL); if (!l) { - RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key); + RegOpenKeyExW(enumKey, device->instanceId, 0, samDesired, &key); RegCloseKey(enumKey); } return key; }
-static HKEY SETUPDI_OpenDrvKey(struct DeviceInfo *devInfo, REGSAM samDesired) +static HKEY SETUPDI_OpenDrvKey(struct device *device, REGSAM samDesired) { static const WCHAR slash[] = { '\',0 }; WCHAR classKeyPath[MAX_PATH]; @@ -3805,7 +3741,7 @@ static HKEY SETUPDI_OpenDrvKey(struct DeviceInfo *devInfo, REGSAM samDesired)
lstrcpyW(classKeyPath, ControlClass); lstrcatW(classKeyPath, slash); - SETUPDI_GuidToString(&devInfo->set->ClassGuid, + SETUPDI_GuidToString(&device->set->ClassGuid, classKeyPath + lstrlenW(classKeyPath)); l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, classKeyPath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classKey, NULL); @@ -3814,7 +3750,7 @@ static HKEY SETUPDI_OpenDrvKey(struct DeviceInfo *devInfo, REGSAM samDesired) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, devInfo->devId); + sprintfW(devId, fmt, device->data.DevInst); l = RegOpenKeyExW(classKey, devId, 0, samDesired, &key); RegCloseKey(classKey); if (l) @@ -3838,7 +3774,7 @@ HKEY WINAPI SetupDiOpenDevRegKey( REGSAM samDesired) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device; HKEY key = INVALID_HANDLE_VALUE;
TRACE("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData, @@ -3870,13 +3806,13 @@ HKEY WINAPI SetupDiOpenDevRegKey( SetLastError(ERROR_INVALID_FLAGS); return INVALID_HANDLE_VALUE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } - if (devInfo->phantom) + if (device->phantom) { SetLastError(ERROR_DEVINFO_NOT_REGISTERED); return INVALID_HANDLE_VALUE; @@ -3886,10 +3822,10 @@ HKEY WINAPI SetupDiOpenDevRegKey( switch (KeyType) { case DIREG_DEV: - key = SETUPDI_OpenDevKey(devInfo, samDesired); + key = SETUPDI_OpenDevKey(device, samDesired); break; case DIREG_DRV: - key = SETUPDI_OpenDrvKey(devInfo, samDesired); + key = SETUPDI_OpenDrvKey(device, samDesired); break; default: WARN("unknown KeyType %d\n", KeyType); @@ -3897,7 +3833,7 @@ HKEY WINAPI SetupDiOpenDevRegKey( return key; }
-static BOOL SETUPDI_DeleteDevKey(struct DeviceInfo *devInfo) +static BOOL SETUPDI_DeleteDevKey(struct device *device) { HKEY enumKey; BOOL ret = FALSE; @@ -3907,7 +3843,7 @@ static BOOL SETUPDI_DeleteDevKey(struct DeviceInfo *devInfo) NULL, &enumKey, NULL); if (!l) { - ret = RegDeleteTreeW(enumKey, devInfo->instanceId); + ret = RegDeleteTreeW(enumKey, device->instanceId); RegCloseKey(enumKey); } else @@ -3915,7 +3851,7 @@ static BOOL SETUPDI_DeleteDevKey(struct DeviceInfo *devInfo) return ret; }
-static BOOL SETUPDI_DeleteDrvKey(struct DeviceInfo *devInfo) +static BOOL SETUPDI_DeleteDrvKey(struct device *device) { static const WCHAR slash[] = { '\',0 }; WCHAR classKeyPath[MAX_PATH]; @@ -3925,7 +3861,7 @@ static BOOL SETUPDI_DeleteDrvKey(struct DeviceInfo *devInfo)
lstrcpyW(classKeyPath, ControlClass); lstrcatW(classKeyPath, slash); - SETUPDI_GuidToString(&devInfo->set->ClassGuid, + SETUPDI_GuidToString(&device->set->ClassGuid, classKeyPath + lstrlenW(classKeyPath)); l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, classKeyPath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classKey, NULL); @@ -3934,7 +3870,7 @@ static BOOL SETUPDI_DeleteDrvKey(struct DeviceInfo *devInfo) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, devInfo->devId); + sprintfW(devId, fmt, device->data.DevInst); ret = RegDeleteTreeW(classKey, devId); RegCloseKey(classKey); } @@ -3954,7 +3890,7 @@ BOOL WINAPI SetupDiDeleteDevRegKey( DWORD KeyType) { struct DeviceInfoSet *set = DeviceInfoSet; - struct DeviceInfo *devInfo; + struct device *device; BOOL ret = FALSE;
TRACE("%p %p %d %d %d\n", DeviceInfoSet, DeviceInfoData, Scope, HwProfile, @@ -3986,13 +3922,13 @@ BOOL WINAPI SetupDiDeleteDevRegKey( SetLastError(ERROR_INVALID_FLAGS); return FALSE; } - devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; - if (devInfo->set != set) + device = (struct device *)DeviceInfoData->Reserved; + if (device->set != set) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (devInfo->phantom) + if (device->phantom) { SetLastError(ERROR_DEVINFO_NOT_REGISTERED); return FALSE; @@ -4002,15 +3938,15 @@ BOOL WINAPI SetupDiDeleteDevRegKey( switch (KeyType) { case DIREG_DEV: - ret = SETUPDI_DeleteDevKey(devInfo); + ret = SETUPDI_DeleteDevKey(device); break; case DIREG_DRV: - ret = SETUPDI_DeleteDrvKey(devInfo); + ret = SETUPDI_DeleteDrvKey(device); break; case DIREG_BOTH: - ret = SETUPDI_DeleteDevKey(devInfo); + ret = SETUPDI_DeleteDevKey(device); if (ret) - ret = SETUPDI_DeleteDrvKey(devInfo); + ret = SETUPDI_DeleteDrvKey(device); break; default: WARN("unknown KeyType %d\n", KeyType); @@ -4023,7 +3959,7 @@ BOOL WINAPI SetupDiDeleteDevRegKey( */ CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULONG flags) { - struct DeviceInfo *device = get_devnode_device(devnode); + struct device *device = get_devnode_device(devnode);
TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
@@ -4040,7 +3976,7 @@ CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULO */ CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, ULONG flags) { - struct DeviceInfo *device = get_devnode_device(devnode); + struct device *device = get_devnode_device(devnode);
TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
@@ -4057,7 +3993,7 @@ CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, UL */ CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) { - struct DeviceInfo *device = get_devnode_device(devnode); + struct device *device = get_devnode_device(devnode);
TRACE("%p, %u, %#x\n", len, devnode, flags);
And especially don't use a pointer to one, since there's no guarantee it'll remain stable.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 98 +++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 47 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 336c548..a845290 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -111,7 +111,8 @@ struct device BOOL phantom; WCHAR *instanceId; struct list interfaces; - SP_DEVINFO_DATA data; + GUID class; + DEVINST devnode; struct list entry; };
@@ -120,7 +121,7 @@ struct InterfaceInfo { LPWSTR referenceString; LPWSTR symbolicLink; - PSP_DEVINFO_DATA device; + struct device *device; };
/* A device may have multiple instances of the same interface, so this holds @@ -135,6 +136,13 @@ struct InterfaceInstances struct list entry; };
+static inline void copy_device_data(SP_DEVINFO_DATA *data, const struct device *device) +{ + data->ClassGuid = device->class; + data->DevInst = device->devnode; + data->Reserved = (ULONG_PTR)device; +} + static struct device **devnode_table; static unsigned int devnode_table_size;
@@ -202,12 +210,9 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances) struct InterfaceInfo *ifaceInfo = (struct InterfaceInfo *)instances->instances[i].Reserved;
- if (ifaceInfo->device && ifaceInfo->device->Reserved) + if (ifaceInfo->device && ifaceInfo->device->phantom) { - struct device *device = (struct device *)ifaceInfo->device->Reserved; - - if (device->phantom) - SetupDiDeleteDeviceInterfaceRegKey(device->set, + SetupDiDeleteDeviceInterfaceRegKey(ifaceInfo->device->set, &instances->instances[i], 0); } HeapFree(GetProcessHeap(), 0, ifaceInfo->referenceString); @@ -319,11 +324,10 @@ static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId, * the device, if it doesn't already exist in the device. If iface is not * NULL, returns a pointer to the newly added (or already existing) interface. */ -static BOOL SETUPDI_AddInterfaceInstance(PSP_DEVINFO_DATA DeviceInfoData, +static BOOL SETUPDI_AddInterfaceInstance(struct device *devInfo, const GUID *InterfaceClassGuid, LPCWSTR ReferenceString, SP_DEVICE_INTERFACE_DATA **ifaceData) { - struct device *devInfo = (struct device *)DeviceInfoData->Reserved; BOOL newInterface = FALSE, ret; struct InterfaceInstances *iface = NULL;
@@ -375,7 +379,7 @@ static BOOL SETUPDI_AddInterfaceInstance(PSP_DEVINFO_DATA DeviceInfoData, if (ifaceInfo) { ret = TRUE; - ifaceInfo->device = &devInfo->data; + ifaceInfo->device = devInfo; ifaceInfo->symbolicLink = SETUPDI_CreateSymbolicLinkPath( devInfo->instanceId, InterfaceClassGuid, ReferenceString); @@ -489,7 +493,7 @@ static HKEY SETUPDI_CreateDrvKey(struct device *device) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, device->data.DevInst); + sprintfW(devId, fmt, device->devnode); RegCreateKeyExW(classKey, devId, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL); RegCloseKey(classKey); @@ -568,12 +572,12 @@ static void SETUPDI_RemoveDevice(struct device *device) SETUPDI_FreeInterfaceInstances(iface); HeapFree(GetProcessHeap(), 0, iface); } - free_devnode(device->data.DevInst); + free_devnode(device->devnode); list_remove(&device->entry); heap_free(device); }
-static SP_DEVINFO_DATA *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, +static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, const GUID *class, const WCHAR *instanceid, BOOL phantom) { struct device *device; @@ -600,17 +604,15 @@ static SP_DEVINFO_DATA *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, device->key = SETUPDI_CreateDevKey(device); device->phantom = phantom; list_init(&device->interfaces); - device->data.cbSize = sizeof(SP_DEVINFO_DATA); - device->data.ClassGuid = *class; - device->data.DevInst = alloc_devnode(device); - device->data.Reserved = (ULONG_PTR)device; + device->class = *class; + device->devnode = alloc_devnode(device); list_add_tail(&set->devices, &device->entry); set->cDevices++;
SETUPDI_GuidToString(class, guidstr); SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_CLASSGUID, (const BYTE *)guidstr, sizeof(guidstr)); - return &device->data; + return device; }
/*********************************************************************** @@ -1406,7 +1408,7 @@ static DWORD SETUPDI_DevNameToDevID(LPCWSTR devName) */ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, const GUID *ClassGuid, PCWSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags, - PSP_DEVINFO_DATA DeviceInfoData) + SP_DEVINFO_DATA *device_data) { struct DeviceInfoSet *set = DeviceInfoSet; BOOL ret = FALSE, allocatedInstanceId = FALSE; @@ -1414,7 +1416,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName,
TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName), debugstr_guid(ClassGuid), debugstr_w(DeviceDescription), - hwndParent, CreationFlags, DeviceInfoData); + hwndParent, CreationFlags, device_data);
if (!DeviceName) { @@ -1505,23 +1507,23 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, } if (ret) { - SP_DEVINFO_DATA *dev = NULL; + struct device *device = NULL;
- if ((dev = SETUPDI_CreateDeviceInfo(set, ClassGuid, instanceId, TRUE))) + if ((device = SETUPDI_CreateDeviceInfo(set, ClassGuid, instanceId, TRUE))) { if (DeviceDescription) - SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, - dev, SPDRP_DEVICEDESC, (const BYTE *)DeviceDescription, + SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_DEVICEDESC, + (const BYTE *)DeviceDescription, lstrlenW(DeviceDescription) * sizeof(WCHAR)); - if (DeviceInfoData) + if (device_data) { - if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + if (device_data->cbSize != sizeof(SP_DEVINFO_DATA)) { SetLastError(ERROR_INVALID_USER_BUFFER); ret = FALSE; } else - *DeviceInfoData = *dev; + copy_device_data(device_data, device); } } } @@ -1633,7 +1635,7 @@ BOOL WINAPI SetupDiEnumDeviceInfo( { if (i++ == index) { - *info = device->data; + copy_device_data(info, device); break; } } @@ -2023,8 +2025,7 @@ end: return ret; }
-static void SETUPDI_AddDeviceInterfaces(SP_DEVINFO_DATA *dev, HKEY key, - const GUID *guid) +static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, const GUID *guid) { DWORD i, len; WCHAR subKeyName[MAX_PATH]; @@ -2042,7 +2043,7 @@ static void SETUPDI_AddDeviceInterfaces(SP_DEVINFO_DATA *dev, HKEY key, if (*subKeyName == '#') { /* The subkey name is the reference string, with a '#' prepended */ - SETUPDI_AddInterfaceInstance(dev, guid, subKeyName + 1, &iface); + SETUPDI_AddInterfaceInstance(device, guid, subKeyName + 1, &iface); l = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey); if (!l) { @@ -2115,14 +2116,14 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet, deviceClassStr[37] == '}') { GUID deviceClass; - SP_DEVINFO_DATA *dev; + struct device *device;
deviceClassStr[37] = 0; UuidFromStringW(&deviceClassStr[1], &deviceClass); - if ((dev = SETUPDI_CreateDeviceInfo(set, + if ((device = SETUPDI_CreateDeviceInfo(set, &deviceClass, deviceInst, FALSE))) - SETUPDI_AddDeviceInterfaces(dev, subKey, guid); + SETUPDI_AddDeviceInterfaces(device, subKey, guid); } RegCloseKey(deviceKey); } @@ -2544,7 +2545,7 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( SetLastError(ERROR_INVALID_USER_BUFFER); return FALSE; } - if ((ret = SETUPDI_AddInterfaceInstance(DeviceInfoData, InterfaceClassGuid, + if ((ret = SETUPDI_AddInterfaceInstance(device, InterfaceClassGuid, ReferenceString, &iface))) { if (DeviceInterfaceData) @@ -2691,8 +2692,7 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( samDesired, NULL, &interfKey, NULL); if (!l) { - struct device *device = - (struct device *)ifaceInfo->device->Reserved; + struct device *device = ifaceInfo->device;
l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ, (BYTE *)device->instanceId, @@ -2940,7 +2940,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, - PSP_DEVINFO_DATA DeviceInfoData) + SP_DEVINFO_DATA *device_data) { struct DeviceInfoSet *set = DeviceInfoSet; struct InterfaceInfo *info; @@ -2949,7 +2949,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, - DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); + DeviceInterfaceDetailDataSize, RequiredSize, device_data);
if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) @@ -2989,8 +2989,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( NULL, NULL); else DeviceInterfaceDetailData->DevicePath[0] = '\0'; - if (DeviceInfoData && DeviceInfoData->cbSize == sizeof(SP_DEVINFO_DATA)) - *DeviceInfoData = *info->device; + + if (device_data && device_data->cbSize == sizeof(SP_DEVINFO_DATA)) + copy_device_data(device_data, info->device); + ret = TRUE; } else @@ -3011,7 +3013,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, - PSP_DEVINFO_DATA DeviceInfoData) + SP_DEVINFO_DATA *device_data) { struct DeviceInfoSet *set = DeviceInfoSet; struct InterfaceInfo *info; @@ -3021,7 +3023,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, - DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); + DeviceInterfaceDetailDataSize, RequiredSize, device_data);
if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) @@ -3057,8 +3059,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( lstrcpyW(DeviceInterfaceDetailData->DevicePath, info->symbolicLink); else DeviceInterfaceDetailData->DevicePath[0] = '\0'; - if (DeviceInfoData && DeviceInfoData->cbSize == sizeof(SP_DEVINFO_DATA)) - *DeviceInfoData = *info->device; + + if (device_data && device_data->cbSize == sizeof(SP_DEVINFO_DATA)) + copy_device_data(device_data, info->device); + ret = TRUE; } else @@ -3750,7 +3754,7 @@ static HKEY SETUPDI_OpenDrvKey(struct device *device, REGSAM samDesired) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, device->data.DevInst); + sprintfW(devId, fmt, device->devnode); l = RegOpenKeyExW(classKey, devId, 0, samDesired, &key); RegCloseKey(classKey); if (l) @@ -3870,7 +3874,7 @@ static BOOL SETUPDI_DeleteDrvKey(struct device *device) static const WCHAR fmt[] = { '%','0','4','u',0 }; WCHAR devId[10];
- sprintfW(devId, fmt, device->data.DevInst); + sprintfW(devId, fmt, device->devnode); ret = RegDeleteTreeW(classKey, devId); RegCloseKey(classKey); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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;
It seems the original motivation for separating these was to facilitate easy enumeration of specific classes using SetupDiEnumDeviceInterfaces(), but it makes other things unnecessarily complex [including an eventual implementation of SetupDiRemoveDeviceInterface()] and the implementation provided here seems quite simple enough.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 549 +++++++++++++++++------------------------------- 1 file changed, 193 insertions(+), 356 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 2e4ff3a..8b97eb5 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -116,24 +116,14 @@ struct device struct list entry; };
-/* Pointed to by SP_DEVICE_INTERFACE_DATA's Reserved member */ -struct InterfaceInfo +struct device_iface { - LPWSTR referenceString; - LPWSTR symbolicLink; + WCHAR *refstr; + WCHAR *symlink; struct device *device; -}; - -/* A device may have multiple instances of the same interface, so this holds - * each instance belonging to a particular interface. - */ -struct InterfaceInstances -{ - GUID guid; - DWORD cInstances; - DWORD cInstancesAllocated; - SP_DEVICE_INTERFACE_DATA *instances; - struct list entry; + GUID class; + DWORD flags; + struct list entry; };
static inline void copy_device_data(SP_DEVINFO_DATA *data, const struct device *device) @@ -143,6 +133,14 @@ static inline void copy_device_data(SP_DEVINFO_DATA *data, const struct device * data->Reserved = (ULONG_PTR)device; }
+static inline void copy_device_iface_data(SP_DEVICE_INTERFACE_DATA *data, + const struct device_iface *iface) +{ + data->InterfaceClassGuid = iface->class; + data->Flags = iface->flags; + data->Reserved = (ULONG_PTR)iface; +} + static struct device **devnode_table; static unsigned int devnode_table_size;
@@ -201,12 +199,11 @@ 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) +static WCHAR *get_iface_key_path(struct device_iface *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); + size_t len = strlenW(DeviceClasses) + 1 + 38 + 1 + strlenW(iface->symlink);
if (!(path = heap_alloc((len + 1) * sizeof(WCHAR)))) { @@ -216,11 +213,11 @@ static WCHAR *get_iface_key_path(SP_DEVICE_INTERFACE_DATA *iface)
strcpyW(path, DeviceClasses); strcatW(path, slashW); - SETUPDI_GuidToString(&iface->InterfaceClassGuid, path + strlenW(path)); + SETUPDI_GuidToString(&iface->class, path + strlenW(path)); strcatW(path, slashW); ptr = path + strlenW(path); - strcatW(path, info->symbolicLink); - if (strlenW(info->symbolicLink) > 3) + strcatW(path, iface->symlink); + if (strlenW(iface->symlink) > 3) ptr[0] = ptr[1] = ptr[3] = '#';
ptr = strchrW(ptr, '\'); @@ -229,16 +226,15 @@ static WCHAR *get_iface_key_path(SP_DEVICE_INTERFACE_DATA *iface) return path; }
-static WCHAR *get_refstr_key_path(SP_DEVICE_INTERFACE_DATA *iface) +static WCHAR *get_refstr_key_path(struct device_iface *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; + size_t len = strlenW(DeviceClasses) + 1 + 38 + 1 + strlenW(iface->symlink) + 1 + 1;
- if (info->referenceString) - len += strlenW(info->referenceString); + if (iface->refstr) + len += strlenW(iface->refstr);
if (!(path = heap_alloc((len + 1) * sizeof(WCHAR)))) { @@ -248,11 +244,11 @@ static WCHAR *get_refstr_key_path(SP_DEVICE_INTERFACE_DATA *iface)
strcpyW(path, DeviceClasses); strcatW(path, slashW); - SETUPDI_GuidToString(&iface->InterfaceClassGuid, path + strlenW(path)); + SETUPDI_GuidToString(&iface->class, path + strlenW(path)); strcatW(path, slashW); ptr = path + strlenW(path); - strcatW(path, info->symbolicLink); - if (strlenW(info->symbolicLink) > 3) + strcatW(path, iface->symlink); + if (strlenW(iface->symlink) > 3) ptr[0] = ptr[1] = ptr[3] = '#';
ptr = strchrW(ptr, '\'); @@ -261,100 +257,12 @@ static WCHAR *get_refstr_key_path(SP_DEVICE_INTERFACE_DATA *iface) strcatW(path, slashW); strcatW(path, hashW);
- if (info->referenceString) - strcatW(path, info->referenceString); + if (iface->refstr) + strcatW(path, iface->refstr);
return path; }
-static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances) -{ - WCHAR *path; - DWORD i; - - for (i = 0; i < instances->cInstances; i++) - { - struct InterfaceInfo *ifaceInfo = - (struct InterfaceInfo *)instances->instances[i].Reserved; - - if (ifaceInfo->device && ifaceInfo->device->phantom) - { - 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); - HeapFree(GetProcessHeap(), 0, ifaceInfo); - } - HeapFree(GetProcessHeap(), 0, instances->instances); -} - -/* Finds the interface with interface class InterfaceClassGuid in the device. - * Returns TRUE if found, and updates *interface to point to device's - * interfaces member where the given interface was found. - * Returns FALSE if not found. - */ -static BOOL SETUPDI_FindInterface(const struct device *device, - const GUID *InterfaceClassGuid, struct InterfaceInstances **iface_ret) -{ - BOOL found = FALSE; - struct InterfaceInstances *iface; - - TRACE("%s\n", debugstr_guid(InterfaceClassGuid)); - - LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct InterfaceInstances, - entry) - { - if (IsEqualGUID(&iface->guid, InterfaceClassGuid)) - { - *iface_ret = iface; - found = TRUE; - break; - } - } - TRACE("returning %d (%p)\n", found, found ? *iface_ret : NULL); - return found; -} - -/* Finds the interface instance with reference string ReferenceString in the - * interface instance map. Returns TRUE if found, and updates instanceIndex to - * the index of the interface instance's instances member - * where the given instance was found. Returns FALSE if not found. - */ -static BOOL SETUPDI_FindInterfaceInstance( - const struct InterfaceInstances *instances, - LPCWSTR ReferenceString, DWORD *instanceIndex) -{ - BOOL found = FALSE; - DWORD i; - - TRACE("%s\n", debugstr_w(ReferenceString)); - - for (i = 0; !found && i < instances->cInstances; i++) - { - SP_DEVICE_INTERFACE_DATA *ifaceData = &instances->instances[i]; - struct InterfaceInfo *ifaceInfo = - (struct InterfaceInfo *)ifaceData->Reserved; - - if (!ReferenceString && !ifaceInfo->referenceString) - { - *instanceIndex = i; - found = TRUE; - } - else if (ReferenceString && ifaceInfo->referenceString && - !lstrcmpiW(ifaceInfo->referenceString, ReferenceString)) - { - *instanceIndex = i; - found = TRUE; - } - } - TRACE("returning %d (%d)\n", found, found ? *instanceIndex : 0); - return found; -} - static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId, const GUID *InterfaceClassGuid, LPCWSTR ReferenceString) { @@ -390,159 +298,93 @@ static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId, return ret; }
-/* Adds an interface with the given interface class and reference string to - * the device, if it doesn't already exist in the device. If iface is not - * NULL, returns a pointer to the newly added (or already existing) interface. - */ -static BOOL SETUPDI_AddInterfaceInstance(struct device *devInfo, - const GUID *InterfaceClassGuid, LPCWSTR ReferenceString, - SP_DEVICE_INTERFACE_DATA **ifaceData) +static struct device_iface *SETUPDI_CreateDeviceInterface(struct device *device, + const GUID *class, const WCHAR *refstr) { - BOOL newInterface = FALSE, ret; - struct InterfaceInstances *iface = NULL; + struct device_iface *iface = NULL; + WCHAR *refstr2 = NULL, *symlink = NULL, *path = NULL; + HKEY key = NULL; + LONG ret;
- TRACE("%p %s %s %p\n", devInfo, debugstr_guid(InterfaceClassGuid), - debugstr_w(ReferenceString), iface); + TRACE("%p %s %s\n", device, debugstr_guid(class), debugstr_w(refstr));
- if (!(ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface))) + /* check if it already exists */ + LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct device_iface, entry) { - iface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(struct InterfaceInstances)); - if (iface) - { - list_add_tail(&devInfo->interfaces, &iface->entry); - newInterface = TRUE; - } + if (IsEqualGUID(&iface->class, class) && !lstrcmpiW(iface->refstr, refstr)) + return iface; } - if (iface) + + iface = heap_alloc(sizeof(*iface)); + symlink = SETUPDI_CreateSymbolicLinkPath(device->instanceId, class, refstr); + + if (!iface || !symlink) { - DWORD instanceIndex = 0; - - if (!(ret = SETUPDI_FindInterfaceInstance(iface, ReferenceString, - &instanceIndex))) - { - SP_DEVICE_INTERFACE_DATA *instance = NULL; - - if (!iface->cInstancesAllocated) - { - iface->instances = HeapAlloc(GetProcessHeap(), 0, - sizeof(SP_DEVICE_INTERFACE_DATA)); - if (iface->instances) - instance = &iface->instances[iface->cInstancesAllocated++]; - } - else if (iface->cInstances == iface->cInstancesAllocated) - { - iface->instances = HeapReAlloc(GetProcessHeap(), 0, - iface->instances, - (iface->cInstancesAllocated + 1) * - sizeof(SP_DEVICE_INTERFACE_DATA)); - if (iface->instances) - instance = &iface->instances[iface->cInstancesAllocated++]; - } - else - instance = &iface->instances[iface->cInstances]; - if (instance) - { - struct InterfaceInfo *ifaceInfo = HeapAlloc(GetProcessHeap(), - 0, sizeof(struct InterfaceInfo)); - - if (ifaceInfo) - { - ret = TRUE; - ifaceInfo->device = devInfo; - ifaceInfo->symbolicLink = SETUPDI_CreateSymbolicLinkPath( - devInfo->instanceId, InterfaceClassGuid, - ReferenceString); - if (ReferenceString) - { - ifaceInfo->referenceString = - HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(ReferenceString) + 1) * - sizeof(WCHAR)); - if (ifaceInfo->referenceString) - lstrcpyW(ifaceInfo->referenceString, - ReferenceString); - else - ret = FALSE; - } - else - ifaceInfo->referenceString = NULL; - if (ret) - { - WCHAR *path; - HKEY key; - - iface->cInstances++; - instance->cbSize = - sizeof(SP_DEVICE_INTERFACE_DATA); - instance->InterfaceClassGuid = *InterfaceClassGuid; - instance->Flags = SPINT_ACTIVE; /* FIXME */ - instance->Reserved = (ULONG_PTR)ifaceInfo; - if (newInterface) - iface->guid = *InterfaceClassGuid; - - if ((path = get_iface_key_path(instance))) - { - 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; - } - else - HeapFree(GetProcessHeap(), 0, ifaceInfo); - } - } - } - else - { - if (ifaceData) - *ifaceData = &iface->instances[instanceIndex]; - } + SetLastError(ERROR_OUTOFMEMORY); + goto err; } - else - ret = FALSE; - TRACE("returning %d\n", ret); - return ret; + + if (refstr && !(refstr2 = strdupW(refstr))) + { + SetLastError(ERROR_OUTOFMEMORY); + goto err; + } + iface->refstr = refstr2; + iface->symlink = symlink; + iface->device = device; + iface->class = *class; + iface->flags = SPINT_ACTIVE; /* FIXME */ + + if (!(path = get_iface_key_path(iface))) + { + SetLastError(ERROR_OUTOFMEMORY); + goto err; + } + + if ((ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, path, &key))) + { + SetLastError(ret); + goto err; + } + RegSetValueExW(key, DeviceInstance, 0, REG_SZ, (BYTE *)device->instanceId, + lstrlenW(device->instanceId) * sizeof(WCHAR)); + RegCloseKey(key); + heap_free(path); + + if (!(path = get_refstr_key_path(iface))) + { + SetLastError(ERROR_OUTOFMEMORY); + goto err; + } + + if ((ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, path, &key))) + { + SetLastError(ret); + goto err; + } + RegSetValueExW(key, SymbolicLink, 0, REG_SZ, (BYTE *)iface->symlink, + lstrlenW(iface->symlink) * sizeof(WCHAR)); + RegCloseKey(key); + heap_free(path); + + list_add_tail(&device->interfaces, &iface->entry); + return iface; + +err: + heap_free(iface); + heap_free(refstr2); + heap_free(symlink); + heap_free(path); + return NULL; }
-static BOOL SETUPDI_SetInterfaceSymbolicLink(SP_DEVICE_INTERFACE_DATA *iface, - LPCWSTR symbolicLink) +static BOOL SETUPDI_SetInterfaceSymbolicLink(struct device_iface *iface, + const WCHAR *symlink) { - struct InterfaceInfo *info = (struct InterfaceInfo *)iface->Reserved; - BOOL ret = FALSE; - - if (info) - { - HeapFree(GetProcessHeap(), 0, info->symbolicLink); - info->symbolicLink = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(symbolicLink) + 1) * sizeof(WCHAR)); - if (info->symbolicLink) - { - lstrcpyW(info->symbolicLink, symbolicLink); - ret = TRUE; - } - } - return ret; + heap_free(iface->symlink); + if ((iface->symlink = strdupW(symlink))) + return TRUE; + return FALSE; }
static HKEY SETUPDI_CreateDevKey(struct device *device) @@ -633,7 +475,8 @@ static BOOL SETUPDI_SetDeviceRegistryPropertyW(struct device *device,
static void SETUPDI_RemoveDevice(struct device *device) { - struct InterfaceInstances *iface, *next; + struct device_iface *iface, *next; + WCHAR *path;
if (device->key != INVALID_HANDLE_VALUE) RegCloseKey(device->key); @@ -652,11 +495,17 @@ static void SETUPDI_RemoveDevice(struct device *device) } heap_free(device->instanceId); LIST_FOR_EACH_ENTRY_SAFE(iface, next, &device->interfaces, - struct InterfaceInstances, entry) + struct device_iface, entry) { list_remove(&iface->entry); - SETUPDI_FreeInterfaceInstances(iface); - HeapFree(GetProcessHeap(), 0, iface); + if ((path = get_refstr_key_path(iface))) + { + RegDeleteKeyW(HKEY_LOCAL_MACHINE, path); + heap_free(path); + } + heap_free(iface->refstr); + heap_free(iface->symlink); + heap_free(iface); } free_devnode(device->devnode); list_remove(&device->entry); @@ -2124,12 +1973,12 @@ static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, const G if (!l) { HKEY subKey; - SP_DEVICE_INTERFACE_DATA *iface = NULL; + struct device_iface *iface;
if (*subKeyName == '#') { /* The subkey name is the reference string, with a '#' prepended */ - SETUPDI_AddInterfaceInstance(device, guid, subKeyName + 1, &iface); + iface = SETUPDI_CreateDeviceInterface(device, guid, subKeyName + 1); l = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey); if (!l) { @@ -2593,16 +2442,15 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( const GUID *InterfaceClassGuid, PCWSTR ReferenceString, DWORD CreationFlags, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) + SP_DEVICE_INTERFACE_DATA *iface_data) { struct DeviceInfoSet *set = DeviceInfoSet; struct device *device; - SP_DEVICE_INTERFACE_DATA *iface = NULL; - BOOL ret; + struct device_iface *iface;
TRACE("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData, debugstr_guid(InterfaceClassGuid), debugstr_w(ReferenceString), - CreationFlags, DeviceInterfaceData); + CreationFlags, iface_data);
if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) { @@ -2631,21 +2479,21 @@ BOOL WINAPI SetupDiCreateDeviceInterfaceW( SetLastError(ERROR_INVALID_USER_BUFFER); return FALSE; } - if ((ret = SETUPDI_AddInterfaceInstance(device, InterfaceClassGuid, - ReferenceString, &iface))) + if (!(iface = SETUPDI_CreateDeviceInterface(device, InterfaceClassGuid, + ReferenceString))) + return FALSE; + + if (iface_data) { - if (DeviceInterfaceData) + if (iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) { - if (DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) - { - SetLastError(ERROR_INVALID_USER_BUFFER); - ret = FALSE; - } - else - *DeviceInterfaceData = *iface; + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; } + + copy_device_iface_data(iface_data, iface); } - return ret; + return TRUE; }
/*********************************************************************** @@ -2682,19 +2530,18 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA( return key; }
-static PWSTR SETUPDI_GetInstancePath(struct InterfaceInfo *ifaceInfo) +static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface) { static const WCHAR hash[] = {'#',0}; PWSTR instancePath = NULL;
- if (ifaceInfo->referenceString) + if (iface->refstr) { - instancePath = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(ifaceInfo->referenceString) + 2) * sizeof(WCHAR)); + instancePath = heap_alloc((lstrlenW(iface->refstr) + 2) * sizeof(WCHAR)); if (instancePath) { lstrcpyW(instancePath, hash); - lstrcatW(instancePath, ifaceInfo->referenceString); + lstrcatW(instancePath, iface->refstr); } else SetLastError(ERROR_OUTOFMEMORY); @@ -2756,16 +2603,16 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( if (!(l = RegCreateKeyExW(interfacesKey, bracedGuidString, 0, NULL, 0, samDesired, NULL, &parent, NULL))) { - struct InterfaceInfo *ifaceInfo = - (struct InterfaceInfo *)DeviceInterfaceData->Reserved; + struct device_iface *ifaceInfo = + (struct device_iface *)DeviceInterfaceData->Reserved; PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo); PWSTR interfKeyName = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(ifaceInfo->symbolicLink) + 1) * sizeof(WCHAR)); + (lstrlenW(ifaceInfo->symlink) + 1) * sizeof(WCHAR)); HKEY interfKey; WCHAR *ptr;
- lstrcpyW(interfKeyName, ifaceInfo->symbolicLink); - if (lstrlenW(ifaceInfo->symbolicLink) > 3) + lstrcpyW(interfKeyName, ifaceInfo->symlink); + if (lstrlenW(ifaceInfo->symlink) > 3) { interfKeyName[0] = '#'; interfKeyName[1] = '#'; @@ -2850,8 +2697,8 @@ BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey( KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL); if (parent != INVALID_HANDLE_VALUE) { - struct InterfaceInfo *ifaceInfo = - (struct InterfaceInfo *)DeviceInterfaceData->Reserved; + struct device_iface *ifaceInfo = + (struct device_iface *)DeviceInterfaceData->Reserved; PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo);
if (instancePath) @@ -2892,88 +2739,78 @@ BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey( * Success: non-zero value. * Failure: FALSE. Call GetLastError() for more info. */ -BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, - const GUID *InterfaceClassGuid, DWORD MemberIndex, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) +BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO devinfo, + SP_DEVINFO_DATA *device_data, const GUID *class, DWORD index, + SP_DEVICE_INTERFACE_DATA *iface_data) { - struct DeviceInfoSet *set = DeviceInfoSet; - BOOL ret = FALSE; + struct DeviceInfoSet *set = devinfo; + struct device *device; + struct device_iface *iface; + DWORD i = 0;
- TRACE("%p, %p, %s, %d, %p\n", DeviceInfoSet, DeviceInfoData, - debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData); + TRACE("%p, %p, %s, %u, %p\n", devinfo, device_data, debugstr_guid(class), + index, iface_data);
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || + if (!devinfo || devinfo == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } - if (DeviceInfoData && (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) || - !DeviceInfoData->Reserved)) + if (device_data && (device_data->cbSize != sizeof(SP_DEVINFO_DATA) || + !device_data->Reserved)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (!DeviceInterfaceData || - DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) + if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
/* In case application fails to check return value, clear output */ - memset(DeviceInterfaceData, 0, sizeof(*DeviceInterfaceData)); - DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + memset(iface_data, 0, sizeof(*iface_data)); + iface_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
- if (DeviceInfoData) + if (device_data) { - struct device *device = (struct device *)DeviceInfoData->Reserved; - struct InterfaceInstances *iface; + device = (struct device *)device_data->Reserved;
- if ((ret = SETUPDI_FindInterface(device, InterfaceClassGuid, &iface))) + LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct device_iface, entry) { - if (MemberIndex < iface->cInstances) - *DeviceInterfaceData = iface->instances[MemberIndex]; - else + if (IsEqualGUID(&iface->class, class)) { - SetLastError(ERROR_NO_MORE_ITEMS); - ret = FALSE; + if (i == index) + { + copy_device_iface_data(iface_data, iface); + return TRUE; + } + i++; } } - else - SetLastError(ERROR_NO_MORE_ITEMS); } else { - struct device *device; - DWORD cEnumerated = 0; - BOOL found = FALSE; - LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry) { - struct InterfaceInstances *iface; - - if (found || cEnumerated >= MemberIndex + 1) - break; - if (SETUPDI_FindInterface(device, InterfaceClassGuid, &iface)) + LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct device_iface, entry) { - if (cEnumerated + iface->cInstances < MemberIndex + 1) - cEnumerated += iface->cInstances; - else + if (IsEqualGUID(&iface->class, class)) { - DWORD instanceIndex = MemberIndex - cEnumerated; - - *DeviceInterfaceData = iface->instances[instanceIndex]; - cEnumerated += instanceIndex + 1; - found = TRUE; - ret = TRUE; + if (i == index) + { + copy_device_iface_data(iface_data, iface); + return TRUE; + } + i++; } } } - if (!found) - SetLastError(ERROR_NO_MORE_ITEMS); } - return ret; + + SetLastError(ERROR_NO_MORE_ITEMS); + return FALSE; }
/*********************************************************************** @@ -3029,7 +2866,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( SP_DEVINFO_DATA *device_data) { struct DeviceInfoSet *set = DeviceInfoSet; - struct InterfaceInfo *info; + struct device_iface *iface; DWORD bytesNeeded = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath[1]); BOOL ret = FALSE;
@@ -3061,14 +2898,14 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( SetLastError(ERROR_INVALID_USER_BUFFER); return FALSE; } - info = (struct InterfaceInfo *)DeviceInterfaceData->Reserved; - if (info->symbolicLink) - bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info->symbolicLink, -1, + iface = (struct device_iface *)DeviceInterfaceData->Reserved; + if (iface->symlink) + bytesNeeded += WideCharToMultiByte(CP_ACP, 0, iface->symlink, -1, NULL, 0, NULL, NULL); if (DeviceInterfaceDetailDataSize >= bytesNeeded) { - if (info->symbolicLink) - WideCharToMultiByte(CP_ACP, 0, info->symbolicLink, -1, + if (iface->symlink) + WideCharToMultiByte(CP_ACP, 0, iface->symlink, -1, DeviceInterfaceDetailData->DevicePath, DeviceInterfaceDetailDataSize - offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath), @@ -3077,7 +2914,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( DeviceInterfaceDetailData->DevicePath[0] = '\0';
if (device_data && device_data->cbSize == sizeof(SP_DEVINFO_DATA)) - copy_device_data(device_data, info->device); + copy_device_data(device_data, iface->device);
ret = TRUE; } @@ -3102,7 +2939,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( SP_DEVINFO_DATA *device_data) { struct DeviceInfoSet *set = DeviceInfoSet; - struct InterfaceInfo *info; + struct device_iface *iface; DWORD bytesNeeded = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR); /* include NULL terminator */ BOOL ret = FALSE; @@ -3136,18 +2973,18 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( SetLastError(ERROR_INVALID_USER_BUFFER); return FALSE; } - info = (struct InterfaceInfo *)DeviceInterfaceData->Reserved; - if (info->symbolicLink) - bytesNeeded += sizeof(WCHAR)*lstrlenW(info->symbolicLink); + iface = (struct device_iface *)DeviceInterfaceData->Reserved; + if (iface->symlink) + bytesNeeded += sizeof(WCHAR) * lstrlenW(iface->symlink); if (DeviceInterfaceDetailDataSize >= bytesNeeded) { - if (info->symbolicLink) - lstrcpyW(DeviceInterfaceDetailData->DevicePath, info->symbolicLink); + if (iface->symlink) + lstrcpyW(DeviceInterfaceDetailData->DevicePath, iface->symlink); else DeviceInterfaceDetailData->DevicePath[0] = '\0';
if (device_data && device_data->cbSize == sizeof(SP_DEVINFO_DATA)) - copy_device_data(device_data, info->device); + copy_device_data(device_data, iface->device);
ret = TRUE; }
This family of functions manipulates the "Device Parameters" subkey, not its parent.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 127 +++++++++++++----------------------------- dlls/setupapi/tests/devinst.c | 57 +++++++++++++++++++ 2 files changed, 97 insertions(+), 87 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))) + + iface = (struct device_iface *)iface_data->Reserved; + if (!(path = get_refstr_key_path(iface))) { - 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; - - l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ, - (BYTE *)device->instanceId, - (lstrlenW(device->instanceId) + 1) * sizeof(WCHAR)); - if (!l) - { - if (instancePath) - { - LONG l; - - 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); + SetLastError(ERROR_OUTOFMEMORY); + return INVALID_HANDLE_VALUE; } - else - SetLastError(l); - return key; + + 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; + } + + ret = RegCreateKeyExW(refstr_key, DeviceParameters, 0, NULL, 0, access, + NULL, ¶ms_key, NULL); + RegCloseKey(refstr_key); + if (ret) + { + SetLastError(ret); + return INVALID_HANDLE_VALUE; + } + + 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(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 92 ++++++++++++++++--------------------------- dlls/setupapi/tests/devinst.c | 2 - 2 files changed, 35 insertions(+), 59 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 44d2cb9..9f77669 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -2531,32 +2531,6 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA( return key; }
-static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface) -{ - static const WCHAR hash[] = {'#',0}; - PWSTR instancePath = NULL; - - if (iface->refstr) - { - instancePath = heap_alloc((lstrlenW(iface->refstr) + 2) * sizeof(WCHAR)); - if (instancePath) - { - lstrcpyW(instancePath, hash); - lstrcatW(instancePath, iface->refstr); - } - else - SetLastError(ERROR_OUTOFMEMORY); - } - else - { - instancePath = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(hash) + 1) * sizeof(WCHAR)); - if (instancePath) - lstrcpyW(instancePath, hash); - } - return instancePath; -} - /*********************************************************************** * SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@) */ @@ -2622,51 +2596,55 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo, /*********************************************************************** * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@) */ -BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey( - HDEVINFO DeviceInfoSet, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, - DWORD Reserved) +BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(HDEVINFO devinfo, + SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved) { - struct DeviceInfoSet *set = DeviceInfoSet; - HKEY parent; - BOOL ret = FALSE; + struct DeviceInfoSet *set = devinfo; + struct device_iface *iface; + HKEY refstr_key; + WCHAR *path; + LONG ret;
- TRACE("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved); + TRACE("%p %p %d\n", devinfo, iface_data, reserved);
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE || + if (!devinfo || devinfo == INVALID_HANDLE_VALUE || set->magic != SETUP_DEVICE_INFO_SET_MAGIC) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } - 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 FALSE; } - parent = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, - KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL); - if (parent != INVALID_HANDLE_VALUE) + + iface = (struct device_iface *)iface_data->Reserved; + if (!(path = get_refstr_key_path(iface))) { - struct device_iface *ifaceInfo = - (struct device_iface *)DeviceInterfaceData->Reserved; - PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo); - - if (instancePath) - { - LONG l = RegDeleteKeyW(parent, instancePath); - - if (l) - SetLastError(l); - else - ret = TRUE; - HeapFree(GetProcessHeap(), 0, instancePath); - } - RegCloseKey(parent); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; } - return ret; + + ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL, + &refstr_key, NULL); + heap_free(path); + if (ret) + { + SetLastError(ret); + return FALSE; + } + + ret = RegDeleteKeyW(refstr_key, DeviceParameters); + RegCloseKey(refstr_key); + if (ret) + { + SetLastError(ret); + return FALSE; + } + + return TRUE; }
/*********************************************************************** diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 95d0dc4..9a8ecbc 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -1419,11 +1419,9 @@ static void test_device_interface_key(void) 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);