[PATCH v2 7/8] setupapi: Check registered device duplicate in SetupDiCreateDeviceInfo().

Zhiyi Zhang zzhang at codeweavers.com
Thu Mar 14 22:42:29 CDT 2019


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/setupapi/devinst.c       | 14 ++++++++++++++
 dlls/setupapi/tests/devinst.c |  6 +++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index cdad889212..ab7eeebe70 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -1510,6 +1510,8 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const
 {
     WCHAR id[MAX_DEVICE_ID_LEN];
     struct DeviceInfoSet *set;
+    HKEY enum_hkey;
+    HKEY instance_hkey;
     struct device *device;
 
     TRACE("devinfo %p, name %s, class %s, description %s, hwnd %p, flags %#x, device_data %p.\n",
@@ -1570,6 +1572,18 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const
     }
     else
     {
+        /* Check if instance is already in registry */
+        RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0, KEY_READ, NULL, &enum_hkey, NULL);
+        if (!RegOpenKeyExW(enum_hkey, name, 0, KEY_READ, &instance_hkey))
+        {
+            RegCloseKey(instance_hkey);
+            RegCloseKey(enum_hkey);
+            SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
+            return FALSE;
+        }
+        RegCloseKey(enum_hkey);
+
+        /* Check if instance is already in set */
         strcpyW(id, name);
         LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
         {
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 01891b16c2..2355f30a35 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -358,9 +358,9 @@ static void test_device_info(void)
 
     set = SetupDiCreateDeviceInfoList(&guid, NULL);
     ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device);
-    todo_wine ok(!ret, "Expect failure\n");
-    todo_wine ok(GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, "Got error %#x\n", GetLastError());
-    todo_wine check_device_info(set, 0, NULL, NULL);
+    ok(!ret, "Expect failure\n");
+    ok(GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, "Got error %#x\n", GetLastError());
+    check_device_info(set, 0, NULL, NULL);
     SetupDiDestroyDeviceInfoList(set);
 
     set = SetupDiGetClassDevsA(&guid, NULL, NULL, 0);
-- 
2.19.2





More information about the wine-devel mailing list