Commit 44ac73ef authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

setupapi: Convert device's interfaces to a standard list.

parent 4bfca01d
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "winnls.h" #include "winnls.h"
#include "setupapi.h" #include "setupapi.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/list.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "cfgmgr32.h" #include "cfgmgr32.h"
#include "initguid.h" #include "initguid.h"
...@@ -116,17 +117,16 @@ struct InterfaceInstances ...@@ -116,17 +117,16 @@ struct InterfaceInstances
DWORD cInstances; DWORD cInstances;
DWORD cInstancesAllocated; DWORD cInstancesAllocated;
SP_DEVICE_INTERFACE_DATA *instances; SP_DEVICE_INTERFACE_DATA *instances;
struct list entry;
}; };
/* Pointed to by SP_DEVINFO_DATA's Reserved member */ /* Pointed to by SP_DEVINFO_DATA's Reserved member */
struct DeviceInfo struct DeviceInfo
{ {
HKEY key; HKEY key;
BOOL phantom; BOOL phantom;
LPWSTR instanceId; LPWSTR instanceId;
DWORD cInterfaces; struct list interfaces;
DWORD cInterfacesAllocated;
struct InterfaceInstances *interfaces;
}; };
static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr) static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
...@@ -157,27 +157,29 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances) ...@@ -157,27 +157,29 @@ static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances)
} }
/* Finds the interface with interface class InterfaceClassGuid in the device. /* Finds the interface with interface class InterfaceClassGuid in the device.
* Returns TRUE if found, and updates interfaceIndex to the index of the * Returns TRUE if found, and updates *interface to point to device's
* device's interfaces member where the given interface was found. * interfaces member where the given interface was found.
* Returns FALSE if not found. * Returns FALSE if not found.
*/ */
static BOOL SETUPDI_FindInterface(const struct DeviceInfo *devInfo, static BOOL SETUPDI_FindInterface(const struct DeviceInfo *devInfo,
const GUID *InterfaceClassGuid, DWORD *interfaceIndex) const GUID *InterfaceClassGuid, struct InterfaceInstances **interface)
{ {
BOOL found = FALSE; BOOL found = FALSE;
DWORD i; struct InterfaceInstances *iface;
TRACE("%s\n", debugstr_guid(InterfaceClassGuid)); TRACE("%s\n", debugstr_guid(InterfaceClassGuid));
for (i = 0; !found && i < devInfo->cInterfaces; i++) LIST_FOR_EACH_ENTRY(iface, &devInfo->interfaces, struct InterfaceInstances,
entry)
{ {
if (IsEqualGUID(&devInfo->interfaces[i].guid, InterfaceClassGuid)) if (IsEqualGUID(&iface->guid, InterfaceClassGuid))
{ {
*interfaceIndex = i; *interface = iface;
found = TRUE; found = TRUE;
break;
} }
} }
TRACE("returning %d (%d)\n", found, found ? *interfaceIndex : 0); TRACE("returning %d (%p)\n", found, found ? *interface : NULL);
return found; return found;
} }
...@@ -261,42 +263,21 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo, ...@@ -261,42 +263,21 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo,
SP_DEVICE_INTERFACE_DATA **ifaceData) SP_DEVICE_INTERFACE_DATA **ifaceData)
{ {
BOOL newInterface = FALSE, ret; BOOL newInterface = FALSE, ret;
DWORD interfaceIndex = 0;
struct InterfaceInstances *iface = NULL; struct InterfaceInstances *iface = NULL;
TRACE("%p %s %s %p\n", devInfo, debugstr_guid(InterfaceClassGuid), TRACE("%p %s %s %p\n", devInfo, debugstr_guid(InterfaceClassGuid),
debugstr_w(ReferenceString), iface); debugstr_w(ReferenceString), iface);
if (!(ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, if (!(ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface)))
&interfaceIndex)))
{ {
if (!devInfo->cInterfacesAllocated) iface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
{ sizeof(struct InterfaceInstances));
devInfo->interfaces = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, if (iface)
sizeof(struct InterfaceInstances));
if (devInfo->interfaces)
{
iface = &devInfo->interfaces[devInfo->cInterfacesAllocated++];
newInterface = TRUE;
}
}
else if (devInfo->cInterfaces == devInfo->cInterfacesAllocated)
{ {
devInfo->interfaces = HeapReAlloc(GetProcessHeap(), list_add_tail(&devInfo->interfaces, &iface->entry);
HEAP_ZERO_MEMORY, devInfo->interfaces, newInterface = TRUE;
(devInfo->cInterfacesAllocated + 1) *
sizeof(struct InterfaceInstances));
if (devInfo->interfaces)
{
iface = &devInfo->interfaces[devInfo->cInterfacesAllocated++];
newInterface = TRUE;
}
} }
else
iface = &devInfo->interfaces[devInfo->cInterfaces];
} }
else
iface = &devInfo->interfaces[interfaceIndex];
if (iface) if (iface)
{ {
DWORD instanceIndex = 0; DWORD instanceIndex = 0;
...@@ -359,11 +340,8 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo, ...@@ -359,11 +340,8 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo,
instance->Flags = SPINT_ACTIVE; /* FIXME */ instance->Flags = SPINT_ACTIVE; /* FIXME */
instance->Reserved = (ULONG_PTR)ifaceInfo; instance->Reserved = (ULONG_PTR)ifaceInfo;
if (newInterface) if (newInterface)
{
memcpy(&iface->guid, InterfaceClassGuid, memcpy(&iface->guid, InterfaceClassGuid,
sizeof(GUID)); sizeof(GUID));
devInfo->cInterfaces++;
}
/* FIXME: now create this homeboy in the registry */ /* FIXME: now create this homeboy in the registry */
if (ifaceData) if (ifaceData)
*ifaceData = instance; *ifaceData = instance;
...@@ -376,8 +354,7 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo, ...@@ -376,8 +354,7 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo,
else else
{ {
if (ifaceData) if (ifaceData)
*ifaceData = *ifaceData = &iface->instances[instanceIndex];
&devInfo->interfaces[interfaceIndex].instances[instanceIndex];
} }
} }
else else
...@@ -436,8 +413,7 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(LPCWSTR instanceId, ...@@ -436,8 +413,7 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(LPCWSTR instanceId,
(LPBYTE)&phantom, sizeof(phantom)); (LPBYTE)&phantom, sizeof(phantom));
RegCloseKey(enumKey); RegCloseKey(enumKey);
} }
devInfo->cInterfaces = devInfo->cInterfacesAllocated = 0; list_init(&devInfo->interfaces);
devInfo->interfaces = NULL;
} }
else else
{ {
...@@ -450,7 +426,7 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(LPCWSTR instanceId, ...@@ -450,7 +426,7 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(LPCWSTR instanceId,
static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo) static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo)
{ {
DWORD i; struct InterfaceInstances *iface, *next;
if (devInfo->key != INVALID_HANDLE_VALUE) if (devInfo->key != INVALID_HANDLE_VALUE)
RegCloseKey(devInfo->key); RegCloseKey(devInfo->key);
...@@ -468,9 +444,13 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo) ...@@ -468,9 +444,13 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo)
} }
} }
HeapFree(GetProcessHeap(), 0, devInfo->instanceId); HeapFree(GetProcessHeap(), 0, devInfo->instanceId);
for (i = 0; i < devInfo->cInterfaces; i++) LIST_FOR_EACH_ENTRY_SAFE(iface, next, &devInfo->interfaces,
SETUPDI_FreeInterfaceInstances(&devInfo->interfaces[i]); struct InterfaceInstances, entry)
HeapFree(GetProcessHeap(), 0, devInfo->interfaces); {
list_remove(&iface->entry);
SETUPDI_FreeInterfaceInstances(iface);
HeapFree(GetProcessHeap(), 0, iface);
}
HeapFree(GetProcessHeap(), 0, devInfo); HeapFree(GetProcessHeap(), 0, devInfo);
} }
...@@ -2238,13 +2218,12 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces( ...@@ -2238,13 +2218,12 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(
{ {
struct DeviceInfo *devInfo = struct DeviceInfo *devInfo =
(struct DeviceInfo *)DeviceInfoData->Reserved; (struct DeviceInfo *)DeviceInfoData->Reserved;
DWORD i; struct InterfaceInstances *iface;
if ((ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &i))) if ((ret = SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface)))
{ {
if (MemberIndex < devInfo->interfaces[i].cInstances) if (MemberIndex < iface->cInstances)
memcpy(DeviceInterfaceData, memcpy(DeviceInterfaceData, &iface->instances[MemberIndex],
&devInfo->interfaces[i].instances[MemberIndex],
sizeof(SP_DEVICE_INTERFACE_DATA)); sizeof(SP_DEVICE_INTERFACE_DATA));
else else
{ {
...@@ -2265,22 +2244,18 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces( ...@@ -2265,22 +2244,18 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(
{ {
struct DeviceInfo *devInfo = struct DeviceInfo *devInfo =
(struct DeviceInfo *)set->devices[i].Reserved; (struct DeviceInfo *)set->devices[i].Reserved;
DWORD interfaceIndex; struct InterfaceInstances *iface;
if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface))
&interfaceIndex))
{ {
struct InterfaceInstances *interface = if (cEnumerated + iface->cInstances < MemberIndex + 1)
&devInfo->interfaces[interfaceIndex]; cEnumerated += iface->cInstances;
if (cEnumerated + interface->cInstances < MemberIndex + 1)
cEnumerated += interface->cInstances;
else else
{ {
DWORD instanceIndex = MemberIndex - cEnumerated; DWORD instanceIndex = MemberIndex - cEnumerated;
memcpy(DeviceInterfaceData, memcpy(DeviceInterfaceData,
&interface->instances[instanceIndex], &iface->instances[instanceIndex],
sizeof(SP_DEVICE_INTERFACE_DATA)); sizeof(SP_DEVICE_INTERFACE_DATA));
cEnumerated += instanceIndex + 1; cEnumerated += instanceIndex + 1;
found = TRUE; found = TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment