15.1.2 Releasing Device and Controller Objects

Any NT driver must release its references to external resources, such as pointers to other drivers’ objects and/or to interrupt objects, that it stored in a device or controller extension before it deletes the corresponding device or controller object.

After it has freed all resources associated with a device or controller object, the Unload routine must call IoDeleteDevice for each device object that the driver created with successful calls to IoCreateDevice, and it must call IoDeleteController if the DriverEntry routine called IoCreateController.

Any Kernel-defined object for which the driver provides storage in a device extension is automatically freed when the Unload routine calls IoDeleteDevice with the corresponding device object. In general, any object that the DriverEntry routine set up by calling KeInitializeXxx can be freed by a call to IoDeleteDevice if the driver provided storage for that object in its device extension. For example, if a driver has a CustomTimerDpc routine and has provided storage for the necessary DPC and timer objects in its device extension, the call to IoDeleteDevice releases these system resources.

In a similar manner, any Kernel-defined object for which the driver provides storage in a controller extension is automatically freed when the Unload routine calls IoDeleteController with the corresponding controller object.