setupapi: Prevent of reallocating memory for _SP_DEVINFO_DATA structures.
authorAlexander Morozov <amorozov@etersoft.ru>
Thu, 3 Apr 2008 15:19:40 +0000 (19:19 +0400)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 4 Apr 2008 09:58:36 +0000 (11:58 +0200)
dlls/setupapi/devinst.c

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