The InstallSelectedDriver function installs the selected driver on the selected device in the Windows DDK (889763)



The information in this article applies to:

  • Microsoft Windows 2000 Driver Development Kit (DDK)
  • Microsoft Windows XP Driver Development Kit (DDK)
  • Microsoft Windows Server 2003 Driver Development Kit (DDK)

SUMMARY

This article includes documentation for the InstallSelectedDriver function. The InstallSelectedDriver function installs the selected driver on the selected device. 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.

INTRODUCTION

In the Microsoft Windows Driver Development Kit (DDK), the InstallSelectedDriver function installs the selected driver on the selected device.

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;
}

Modification Type:MinorLast Reviewed:2/10/2006
Keywords:kbinfo KB889763 kbAudDeveloper