Using IRP Completion Routines

Note For optimal reliability and performance, we recommend using file system minifilter drivers instead of legacy file system filter drivers. Also, legacy file system filter drivers can’t attach to direct access (DAX) volumes. For more about file system minifilter drivers, see Advantages of the Filter Manager Model. To port your legacy driver to a minifilter driver, see Guidelines for Porting Legacy Filter Drivers.

File system filter drivers use completion routines that are similar to those used by device drivers. A completion routine performs completion processing on an IRP. Any driver routine that passes an IRP down to the next-lower-level driver can optionally register a completion routine for the IRP by calling IoSetCompletionRoutine before calling IoCallDriver.

Every IRP completion routine is defined as follows:

    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 

Completion routines are called at IRQL <= DISPATCH_LEVEL, in an arbitrary thread context.

Because they can be called at IRQL DISPATCH_LEVEL, completion routines cannot call kernel-mode routines that must be called at a lower IRQL, such as IoDeleteDevice. For the same reason, any data structures that are used in a completion routine must be allocated from nonpaged pool.

This section discusses the following topics:

How Completion Processing Is Performed

Checking the PendingReturned Flag

Returning Status from Completion Routines

Example: Simple Pass-Through Dispatch and Completion

Constraints on Completion Routines