Zebediah Figura : newdev: Implement UpdateDriverForPlugAndPlayDevices().
Alexandre Julliard
julliard at winehq.org
Wed May 29 15:50:37 CDT 2019
Module: wine
Branch: master
Commit: 85ff60bb7d3d27673843afc0cec00b6dcb616623
URL: https://source.winehq.org/git/wine.git/?a=commit;h=85ff60bb7d3d27673843afc0cec00b6dcb616623
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Tue May 28 19:14:14 2019 -0500
newdev: Implement UpdateDriverForPlugAndPlayDevices().
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/newdev/Makefile.in | 1 +
dlls/newdev/main.c | 97 ++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/dlls/newdev/Makefile.in b/dlls/newdev/Makefile.in
index 728dea3..c447a38 100644
--- a/dlls/newdev/Makefile.in
+++ b/dlls/newdev/Makefile.in
@@ -1,4 +1,5 @@
MODULE = newdev.dll
IMPORTLIB = newdev
+IMPORTS = setupapi
C_SRCS = main.c
diff --git a/dlls/newdev/main.c b/dlls/newdev/main.c
index b1a5ccf..108aec0 100644
--- a/dlls/newdev/main.c
+++ b/dlls/newdev/main.c
@@ -1,5 +1,5 @@
/*
- * NewDev
+ * New Device installation API
*
* Copyright 2003 Ulrich Czekalla
*
@@ -25,12 +25,14 @@
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
+#include "cfgmgr32.h"
#include "newdev.h"
-#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/unicode.h"
-WINE_DEFAULT_DEBUG_CHANNEL(newdev);
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
/***********************************************************************
* InstallNewDevice (NEWDEV.@)
@@ -53,21 +55,96 @@ BOOL WINAPI InstallSelectedDriver(HWND parent, HDEVINFO info, const WCHAR *reser
/***********************************************************************
* UpdateDriverForPlugAndPlayDevicesA (NEWDEV.@)
*/
-BOOL WINAPI UpdateDriverForPlugAndPlayDevicesA(HWND hwndParent, LPCSTR HardwareId,
- LPCSTR FullInfPath, DWORD InstallFlags, PBOOL bRebootRequired OPTIONAL)
+BOOL WINAPI UpdateDriverForPlugAndPlayDevicesA(HWND parent, const char *hardware_id,
+ const char *inf_path, DWORD flags, BOOL *reboot)
{
- FIXME("Stub! %s %s 0x%08x\n", HardwareId, FullInfPath, InstallFlags);
- return TRUE;
+ WCHAR hardware_idW[MAX_DEVICE_ID_LEN];
+ WCHAR inf_pathW[MAX_PATH];
+
+ MultiByteToWideChar(CP_ACP, 0, hardware_id, -1, hardware_idW, ARRAY_SIZE(hardware_idW));
+ MultiByteToWideChar(CP_ACP, 0, inf_path, -1, inf_pathW, ARRAY_SIZE(inf_pathW));
+
+ return UpdateDriverForPlugAndPlayDevicesW(parent, hardware_idW, inf_pathW, flags, reboot);
}
+static BOOL hardware_id_matches(const WCHAR *id, const WCHAR *device_ids)
+{
+ while (*device_ids)
+ {
+ if (!strcmpW(id, device_ids))
+ return TRUE;
+ device_ids += strlenW(device_ids) + 1;
+ }
+ return FALSE;
+}
/***********************************************************************
* UpdateDriverForPlugAndPlayDevicesW (NEWDEV.@)
*/
-BOOL WINAPI UpdateDriverForPlugAndPlayDevicesW(HWND hwndParent, LPCWSTR HardwareId,
- LPCWSTR FullInfPath, DWORD InstallFlags, PBOOL bRebootRequired OPTIONAL)
+BOOL WINAPI UpdateDriverForPlugAndPlayDevicesW(HWND parent, const WCHAR *hardware_id,
+ const WCHAR *inf_path, DWORD flags, BOOL *reboot)
{
- FIXME("Stub! %s %s 0x%08x\n", debugstr_w(HardwareId), debugstr_w(FullInfPath), InstallFlags);
+ SP_DEVINSTALL_PARAMS_W params = {sizeof(params)};
+ SP_DEVINFO_DATA device = {sizeof(device)};
+ WCHAR *device_ids = NULL;
+ DWORD size = 0, i, j;
+ HDEVINFO set;
+
+ static const DWORD dif_list[] =
+ {
+ DIF_SELECTBESTCOMPATDRV,
+ DIF_ALLOW_INSTALL,
+ DIF_INSTALLDEVICEFILES,
+ DIF_REGISTER_COINSTALLERS,
+ DIF_INSTALLINTERFACES,
+ DIF_INSTALLDEVICE,
+ DIF_NEWDEVICEWIZARD_FINISHINSTALL,
+ };
+
+ TRACE("parent %p, hardware_id %s, inf_path %s, flags %#x, reboot %p.\n",
+ parent, debugstr_w(hardware_id), debugstr_w(inf_path), flags, reboot);
+
+ if (flags)
+ FIXME("Unhandled flags %#x.\n", flags);
+
+ if (reboot) *reboot = FALSE;
+
+ if ((set = SetupDiGetClassDevsW(NULL, NULL, 0, DIGCF_ALLCLASSES)) == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i)
+ {
+ if (!SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, (BYTE *)device_ids, size, &size))
+ {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ continue;
+ device_ids = heap_realloc(device_ids, size);
+ SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, (BYTE *)device_ids, size, NULL);
+ }
+
+ if (!hardware_id_matches(hardware_id, device_ids))
+ continue;
+
+ if (!SetupDiGetDeviceInstallParamsW(set, &device, ¶ms))
+ continue;
+
+ strcpyW(params.DriverPath, inf_path);
+ params.Flags |= DI_ENUMSINGLEINF;
+ if (!SetupDiSetDeviceInstallParamsW(set, &device, ¶ms))
+ continue;
+
+ if (!SetupDiBuildDriverInfoList(set, &device, SPDIT_COMPATDRIVER))
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(dif_list); ++j)
+ {
+ if (!SetupDiCallClassInstaller(dif_list[j], set, &device) && GetLastError() != ERROR_DI_DO_DEFAULT)
+ break;
+ }
+ }
+
+ SetupDiDestroyDeviceInfoList(set);
+ heap_free(device_ids);
return TRUE;
}
More information about the wine-cvs
mailing list