Releasing Driver-Allocated Resources

The specifics of how a driver uses the registry, sets up system objects and resources in its device extensions, controller extension, or driver-allocated nonpaged pool varies from driver to driver. However, any Unload routine must release the resources a driver is using in stages.

Any driver's Unload routine must ensure that no other driver routine is currently using or might shortly be using a particular resource before it releases that resource.

In general, an Unload routine releases all driver-allocated resources in the following stages:

  1. If the driver has not already done so, disable interrupts on any physical devices, if possible, and then call IoDisconnectInterrupt as soon as interrupts are disabled.

  2. Ensure that no other driver routine can reference the resources that the Unload routine intends to release.

    For example, an Unload routine must call IoStopTimer if the driver's IoTimer routine is currently enabled for a particular device object. It must ensure that no thread is waiting for any of the driver's dispatcher objects and that its timer objects are not queued for calls to its CustomTimerDpc routines before it frees the storage for its dispatcher objects. It must call KeRemoveQueueDpc if it has a CustomDpc routine that the ISR might have queued, and so on.

    If the driver called IoQueueWorkItem, it must ensure that the work item has completed. IoQueueWorkItem takes out a reference on the associated device object; the driver cannot be unloaded if any such references remain.

    If the driver called PsCreateSystemThread, the Unload routine also must cause the driver-created thread to be run so that the thread itself can call PsTerminateSystemThread before the driver is unloaded. A driver cannot release a driver-created system thread by calling ZwClose with the ThreadHandle returned by PsCreateSystemThread.

  3. Release any device-specific resources that the driver allocated. Doing so might involve calling the following system support routines:

  4. Release system objects and resources that the DriverEntry or Reinitialize routine set up in the device extension of the device objects or in the controller extension of the controller object (if it created one). In particular, the driver must do the following before it attempts to delete the device object (IoDeleteDevice) or controller object (IoDeleteController):

  5. Free the hardware resources that the DriverEntry or Reinitialize routine claimed for the driver's physical devices, if any, in the registry under the \Registry\Machine\Hardware\ResourceMap tree.

  6. Remove any names for its devices that the DriverEntry or Reinitialize routine stored in the registry under the \Registry..\DeviceMap tree, as well.

After the driver has released device, system, and hardware resources, it can delete its device and controller objects, as described in Releasing Device and Controller Objects.