setupapi: Prevent of reallocating memory for _SP_DEVINFO_DATA structures.

This commit is contained in:
Alexander Morozov 2008-04-03 19:19:40 +04:00 committed by Alexandre Julliard
parent cb2274e690
commit 62520da8d3
1 changed files with 53 additions and 36 deletions

View File

@ -98,7 +98,13 @@ struct DeviceInfoSet
GUID ClassGuid; GUID ClassGuid;
HWND hwndParent; HWND hwndParent;
DWORD cDevices; DWORD cDevices;
SP_DEVINFO_DATA *devices; struct list devices;
};
struct DeviceInstance
{
struct list entry;
SP_DEVINFO_DATA data;
}; };
/* Pointed to by SP_DEVICE_INTERFACE_DATA's Reserved member */ /* Pointed to by SP_DEVICE_INTERFACE_DATA's Reserved member */
@ -541,27 +547,24 @@ static BOOL SETUPDI_AddDeviceToSet(struct DeviceInfoSet *set,
if (devInfo) if (devInfo)
{ {
if (set->devices) struct DeviceInstance *devInst =
set->devices = HeapReAlloc(GetProcessHeap(), 0, set->devices, HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInstance));
(set->cDevices + 1) * sizeof(SP_DEVINFO_DATA));
else if (devInst)
set->devices = HeapAlloc(GetProcessHeap(), 0,
sizeof(SP_DEVINFO_DATA));
if (set->devices)
{ {
WCHAR classGuidStr[39]; WCHAR classGuidStr[39];
SP_DEVINFO_DATA *DeviceInfoData = &set->devices[set->cDevices++];
DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA); list_add_tail(&set->devices, &devInst->entry);
DeviceInfoData->ClassGuid = *guid; set->cDevices++;
DeviceInfoData->DevInst = devInfo->devId; devInst->data.cbSize = sizeof(SP_DEVINFO_DATA);
DeviceInfoData->Reserved = (ULONG_PTR)devInfo; devInst->data.ClassGuid = *guid;
devInst->data.DevInst = devInfo->devId;
devInst->data.Reserved = (ULONG_PTR)devInfo;
SETUPDI_GuidToString(guid, classGuidStr); SETUPDI_GuidToString(guid, classGuidStr);
SetupDiSetDeviceRegistryPropertyW((HDEVINFO)set, SetupDiSetDeviceRegistryPropertyW((HDEVINFO)set,
DeviceInfoData, SPDRP_CLASSGUID, (const BYTE *)classGuidStr, &devInst->data, SPDRP_CLASSGUID, (const BYTE *)classGuidStr,
lstrlenW(classGuidStr) * sizeof(WCHAR)); lstrlenW(classGuidStr) * sizeof(WCHAR));
if (dev) if (dev) *dev = &devInst->data;
*dev = DeviceInfoData;
ret = TRUE; ret = TRUE;
} }
else else
@ -1185,7 +1188,7 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
ClassGuid ? ClassGuid : &GUID_NULL, ClassGuid ? ClassGuid : &GUID_NULL,
sizeof(list->ClassGuid)); sizeof(list->ClassGuid));
list->cDevices = 0; list->cDevices = 0;
list->devices = NULL; list_init(&list->devices);
return (HDEVINFO)list; return (HDEVINFO)list;
} }
@ -1423,12 +1426,12 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(
if (set->cDevices) if (set->cDevices)
{ {
DWORD i, highestDevID = 0; DWORD highestDevID = 0;
struct DeviceInstance *devInst;
for (i = 0; i < set->cDevices; i++) LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry)
{ {
struct DeviceInfo *devInfo = struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved;
(struct DeviceInfo *)set->devices[i].Reserved;
LPCWSTR devName = strrchrW(devInfo->instanceId, '\\'); LPCWSTR devName = strrchrW(devInfo->instanceId, '\\');
DWORD id; DWORD id;
@ -1460,14 +1463,13 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(
} }
else else
{ {
DWORD i; struct DeviceInstance *devInst;
ret = TRUE; ret = TRUE;
instanceId = DeviceName; instanceId = DeviceName;
for (i = 0; ret && i < set->cDevices; i++) LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry)
{ {
struct DeviceInfo *devInfo = struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved;
(struct DeviceInfo *)set->devices[i].Reserved;
if (!lstrcmpiW(DeviceName, devInfo->instanceId)) if (!lstrcmpiW(DeviceName, devInfo->instanceId))
{ {
@ -1579,7 +1581,18 @@ BOOL WINAPI SetupDiEnumDeviceInfo(
{ {
if (info->cbSize == sizeof(SP_DEVINFO_DATA)) if (info->cbSize == sizeof(SP_DEVINFO_DATA))
{ {
memcpy(info, &list->devices[index], info->cbSize); struct DeviceInstance *devInst;
DWORD i = 0;
LIST_FOR_EACH_ENTRY(devInst, &list->devices,
struct DeviceInstance, entry)
{
if (i++ == index)
{
*info = devInst->data;
break;
}
}
ret = TRUE; ret = TRUE;
} }
else else
@ -2817,16 +2830,17 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(
} }
else else
{ {
DWORD i, cEnumerated = 0; struct DeviceInstance *devInst;
DWORD cEnumerated = 0;
BOOL found = FALSE; BOOL found = FALSE;
for (i = 0; !found && cEnumerated < MemberIndex + 1 && LIST_FOR_EACH_ENTRY(devInst, &set->devices, struct DeviceInstance, entry)
i < set->cDevices; i++)
{ {
struct DeviceInfo *devInfo = struct DeviceInfo *devInfo = (struct DeviceInfo *)devInst->data.Reserved;
(struct DeviceInfo *)set->devices[i].Reserved;
struct InterfaceInstances *iface; struct InterfaceInstances *iface;
if (found || cEnumerated >= MemberIndex + 1)
break;
if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface)) if (SETUPDI_FindInterface(devInfo, InterfaceClassGuid, &iface))
{ {
if (cEnumerated + iface->cInstances < MemberIndex + 1) if (cEnumerated + iface->cInstances < MemberIndex + 1)
@ -2871,12 +2885,15 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
{ {
DWORD i; struct DeviceInstance *devInst, *devInst2;
for (i = 0; i < list->cDevices; i++) LIST_FOR_EACH_ENTRY_SAFE(devInst, devInst2, &list->devices,
SETUPDI_FreeDeviceInfo( struct DeviceInstance, entry)
(struct DeviceInfo *)list->devices[i].Reserved); {
HeapFree(GetProcessHeap(), 0, list->devices); SETUPDI_FreeDeviceInfo( (struct DeviceInfo *)devInst->data.Reserved );
list_remove(&devInst->entry);
HeapFree(GetProcessHeap(), 0, devInst);
}
HeapFree(GetProcessHeap(), 0, list); HeapFree(GetProcessHeap(), 0, list);
ret = TRUE; ret = TRUE;
} }