[PATCH 7/9] setupapi: Merge the InterfaceInfo and InterfaceInstances structs.
Zebediah Figura
z.figura12 at gmail.com
Sun Jul 29 20:26:27 CDT 2018
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 at 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;
}
--
2.7.4
More information about the wine-devel
mailing list