Zebediah Figura : setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().

Alexandre Julliard julliard at winehq.org
Thu Aug 16 13:42:49 CDT 2018


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sun Jul 29 20:26:28 2018 -0500

setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().

This family of functions manipulates the "Device Parameters" subkey, not its
parent.

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

---

 dlls/setupapi/devinst.c       | 123 +++++++++++++-----------------------------
 dlls/setupapi/tests/devinst.c |  57 ++++++++++++++++++++
 2 files changed, 95 insertions(+), 85 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 8b97eb5..44d2cb9 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -76,6 +76,7 @@ static const WCHAR Enum[] = {'S','y','s','t','e','m','\\',
 				  'E','n','u','m',0};
 static const WCHAR DeviceDesc[] = {'D','e','v','i','c','e','D','e','s','c',0};
 static const WCHAR DeviceInstance[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
+static const WCHAR DeviceParameters[] = {'D','e','v','i','c','e',' ','P','a','r','a','m','e','t','e','r','s',0};
 static const WCHAR HardwareId[] = {'H','a','r','d','w','a','r','e','I','D',0};
 static const WCHAR CompatibleIDs[] = {'C','o','m','p','a','t','i','b','l','e','I','d','s',0};
 static const WCHAR Service[] = {'S','e','r','v','i','c','e',0};
@@ -2559,111 +2560,63 @@ static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface)
 /***********************************************************************
  *		SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
  */
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-        DWORD Reserved,
-        REGSAM samDesired,
-        HINF InfHandle,
-        PCWSTR InfSectionName)
+HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo,
+    SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved, REGSAM access,
+    HINF hinf, const WCHAR *section)
 {
-    struct DeviceInfoSet *set = DeviceInfoSet;
-    HKEY key = INVALID_HANDLE_VALUE, interfacesKey;
-    LONG l;
+    struct DeviceInfoSet *set = devinfo;
+    struct device_iface *iface;
+    HKEY refstr_key, params_key;
+    WCHAR *path;
+    LONG ret;
 
-    TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
-            samDesired, InfHandle, InfSectionName);
+    TRACE("%p %p %d %#x %p %s\n", devinfo, iface_data, reserved, access, hinf,
+        debugstr_w(section));
 
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
+    if (!devinfo || devinfo == INVALID_HANDLE_VALUE ||
             set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
     {
         SetLastError(ERROR_INVALID_HANDLE);
         return INVALID_HANDLE_VALUE;
     }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
-            !DeviceInterfaceData->Reserved)
+    if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
+            !iface_data->Reserved)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return INVALID_HANDLE_VALUE;
     }
-    if (InfHandle && !InfSectionName)
+    if (hinf && !section)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return INVALID_HANDLE_VALUE;
     }
-    if (!(l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, DeviceClasses, 0, NULL, 0,
-                    samDesired, NULL, &interfacesKey, NULL)))
-    {
-        HKEY parent;
-        WCHAR bracedGuidString[39];
 
-        SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid,
-                bracedGuidString);
-        if (!(l = RegCreateKeyExW(interfacesKey, bracedGuidString, 0, NULL, 0,
-                        samDesired, NULL, &parent, NULL)))
-        {
-            struct device_iface *ifaceInfo =
-                (struct device_iface *)DeviceInterfaceData->Reserved;
-            PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo);
-            PWSTR interfKeyName = HeapAlloc(GetProcessHeap(), 0,
-                    (lstrlenW(ifaceInfo->symlink) + 1) * sizeof(WCHAR));
-            HKEY interfKey;
-            WCHAR *ptr;
-
-            lstrcpyW(interfKeyName, ifaceInfo->symlink);
-            if (lstrlenW(ifaceInfo->symlink) > 3)
-            {
-                interfKeyName[0] = '#';
-                interfKeyName[1] = '#';
-                interfKeyName[3] = '#';
-            }
-            ptr = strchrW(interfKeyName, '\\');
-            if (ptr)
-                *ptr = 0;
-            l = RegCreateKeyExW(parent, interfKeyName, 0, NULL, 0,
-                    samDesired, NULL, &interfKey, NULL);
-            if (!l)
-            {
-                struct device *device = ifaceInfo->device;
+    iface = (struct device_iface *)iface_data->Reserved;
+    if (!(path = get_refstr_key_path(iface)))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return INVALID_HANDLE_VALUE;
+    }
 
