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