MORE INFORMATION
The
InstallSelectedDriver function is included with Microsoft Windows 2000 and with later versions of the Windows operating system.
The
InstallSelectedDriver function retrieves the selected device by calling
the
SetupDiGetSelectedDevice function on the
DeviceInfoSet parameter. The
InstallSelectedDriver function then retrieves the
selected driver by calling the
SetupDiGetSelectedDriver function on the
DeviceInfoSet
parameter and on the selected device. Therefore, make sure that the
SetupDiSetSelectedDevice function is called on the related
SP_DEVINFO_DATA structure. Additionally, the
SetupDiSetSelectedDriver function must be called on the
related
SP_DRVINFO_DATA structure.
This
InstallSelectedDriver API is not present in any header
files. Therefore, callers must use this API by calling the
LoadLibrary
function on the Newdev.dll file and
by calling the
GetProcAddress
function on the
InstallSelectedDriver function.
Use the
InstallSelectedDriver function only if you want to target a specific driver to a specific
device. If you do not want to target a specific driver to a specific device, use the
UpdateDriverForPlugAndPlayDevices function
instead. The
UpdateDriverForPlugAndPlayDevices function installs the best driver in a
particular INF on all devices in the computer that match the specified
hardware ID.
If the
UpdateDriverForPlugAndPlayDevices function returns the ERROR_IN_WOW64 error value in a 32-bit
application, the 32-bit
application is running on a computer that is running a 64-bit version of Windows Server 2003. This is not
allowed.
The InstallSelectedDriver function
When the
InstallSelectedDriver function receives a
DeviceInfoSet parameter, the
InstallSelectedDriver function installs the selected driver on the selected device.
BOOL WINAPI
InstallSelectedDriver(
HWND hwndParent,
HDEVINFO DeviceInfoSet,
LPCWSTR Reserved,
BOOL Backup,
PDWORD pReboot
);
Parameters
- The hwndParent parameter is a caller-supplied handle to the top-level window. Use this parameter for
any user interface that is related to installing devices.
- The DeviceInfoSet parameter is a caller-supplied HDEVINFO handle. Use this parameter for a valid DeviceInfoSet parameter
that has a selected device that has a selected driver.
- The Reserved parameter must be null.
- The Backup parameter is a caller-supplied BOOL. Set this parameter to true if you want to back up the current driver. Otherwise, set this parameter to
false.
- The pReboot parameter is the address of a DWORD value that indicates whether you must restart the computer. If you must restart the computer, this DWORD pointer is set to DI_NEEDREBOOT.
Return value
The
InstallSelectedDriver function returns
true if a device was upgraded and
if no error was encountered. Otherwise, it returns
false, and the logged error can be retrieved with a call to the
GetLastError function.
Headers
The headers for the
InstallSelectedDriver function link to the Newdev.lib file.
Code sample
/* You can build the following code sample by using the following command-line arguments after you select the correct build environment, such as XP Checked:
cl -nologo -DUNICODE <SourceFile.cpp> -link setupapi.lib
NOTE: <SourceFile.cpp> represents the name of the source file.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <objbase.h>
#include <tchar.h>
#include <setupapi.h>
#include <strsafe.h>
#define SIZECHARS(x) (sizeof((x))/sizeof(TCHAR))
//
// The following is the prototype for the newdev!InstallSelectedDriver API.
//
typedef
BOOL
(*PINSTALLSELECTEDDRIVER)(
HWND hwndParent,
HDEVINFO DeviceInfoSet,
LPCWSTR Reserved,
BOOL Backup,
PDWORD pReboot
);
int
__cdecl
wmain(
IN int argc,
IN WCHAR *argv[]
)
{
DWORD Err = NO_ERROR;
HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
SP_DRVINFO_DATA DriverInfoData;
SP_DEVINSTALL_PARAMS DeviceInstallParams;
TCHAR NewDevPath[MAX_PATH];
HMODULE hNewDev = NULL;
PINSTALLSELECTEDDRIVER pInstallSelectedDriver = NULL;
DWORD Reboot;
//
// The command line will contain a device instance Id and a full
// path of an INF.
//
if (argc < 3) {
printf("Usage: iseldr \"device instance id\" \"full path to the INF file\"\n");
return ERROR_INVALID_PARAMETER;
}
printf("%ws\n", argv[1]);
printf("%ws\n", argv[2]);
//
// Create an empty device information list.
//
DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
Err = GetLastError();
goto clean0;
}
//
// Add the device that is referenced by the device instance id parameter
// to the device information list.
//
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
if (!SetupDiOpenDeviceInfo(DeviceInfoSet,
(PCWSTR)argv[1],
NULL,
0,
&DeviceInfoData)) {
Err = GetLastError();
goto clean0;
}
//
// InstallSelectedDriver works on the selected device and on the
// selected driver on that device. Therefore, set this device as the
// selected one in the device information list.
//
if (!SetupDiSetSelectedDevice(DeviceInfoSet,
&DeviceInfoData)) {
Err = GetLastError();
goto clean0;
}
//
// You now have a SP_DEVINFO_DATA structure
// representing your device. Next, get a SP_DRVINFO_DATA
// structure to install on that device.
//
DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
&DeviceInfoData,
&DeviceInstallParams)) {
Err = GetLastError();
goto clean0;
}
//
// Only build the driver list out of the passed-in INF.
// To do this, set the DI_ENUMSINGLEINF flag, and copy the
// full path of the INF into the DriverPath field of the
// DeviceInstallParams structure.
//
DeviceInstallParams.Flags |= DI_ENUMSINGLEINF;
if (FAILED(StringCchCopy(DeviceInstallParams.DriverPath,
SIZECHARS(DeviceInstallParams.DriverPath),
argv[2]))) {
//
// The file path that was passed in was too big.
//
Err = ERROR_INVALID_PARAMETER;
goto clean0;
}
//
// Set the DI_FLAGSEX_ALLOWEXCLUDEDDRVS flag so that you can use
// this INF even if it is marked as ExcludeFromSelect.
// ExcludeFromSelect means do not show the INF in the legacy Add
// Hardware Wizard.
//
DeviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
if (!SetupDiSetDeviceInstallParams(DeviceInfoSet,
&DeviceInfoData,
&DeviceInstallParams)) {
Err = GetLastError();
goto clean0;
}
//
// Build up a Driver Information List from the specified INF.
// Build a compatible driver list, meaning only include the
// driver nodes that match one of the hardware or compatible Ids of
// the device.
//
if (!SetupDiBuildDriverInfoList(DeviceInfoSet,
&DeviceInfoData,
SPDIT_COMPATDRIVER)) {
Err = GetLastError();
goto clean0;
}
//
// Pick the best driver in the list of drivers that was built.
//
if (!SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV,
DeviceInfoSet,
&DeviceInfoData)) {
Err = GetLastError();
goto clean0;
}
//
// Get the selected driver node.
// Note: If this list does not contain any drivers, this call
// will fail with ERROR_NO_DRIVER_SELECTED.
//
DriverInfoData.cbSize = sizeof(DriverInfoData);
if (!SetupDiGetSelectedDriver(DeviceInfoSet,
&DeviceInfoData,
&DriverInfoData)) {
Err = GetLastError();
goto clean0;
}
//
// At this point, you have a valid SP_DEVINFO_DATA structure and a
// valid SP_DRVINFO_DATA structure.
// Load newdev.dll, GetProcAddress(InstallSelectedDriver), and call
// that API.
//
// To be more secure, make sure to load the newdev.dll file from the
// system 32 directory.
//
if (GetSystemDirectory(NewDevPath, SIZECHARS(NewDevPath)) == 0) {
Err = GetLastError();
goto clean0;
}
if (FAILED(StringCchCat(NewDevPath, SIZECHARS(NewDevPath), TEXT("\\NEWDEV.DLL")))) {
Err = ERROR_INSUFFICIENT_BUFFER;
goto clean0;
}
hNewDev = LoadLibrary(NewDevPath);
if (!hNewDev) {
Err = GetLastError();
goto clean0;
}
pInstallSelectedDriver = (PINSTALLSELECTEDDRIVER)GetProcAddress(hNewDev, "InstallSelectedDriver");
if (!pInstallSelectedDriver) {
Err = GetLastError();
goto clean0;
}
//
// Call pInstallSelectedDriver to install the selected driver on
// the selected device.
//
pInstallSelectedDriver(NULL,
DeviceInfoSet,
NULL,
TRUE,
&Reboot);
if (Reboot & (DI_NEEDREBOOT | DI_NEEDRESTART)) {
//
// A reboot is required.
//
}
clean0:
if (hNewDev) {
FreeLibrary(hNewDev);
hNewDev = NULL;
}
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
DeviceInfoSet = INVALID_HANDLE_VALUE;
}
printf("iseldrv returned 0x%X\n", Err);
return Err;
}