Signed-off-by: Zebediah Figura z.figura12@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 ); }