-                l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ,
-                        (BYTE *)device->instanceId,
-                        (lstrlenW(device->instanceId) + 1) * sizeof(WCHAR));
-                if (!l)
-                {
-                    if (instancePath)
-                    {
-                        LONG l;
+    ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL,
+        &refstr_key, NULL);
+    heap_free(path);
+    if (ret)
+    {
+        SetLastError(ret);
+        return INVALID_HANDLE_VALUE;
+    }
 
-                        l = RegCreateKeyExW(interfKey, instancePath, 0, NULL, 0,
-                                samDesired, NULL, &key, NULL);
-                        if (l)
-                        {
-                            SetLastError(l);
-                            key = INVALID_HANDLE_VALUE;
-                        }
-                        else if (InfHandle)
-                            FIXME("INF section installation unsupported\n");
-                    }
-                }
-                else
-                    SetLastError(l);
-                RegCloseKey(interfKey);
-            }
-            else
-                SetLastError(l);
-            HeapFree(GetProcessHeap(), 0, interfKeyName);
-            HeapFree(GetProcessHeap(), 0, instancePath);
-            RegCloseKey(parent);
-        }
-        else
-            SetLastError(l);
-        RegCloseKey(interfacesKey);
+    ret = RegCreateKeyExW(refstr_key, DeviceParameters, 0, NULL, 0, access,
+        NULL, &params_key, NULL);
+    RegCloseKey(refstr_key);
+    if (ret)
+    {
+        SetLastError(ret);
+        return INVALID_HANDLE_VALUE;
     }
-    else
-        SetLastError(l);
-    return key;
+
+    return params_key;
 }
 
 /***********************************************************************
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 2bb8027..95d0dc4 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -1376,6 +1376,62 @@ static void test_devnode(void)
     SetupDiDestroyDeviceInfoList(set);
 }
 
+static void test_device_interface_key(void)
+{
+    const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\"
+        "{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"
+        "##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
+    SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
+    SP_DEVINFO_DATA devinfo = { sizeof(devinfo) };
+    HKEY parent, key, dikey;
+    char buffer[5];
+    HDEVINFO set;
+    LONG sz, ret;
+
+    set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES);
+    ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
+
+    ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo);
+    ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
+
+    ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface);
+    ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError());
+
+    ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent);
+    ok(!ret, "failed to open device parent key: %u\n", ret);
+
+    ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+    ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
+
+    dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL);
+    ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
+
+    ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+    ok(!ret, "key should exist: %u\n", ret);
+
+    ret = RegSetValueA(key, NULL, REG_SZ, "test", 5);
+    sz = sizeof(buffer);
+    ret = RegQueryValueA(dikey, NULL, buffer, &sz);
+    ok(!ret, "RegQueryValue failed: %u\n", ret);
+    ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer);
+
+    RegCloseKey(dikey);
+    RegCloseKey(key);
+
+    ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0);
+todo_wine
+    ok(ret, "got error %u\n", GetLastError());
+
+    ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
+todo_wine
+    ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
+
+    RegCloseKey(parent);
+    SetupDiRemoveDeviceInterface(set, &iface);
+    SetupDiRemoveDevice(set, &devinfo);
+    SetupDiDestroyDeviceInfoList(set);
+}
+
 START_TEST(devinst)
 {
     HKEY hkey;
@@ -1414,4 +1470,5 @@ START_TEST(devinst)
     testDeviceRegistryPropertyW();
     testSetupDiGetINFClassA();
     test_devnode();
+    test_device_interface_key();
 }




More information about the wine-cvs mailing list