[PATCH 6/9] setupapi: create device registry properties based on EnumDisplayDevice() data during initialization

Donat Enikeev donat at enikeev.net
Mon Apr 24 15:51:22 CDT 2017


Based on staging patches from: Michael Muller <michael at fds-team.de> and Sebastian Lackner <sebastian at fds-team.de> 

Signed-off-by: Donat Enikeev <donat at enikeev.net>
---
 dlls/setupapi/devinst.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 93 insertions(+), 5 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index ffb5fad..3f56a0c 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -39,6 +39,9 @@
 #include "winioctl.h"
 #include "rpc.h"
 #include "rpcdce.h"
+#include "objbase.h"
+#include "initguid.h"
+#include "devguid.h"
 
 #include "setupapi_private.h"
 
@@ -2035,6 +2038,93 @@ static void SETUPDI_AddDeviceInterfaces(SP_DEVINFO_DATA *dev, HKEY key,
     /* FIXME: find and add all the device's interfaces to the device */
 }
 
+static void create_enum_registry_keys(HKEY enumKey, DISPLAY_DEVICEW *disp)
+{
+    static const WCHAR device_instance_idW[] = {'0','0','0','0',0};
+    static const WCHAR device_driverW[] = {'%','s','\\','%','s',0};
+    static const WCHAR DriverDateDataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
+    HKEY devKey, intKey;
+    WCHAR displayGUIDW[39], driverW[(sizeof(device_instance_idW)+sizeof(displayGUIDW))/sizeof(WCHAR)+1];
+    WCHAR *hardwareIDW;
+    SYSTEMTIME systime;
+    FILETIME filetime;
+    DWORD disposition, size;
+    LONG l;
+
+    TRACE("%s\n", debugstr_w(disp->DeviceID));
+
+    l = RegCreateKeyExW(enumKey, disp->DeviceID, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS,
+                        NULL, &devKey, NULL);
+    if (l) return;
+
+    l = RegCreateKeyExW(devKey, device_instance_idW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS,
+                        NULL, &intKey, NULL);
+    if (!l)
+    {
+        StringFromGUID2(&GUID_DEVCLASS_DISPLAY, displayGUIDW, 39);
+        RegSetValueExW(intKey, ClassGUID, 0, REG_SZ, (BYTE*)displayGUIDW, 39*sizeof(WCHAR));
+        sprintfW(driverW, device_driverW, displayGUIDW, device_instance_idW);
+        RegSetValueExW(intKey, Driver, 0, REG_SZ, (BYTE*)driverW, strlenW(driverW)*sizeof(WCHAR));
+        RegSetValueExW(intKey, FriendlyName, 0, REG_SZ, (BYTE*)disp->DeviceString,
+            strlenW(disp->DeviceString)*sizeof(WCHAR));
+
+        size = (strlenW(disp->DeviceID) + 2) * sizeof(WCHAR);
+        if ((hardwareIDW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)))
+        {
+            strcpyW(hardwareIDW, disp->DeviceID); /* we need two \0 for REG_MULTI_SZ */
+            RegSetValueExW(intKey, HardwareId, 0, REG_MULTI_SZ, (BYTE *)hardwareIDW, size);
+            HeapFree(GetProcessHeap(), 0, hardwareIDW);
+        }
+        RegCloseKey(intKey);
+    }
+
+    RegCloseKey(devKey);
+
+    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ControlClass, 0, NULL, 0, KEY_ALL_ACCESS,
+                        NULL, &devKey, NULL);
+    if (l) return;
+
+    l = RegCreateKeyExW(devKey, driverW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS,
+                        NULL, &intKey, &disposition);
+    if (!l && disposition == REG_CREATED_NEW_KEY)
+    {
+        GetSystemTime(&systime);
+        if (SystemTimeToFileTime(&systime, &filetime))
+            RegSetValueExW(intKey, DriverDateDataW, 0, REG_BINARY, (BYTE *)&filetime, sizeof(filetime));
+    }
+
+    RegCloseKey(intKey);
+    RegCloseKey(devKey);
+}
+
+static LONG open_enum_key(HKEY *key)
+{
+    static BOOL initialized = FALSE;
+    DISPLAY_DEVICEW disp;
+    HKEY enumKey;
+    LONG l;
+    DWORD devnum = 0;
+
+    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0, KEY_ALL_ACCESS,
+                        NULL, &enumKey, NULL);
+    if (l) return l;
+
+    if (!initialized)
+    {
+        disp.cb = sizeof(disp);
+        while (EnumDisplayDevicesW(NULL, devnum, &disp, 0))
+        {
+            create_enum_registry_keys(enumKey, &disp);
+            devnum++;
+        }
+
+        initialized = TRUE;
+    }
+
+    *key = enumKey;
+    return ERROR_SUCCESS;
+}
+
 static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet,
         HKEY key, const GUID *guid, LPCWSTR enumstr)
 {
@@ -2046,8 +2136,7 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet,
 
     TRACE("%s\n", debugstr_w(enumstr));
 
-    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0, KEY_READ, NULL,
-            &enumKey, NULL);
+    l = open_enum_key(&enumKey);
     for (i = 0; !l; i++)
     {
         len = sizeof(subKeyName) / sizeof(subKeyName[0]);
@@ -2275,8 +2364,7 @@ static void SETUPDI_EnumerateDevices(HDEVINFO DeviceInfoSet, const GUID *class,
     TRACE("%p, %s, %s, %08x\n", DeviceInfoSet, debugstr_guid(class),
             debugstr_w(enumstr), flags);
 
-    l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0, KEY_READ, NULL,
-            &enumKey, NULL);
+    l = open_enum_key(&enumKey);
     if (enumKey != INVALID_HANDLE_VALUE)
     {
         if (enumstr)
@@ -2353,7 +2441,7 @@ HDEVINFO WINAPI SetupDiGetClassDevsExW(const GUID *class, PCWSTR enumstr, HWND p
         return INVALID_HANDLE_VALUE;
     }
     if (flags & unsupportedFlags)
-        WARN("unsupported flags %08x\n", flags & unsupportedFlags);
+        FIXME("unsupported flags %08x\n", flags & unsupportedFlags);
     if (deviceset)
         set = deviceset;
     else
-- 
2.7.4




More information about the wine-patches mailing list