Writing a Device Installation ApplicationIf your driver package includes drivers and INF files that replace "in-box" drivers and INF files, or if your package includes device
-specific applications, it should include a device
installation application that installs those components. The device installation application should be invoked by Autorun (described in Platform SDK documentation), so that it starts automatically when a user inserts your distribution disk.
Your driver package must handle two situations:
- The user plugs in your hardware before inserting your distribution medium.
- The user inserts your distribution medium before plugging in your hardware.
User Plugs in Hardware Before Inserting Distribution MediumIf the user plugs in new hardware before inserting your distribution medium into a drive, there are two scenarios to deal with:
- System-supplied in-box drivers support the device. In this case, Setup automatically installs the device based on INF files and drivers stored on the system disk. The system will not ask the user to insert vendor-supplied distribution media, so if you have provided a distribution medium containing device-specific applications, the applications are not installed at this time.
- System-supplied in-box drivers do not support the device. In this case the Found New Hardware wizard starts executing and asks the user for a distribution medium. When the user inserts the medium, the Autorun-invoked device installation application checks for in-progress installations. Because the Found New Hardware wizard is active, the device installation application should stop itself. The wizard can then search the medium for an appropriate INF file. You can provide a co-installer that installs device-specific applications, as described in Installing Device-Specific Applications.
In either of these cases, the system will also attempt to access the Windows Update Web site to see if newer drivers and INF files are available. If they are, these drivers and INFs will be used instead of those already on the system or on the distribution medium. If the Web site is inaccessible or if no new drivers are available there, the system uses the drivers and INFs available in-box or on the distribution medium (whichever are newer).
Your distribution medium can contain an Autorun-invoked device installation application. When the user inserts your distribution medium, this application will start automatically. Assuming the user inserts the medium after the device has been plugged in and installed, the device installation application can do either or both of the following:
- If the system installed the device using in-box drivers, the device installation application can reinstall the device using drivers and INF files supplied on the distribution medium, using UpdateDriverForPlugAndPlayDevices.
- If the distribution medium contains device-specific applications, and a co-installer didn't install those applications in response to a DIF_NEWDEVICEWIZARD_FINISHINSTALL function code, the device installation application can use Microsoft? Installer to install them. (Microsoft Installer is described in Platform SDK documentation.)
User Inserts Distribution Medium Before Plugging in HardwareIf the user inserts your distribution medium before plugging in the hardware, an Autorun-invoked device installation application on the medium can:
- Check for in-progress installations, and stop executing if other installation activities are in progress.
- "Preinstall" driver files and INFs (see Pre-installing Driver Files).
- Use Microsoft Installer to install device-specific applications.
- If the device is "hot-pluggable," tell the user to plug it in. (If the bus doesn't provide hot-plug notification, initiate reenumeration by calling CM_Reenumerate_DevNode.)
- If the device is not hot-pluggable, tell the user to turn the system off, plug in the device, and turn the system back on.
Determining Whether the Device Is Plugged InNote that the behavior of an Autorun-invoked device installation application must depend on whether the user plugs in the hardware first or inserts the distribution medium first. Since vendors typically provide one distribution disk, and a disk can only have one Autorun-invoked application, your Autorun-invoked device installation application must determine if your device has been plugged in.
To determine if a device is plugged in, the application can call the
UpdateDriverForPlugAndPlayDevices function, passing the hardware ID of the device. The device is plugged in if:
- the function returns TRUE. (This also installs the driver for the device.)
- the function returns FALSE and the Win32 GetLastError function returns NO_ERROR. (No installation occurs.)
The device is not plugged in if the function returns FALSE and
GetLastError returns NO_SUCH_DEVINST. (No installation occurs.)
Reinstalling an Unplugged DeviceWhen a device that formerly was attached has been unplugged, the device's devnode remains in the system, although it is both inactive and hidden. Before you can reinstall such a device, you must first find this "phantom" devnode, and mark it as needing reinstallation. Then, when the device is plugged back in, Plug and Play will reenumerate the device, find the new driver for it, and install the driver for the device.
To reinstall an unplugged device: - Call the SetupCopyOEMInf function (described in the Platform SDK documentation). The SetupCopyOEMInf function ensures that the correct INF file is present in the %windir%\inf directory.
- Find the unplugged devices. Call the SetupDiGetClassDevs function. In the call to this function, clear the DIGCF_PRESENT flag in the Flags parameter. You need to find all devices, not just those that are present. You can narrow the results of your search by specifying the particular device class in the ClassGuid parameter.
- Find the hardware IDs and compatible IDs of unplugged devices. SetupDiGetClassDevs returns a handle to the device information set that contains all installed devices, whether plugged in or not, in the device class (assuming that you specified a device class in the first step). By making successive calls to the SetupDiEnumDeviceInfo function, you can use this handle to enumerate all of the devices in the device information set. Each call provides you with an SP_DEVINFO_DATA structure for the device. To get the list of hardware IDs, call the SetupDiGetDeviceRegistryProperty function with the Property parameter set to SPDRP_HARDWAREID. To get the list of the compatible IDs, call the same function, but with the Property parameter set to SPDRP_COMPATIBLEIDS. Both lists are MULTI-SZ strings.
- Look for a match between the ID of your device and the hardware IDs (or compatible IDs) of the previous step. Make sure that you perform full string comparisons between the hardware ID/compatible ID and the ID for your device. A partial comparison can lead to inappropriate matches.
When you find a match, call the CM_Get_DevNode_Status function, passing SP_DRVINFO_DATA.DevInst in the dnDevInst parameter. If this function returns CR_NO_SUCH_DEVINST, that confirms that the device is unattached (that is, has a phantom devnode).
- Mark the device. Call the SetupDiGetDeviceRegistryProperty function with the Property parameter set to SPDRP_CONFIGFLAGS. When this function returns, the PropertyBuffer parameter points to the device's ConfigFlags value from the registry. Perform a bitwise OR of this value with CONFIGFLAG_REINSTALL (defined in regstr.h). After doing this, call the SetupDiSetDeviceRegistryProperty function, passing SPDRP_CONFIGFLAGS. This action modifies the registry's ConfigFlags value to incorporate the CONFIGFLAG_REINSTALL flag. This causes the device to be reinstalled the next time the device is reenumerated.
- Plug in the device. Plug and Play will reenumerate the device, find the new driver for it, and install that driver.
Pre-installing Driver FilesTo preinstall driver files, your device installation application should follow these steps:
- On the target system, create a directory for the driver files. If your device installation application installs an application, the driver files should be stored in a subdirectory of the application directory.
- Copy all files in the driver package from the distribution media to the directory created in Step 1. The driver package includes the driver or drivers, the INF file, the catalog file, and so forth.
- Call SetupCopyOEMInf (described in Platform SDK documentation), specifying the INF file in the directory created in Step 1. Specify SPOST_PATH for the OEMSourceMediaType parameter and specify NULL for the OEMSourceMediaLocation parameter. SetupCopyOEMInf copies the INF file for the driver package into the %windir%\Inf directory on the target system and directs SetupAPI to store the source location of the INF file in its list of preprocessed INF files. SetupCopyOEMInf also processes the catalog file, so the PnP Manager will install the driver the next time it recognizes a device listed in the INF file.
When the user plugs in the device, the PnP Manager recognizes the device, finds the INF file copied by
SetupCopyOEMInf, and installs the drivers copied in Step 2. (For more information about copying INF files, see
Copying INFs.)
Installing Device-Specific ApplicationsIf your distribution medium includes device-specific applications, the medium should include two methods for installing those applications:
- A device-specific co-installer that installs the device-specific applications when it receives the DIF_NEWDEVICEWIZARD_FINISHINSTALL function code. If the user plugs in the device before inserting the distribution medium, and the device is not supported by in-box drivers, Setup calls the co-installer during the installation process. The co-installer should determine if the device-specific applications have already been installed and if they have not, it should install them. For more information, see Writing a Co-installer.
- A device installation application that uses Windows Installer to install the device-specific applications. If the user inserts the distribution medium before plugging in the device, the medium's Autorun-invoked device installation application should determine if the device-specific applications have already been installed and if they have not, it should install them using Windows Installer. For more information, see the Platform SDK documentation.
Checking for In-Progress InstallationsIf your device installation application will be invoked by Autorun when the installation CD is inserted, there is another consideration. If your application is meant for use on Windows 2000 and later (but not Windows 95/98/Me), it should determine if other installation activities are in progress before performing its installations. To make this determination, the application should call
CMP_WaitNoPendingInstallEvents, typically with a zero time-out value. If the return value from this function indicates other installation activities are pending (for instance, the Found New Hardware wizard might be active), the device installation application should exit.
To make your device installation application compatible with platforms that don't support
CMP_WaitNoPendingInstallEvents, the application should include the following code:
[pre]BOOLIsDeviceInstallInProgress (VOID){ HMODULE hModule; CMP_WAITNOPENDINGINSTALLEVENTS_PROC pCMP_WaitNoPendingInstallEvents; hModule = GetModuleHandle(TEXT("setupapi.dll")); if(!hModule) { // Should never happen since we're linked to SetupAPI, but... return FALSE; } pCMP_WaitNoPendingInstallEvents = (CMP_WAITNOPENDINGINSTALLEVENTS_PROC)GetProcAddress(hModule, "CMP_WaitNoPendingInstallEvents"); if(!pCMP_WaitNoPendingInstallEvents) { // We're running on a release of the operating system that doesn't supply this function. // Trust the operating system to suppress Autorun when appropriate. return FALSE; } return (pCMP_WaitNoPendingInstallEvents(0) == WAIT_TIMEOUT);}int__cdecl_tmain(IN int argc, IN PTCHAR argv[]){ if(IsDeviceInstallInProgress()) { // // We don't want to start right now. Instead, our // device co-installer will invoke this application // (if necessary) during finish-install processing. // return -1; } . .}[/pre]Use of this code is based on the premise that if a platform doesn't support
CMP_WaitNoPendingInstallEvents, the platform does not invoke Autorun if installation activities are in progress. For a sample usage of this code, see the toaster installation package under the DDK's
src/general subdirectory.
Guidelines for Writing Device Installation ApplicationsDevice installation applications
must do the following:
- Support removal ("uninstall") of all device-specific applications that it installs. As part of that uninstall process, the device installation application should check to see if any associated devices are still present on the system and, if so, warn the user.
- Follow the guidelines for installing devices on 64-bit systems.
- List all installed applications in Add/Remove Programs, using Microsoft? Windows? Installer (MSI), so the user can uninstall them if desired.
- Follow the guidelines for Microsoft? Windows? applications. See the Microsoft Developer Network (MSDN) Web site for more information. (Submit device-specific applications to the appropriate Windows Logo program for software. See the MSDN Web site for more information.)
Device installation applications
must not do the following:
- Do not instruct the user to copy or overwrite any files, especially .inf and .sys files.
- Do not delete the installed driver files from the system during the uninstall operation, even if the hardware has been removed.
- Do not force any unnecessary system reboots. Reboots are generally not required for installing PnP devices or software applications. The UpdateDriverForPlugAndPlayDevices function's bRebootRequired parameter indicates the need for a reboot.
- Do not use "RunOnce" registry entries to spawn device installation applications, because this requires a system reboot.
- Do not use a device or class co-installer, or a class installer, to spawn a device installation application, because the state of the system during device installation cannot be guaranteed to be safe for installing software applications. Specifically, if the device installation application runs on the server side, the system will hang. (However, device installation applications can be spawned from within finish-install wizard pages supplied by class installers or co-installers.)
- Do not use the Startup Group to spawn device installation applications.
- Do not use win.ini entries to spawn device installation applications.
- Do not force the user to install any device-specific applications, unless the device will not operate without the application. Examples might include utilities for setting configurable keyboard keys or for setting a modem's country/region code, if an in-box application does not support such a capability.
Built on Friday, April 11, 2003