From 9732937171cfb05055b0ef8cb2d4fcf7efddf679 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 11 Feb 2016 03:20:33 +0100
Subject: [PATCH] setupapi: Handle the case that a full driver path is passed
 to SetupDiGetClassDevs.

---
 dlls/setupapi/devinst.c       | 26 ++++++++++++++++++++++++--
 dlls/setupapi/tests/devinst.c | 25 +++++++++++++++++++++++--
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 38d994e3a..846531343 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -2455,8 +2455,30 @@ static void SETUPDI_EnumerateDevices(HDEVINFO DeviceInfoSet, const GUID *class,
                     &enumStrKey);
             if (!l)
             {
-                SETUPDI_EnumerateMatchingDevices(DeviceInfoSet, enumstr,
-                        enumStrKey, class, flags);
+                WCHAR *bus, *device;
+                HKEY devKey;
+
+                if (!strchrW(enumstr, '\\'))
+                {
+                    SETUPDI_EnumerateMatchingDevices(DeviceInfoSet, enumstr,
+                                                     enumStrKey, class, flags);
+                }
+                else if ((bus = strdupW(enumstr)))
+                {
+                    device = strchrW(bus, '\\');
+                    *device++ = 0;
+
+                    l = RegOpenKeyExW(enumKey, enumstr, 0, KEY_READ, &devKey);
+                    if (!l)
+                    {
+                        SETUPDI_EnumerateMatchingDeviceInstances(DeviceInfoSet, bus, device,
+                                                                 devKey, class, flags);
+                        RegCloseKey(devKey);
+                    }
+
+                    HeapFree(GetProcessHeap(), 0, bus);
+                }
+
                 RegCloseKey(enumStrKey);
             }
         }
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index afb431f8d..332755190 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -1884,6 +1884,28 @@ static void test_device_interface_key(void)
     SetupDiDestroyDeviceInfoList(set);
 }
 
+static void testSetupDiGetClassDevsA(void)
+{
+    static GUID displayguid = {0x4d36e968, 0xe325, 0x11ce, {0xbf,0xc1,0x08,0x00,0x2b,0xe1,0x03,0x18}};
+    SP_DEVINFO_DATA devinfo;
+    DISPLAY_DEVICEA disp;
+    HDEVINFO set;
+    BOOL ret;
+
+    disp.cb = sizeof(disp);
+    ok(EnumDisplayDevicesA(NULL, 0, &disp, 0), "EnumDisplayDevices failed: %08x\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    set = SetupDiGetClassDevsA(&displayguid, disp.DeviceID, 0, 0);
+    ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", GetLastError());
+
+    devinfo.cbSize = sizeof(devinfo);
+    ret = SetupDiEnumDeviceInfo(set, 0, &devinfo);
+    ok(ret, "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError());
+
+    SetupDiDestroyDeviceInfoList(set);
+}
+
 static void test_device_install_params(void)
 {
     SP_DEVINFO_DATA device = {sizeof(device)};
@@ -1951,8 +1973,6 @@ static void test_device_install_params(void)
     ok(!params.FileQueue, "Got queue %p.\n", params.FileQueue);
     ok(!params.ClassInstallReserved, "Got class installer data %#lx.\n", params.ClassInstallReserved);
     ok(!strcasecmp(params.DriverPath, "C:\\windows"), "Got driver path %s.\n", params.DriverPath);
-
-    SetupDiDestroyDeviceInfoList(set);
 }
 
 #ifdef __i386__
@@ -2135,6 +2155,7 @@ START_TEST(devinst)
     test_registry_property_a();
     test_registry_property_w();
     test_get_inf_class();
+    testSetupDiGetClassDevsA();
     test_devnode();
     test_device_interface_key();
     test_device_install_params();
-- 
2.21.0

