Using IRP Completion Routines

Note

For optimal reliability and performance, use file system minifilter drivers with Filter Manager support instead of legacy file system filter drivers. 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:

NTSTATUS
(*PIO_COMPLETION_ROUTINE) (
    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