Usually, NT drivers do not complete IRPs in their Dispatch routines unless the parameters for the given request are invalid or, in a device driver, unless the particular IRP_MJ_XXX requires no device I/O operation(s).
A higher-level NT driver should complete an IRP in its Dispatch routine(s) or pass it on for processing by lower drivers according to the following guidelines:
A cleanup request indicates that an application is being terminated or has closed a file handle for the file object that represents the driver’s device object. When the DispatchCleanup routine returns, usually the driver’s DispatchClose routine is called next.
Note that every NT driver in a chain of layered drivers can check the validity of parameters in its own I/O stack location of each IRP input to the driver’s Dispatch routines. In such a chain, each driver’s Dispatch routine can complete only those IRPs for which it can determine the validity of parameters in its own I/O stack location. Completing IRPs with invalid parameters in the Dispatch routine of the highest possible driver improves I/O throughput for any chain of NT drivers and for the system overall.
A lowest-level NT driver should complete an IRP in its Dispatch routine(s) according to the following guidelines:
Usually, any higher-level driver has already checked the parameters for a requested operation, but device drivers can perform their own “sanity checks” on parameters as well. However, device drivers do not check the parameters of IRP_MJ_INTERNAL_DEVICE_CONTROL requests because a closely coupled higher-level driver is responsible for setting up the parameters for these requests.
A cleanup request indicates that an application is being terminated or has closed a file handle for the file object that represents the driver’s device object. When the DispatchCleanup routine returns, usually the driver’s DispatchClose routine is called next. For more information about handling cancelable IRPs, see also Chapter 12.
For example, a driver might save the current mode of its device in the device extension, particularly if it seldom changes device modes after initialization. Its DispatchDeviceControl routine could then satisfy a request that queried the current device mode by returning this stored information.
Otherwise, the Dispatch routine must call IoMarkIrpPending with the IRP, queue the IRP to other driver routines for further processing, and return STATUS_PENDING.