Module: wine Branch: master Commit: e2194b93b5a77a2e11700833223d4504dba738c1 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e2194b93b5a77a2e117008332...
Author: Zebediah Figura z.figura12@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@gmail.com Signed-off-by: Alexandre Julliard julliard@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);