Zebediah Figura : setupapi: Avoid adding duplicate devices in SetupDiGetClassDevs().

Alexandre Julliard julliard at winehq.org
Tue May 28 15:06:49 CDT 2019


Module: wine
Branch: master
Commit: e2194b93b5a77a2e11700833223d4504dba738c1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e2194b93b5a77a2e11700833223d4504dba738c1

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Mon May 27 22:13:20 2019 -0500

setupapi: Avoid adding duplicate devices in SetupDiGetClassDevs().

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/setupapi/devinst.c       | 35 ++++++++++++++++++-----------------
 dlls/setupapi/tests/devinst.c |  2 --
 2 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 3c75fdf..743999d 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -748,7 +748,8 @@ static void delete_device(struct device *device)
     heap_free(device);
 }
 
-static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set,
+/* Create a new device, or return a device already in the set. */
+static struct device *create_device(struct DeviceInfoSet *set,
     const GUID *class, const WCHAR *instanceid, BOOL phantom)
 {
     const DWORD one = 1;
@@ -758,6 +759,15 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set,
     TRACE("%p, %s, %s, %d\n", set, debugstr_guid(class),
         debugstr_w(instanceid), phantom);
 
+    LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
+    {
+        if (!strcmpiW(instanceid, device->instanceId))
+        {
+            TRACE("Found device %p already in set.\n", device);
+            return device;
+        }
+    }
+
     if (!(device = heap_alloc_zero(sizeof(*device))))
     {
         SetLastError(ERROR_OUTOFMEMORY);
@@ -788,6 +798,8 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set,
     SETUPDI_GuidToString(class, guidstr);
     SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_CLASSGUID,
         (const BYTE *)guidstr, sizeof(guidstr));
+
+    TRACE("Created new device %p.\n", device);
     return device;
 }
 
@@ -1620,7 +1632,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const
         }
     }
 
-    if (!(device = SETUPDI_CreateDeviceInfo(set, class, id, TRUE)))
+    if (!(device = create_device(set, class, id, TRUE)))
         return FALSE;
 
     if (description)
@@ -2196,8 +2208,7 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet,
                                 deviceClassStr[37] = 0;
                                 UuidFromStringW(&deviceClassStr[1],
                                         &deviceClass);
-                                if ((device = SETUPDI_CreateDeviceInfo(set,
-                                        &deviceClass, deviceInst, FALSE)))
+                                if ((device = create_device(set, &deviceClass, deviceInst, FALSE)))
                                     SETUPDI_AddDeviceInterfaces(device, subKey, guid, flags);
                             }
                             RegCloseKey(deviceKey);
@@ -2318,7 +2329,7 @@ static void SETUPDI_EnumerateMatchingDeviceInstances(struct DeviceInfoSet *set,
                             if (snprintfW(id, ARRAY_SIZE(id), fmt, enumerator,
                                     deviceName, deviceInstance) != -1)
                             {
-                                SETUPDI_CreateDeviceInfo(set, &deviceClass, id, FALSE);
+                                create_device(set, &deviceClass, id, FALSE);
                             }
                         }
                     }
@@ -3398,7 +3409,7 @@ BOOL WINAPI SetupDiOpenDeviceInfoW(HDEVINFO devinfo, PCWSTR instance_id, HWND hw
                                    PSP_DEVINFO_DATA device_data)
 {
     struct DeviceInfoSet *set;
-    struct device *device = NULL, *enum_device;
+    struct device *device;
     WCHAR classW[40];
     GUID guid;
     HKEY enumKey = NULL;
@@ -3448,17 +3459,7 @@ BOOL WINAPI SetupDiOpenDeviceInfoW(HDEVINFO devinfo, PCWSTR instance_id, HWND hw
         goto done;
     }
 
-    /* If current set already contains a same instance, don't create new ones */
-    LIST_FOR_EACH_ENTRY(enum_device, &set->devices, struct device, entry)
-    {
-        if (!strcmpiW(instance_id, enum_device->instanceId))
-        {
-            device = enum_device;
-            break;
-        }
-    }
-
-    if (!device && !(device = SETUPDI_CreateDeviceInfo(set, &guid, instance_id, FALSE)))
+    if (!(device = create_device(set, &guid, instance_id, FALSE)))
         goto done;
 
     if (!device_data || device_data->cbSize == sizeof(SP_DEVINFO_DATA))
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 09cd7ae..f266592 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -2933,7 +2933,6 @@ todo_wine {
     ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
     check_device_list(set, &GUID_NULL);
     check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\FOO");
-todo_wine
     check_device_info(set, 1, NULL, NULL);
     check_device_iface(set, NULL, &iface_guid, 0, 0, "\\\\?\\root#legacy_bogus#foo#{deadbeef-3f65-11db-b704-0011955c2bdb}");
     check_device_iface(set, NULL, &iface_guid, 1, 0, NULL);
@@ -2980,7 +2979,6 @@ todo_wine {
     ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
     check_device_list(set, &GUID_NULL);
     check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\FOO");
-todo_wine
     check_device_info(set, 1, NULL, NULL);
     check_device_iface(set, NULL, &iface_guid, 0, 0, "\\\\?\\root#legacy_bogus#foo#{deadbeef-3f65-11db-b704-0011955c2bdb}");
     check_device_iface(set, NULL, &iface_guid, 1, 0, NULL);




More information about the wine-cvs mailing list