Completing the IRP
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.
Every dispatch routine receives a pointer to the IRP's target device object in its DeviceObject parameter. If the legacy filter driver has a control device object (CDO), the dispatch routine should check whether DeviceObject points to the filter driver's CDO before performing any processing on the IRP.
File system filter drivers aren't required to support any I/O operations that are sent specifically to the CDO. (For more information about commonly supported operations, see The Filter Driver's Control Device Object.) However, the CDO must complete every IRP that is sent to it.
To complete an IRP, a dispatch routine must perform all of the following steps:
Set Irp->IoStatus.Status to an appropriate NTSTATUS value.
Call IoCompleteRequest to return the IRP to the I/O Manager.
Return the same status value as in step 1 to the caller.
Completing an IRP is sometimes referred to as "succeeding" or "failing" the IRP:
Succeeding an IRP means to complete it with a success or informational NTSTATUS value such as STATUS_SUCCESS.
Failing an IRP means to complete it with an error or warning NTSTATUS value such as STATUS_INVALID_DEVICE_REQUEST or STATUS_BUFFER_OVERFLOW.
NTSTATUS values are defined in ntstatus.h. These values fall into four categories: success, informational, warning, and error. For more information, see Using NTSTATUS Values.
Although STATUS_PENDING is a success NTSTATUS value, it's a programming error to complete an IRP with STATUS_PENDING.