The input parameter to an Unload routine is a DriverObject pointer, as shown by the declaration, to the driver object that the NT I/O Manager uses to represent that driver’s load image.
Every NT driver’s calls to IoCreateDevice require the DriverObject pointer that was input to its DriverEntry routine. Each successful call to IoCreateDevice associates the newly created device object with the given driver object.
Consequently, an NT driver’s Unload routine can walk the chain of device objects associated with the input DriverObject to release the resources and objects that driver was using.
Consider the following implementation guidelines for the Unload routines of NT drivers
While the NT I/O Manager does not continue to send IRPs to any driver after its Unload routine has been called, disabling interrupts from the device should be the first thing done by any device driver’s Unload routine if possible. Otherwise, its ISR might be called to handle a device interrupt while the Unload routine is executing and releasing resources in the device extension that the ISR needs to handle the interrupt. Note that even if its ISR runs successfully in these circumstances, the DpcForIsr or CustomDpc routine that the ISR queues, and possibly other driver routines that run at IRQL >= DISPATCH_LEVEL, will execute before the Unload routine regains control, thereby increasing the likelihood that the Unload routine has deleted a resource that another driver routine references. For more information about managing IRQLs in NT drivers, see Chapter 16.
Any Unload routine must release the resources an NT driver is using in stages. However, the specifics of how any particular NT driver uses the registry, sets up system objects and resources in its device extension(s), in any controller extension, or in driver-allocated nonpaged pool varies from driver to driver.
A DriverEntry and Unload routine can sometimes share internal driver routines that set up necessary parameters to allocate and release resources. For example, a driver that sets up symbolic links between Win32®-visible names and the corresponding NT device object names for its devices might have a common routine to construct Unicode string paths to the registry keys in the \Registry..\DeviceMap tree where it stores configuration information about these aliases.
In general, an NT driver’s Unload routine releases all driver-allocated resources in the following stages:
For more information about releasing hardware resource claims in the registry, see Chapter 16. For specific information about IoAssignResources and IoReportResourceUsage, see the Kernel-Mode Driver Reference.
The Unload routine should remove any names for its devices that the DriverEntry routine stored in the registry under the \Registry..\DeviceMap tree, as well.
If the DriverEntry routine called IoGetConfigurationInformation to increment the count for a particular type of device, the Unload routine also must call IoGetConfigurationInformation and decrements the count for its devices in the I/O Manager’s global configuration information structure as it deletes the corresponding device objects.
In effect, an Unload routine must undo whatever the corresponding DriverEntry and Reinitialize, if any, routine(s) did to initialize its physical device(s), if any. An Unload routine must undo whatever the corresponding DriverEntry and Reinitialize, if any, routine(s) did to allocate the resources the driver needed to remain loaded and process IRPs.
Before it returns control, an Unload routine also is responsible for freeing any other driver-allocated resources that have not yet been freed by other driver routines.