[PATCH 3/6] wineboot: Create a root-enumerated device object for winebus.

Zebediah Figura z.figura12 at gmail.com
Thu Jun 27 22:30:14 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
There does not seem to be a way to trigger root PnP device installation from
e.g. an INF file [in particular, InstallHinfSection() will not install root
PnP devices].

 programs/wineboot/Makefile.in |  2 +-
 programs/wineboot/wineboot.c  | 55 +++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index f6da0f9df65..42ae420cebc 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -1,7 +1,7 @@
 MODULE    = wineboot.exe
 APPMODE   = -mconsole
 IMPORTS   = uuid advapi32
-DELAYIMPORTS = shell32 shlwapi version user32
+DELAYIMPORTS = shell32 shlwapi version user32 setupapi newdev
 
 C_SRCS = \
 	shutdown.c \
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index defd12627d6..4b5ec738bc9 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -82,6 +82,8 @@
 #include <shobjidl.h>
 #include <shlwapi.h>
 #include <shellapi.h>
+#include <setupapi.h>
+#include <newdev.h>
 #include "resource.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
@@ -1090,6 +1092,57 @@ static HANDLE start_rundll32( const char *inf_path, BOOL wow64 )
     return pi.hProcess;
 }
 
+static void install_root_pnp_devices(void)
+{
+    static const struct
+    {
+        const char *name;
+        const char *hardware_id;
+        const char *infpath;
+    }
+    root_devices[] =
+    {
+        {"root\\wine\\winebus", "root\\winebus\0", "C:\\windows\\inf\\winebus.inf"},
+    };
+    SP_DEVINFO_DATA device = {sizeof(device)};
+    unsigned int i;
+    HDEVINFO set;
+
+    if ((set = SetupDiCreateDeviceInfoList( NULL, NULL )) == INVALID_HANDLE_VALUE)
+    {
+        WINE_ERR("Failed to create device info list, error %#x.\n", GetLastError());
+        return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(root_devices); ++i)
+    {
+        if (!SetupDiCreateDeviceInfoA( set, root_devices[i].name, &GUID_NULL, NULL, NULL, 0, &device))
+        {
+            if (GetLastError() != ERROR_DEVINST_ALREADY_EXISTS)
+                WINE_ERR("Failed to create device %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError());
+            continue;
+        }
+
+        if (!SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_HARDWAREID,
+                (const BYTE *)root_devices[i].hardware_id, (strlen(root_devices[i].hardware_id) + 2) * sizeof(WCHAR)))
+        {
+            WINE_ERR("Failed to set hardware id for %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError());
+            continue;
+        }
+
+        if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device))
+        {
+            WINE_ERR("Failed to register device %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError());
+            continue;
+        }
+
+        if (!UpdateDriverForPlugAndPlayDevicesA(NULL, root_devices[i].hardware_id, root_devices[i].infpath, 0, NULL))
+            WINE_ERR("Failed to install drivers for %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError());
+    }
+
+    SetupDiDestroyDeviceInfoList(set);
+}
+
 /* execute rundll32 on the wine.inf file if necessary */
 static void update_wineprefix( BOOL force )
 {
@@ -1133,6 +1186,8 @@ static void update_wineprefix( BOOL force )
             }
             DestroyWindow( hwnd );
         }
+        install_root_pnp_devices();
+
         WINE_MESSAGE( "wine: configuration in '%s' has been updated.\n", config_dir );
     }
 
-- 
2.22.0




More information about the wine-devel mailing list