6.2.2 How to Complete an IRP in a Dispatch Routine
If an input IRP can be completed immediately, a Dispatch routine does the following:
1.Sets the Status and Information members of the IRP's I/O status block with appropriate values, in general:
·The Dispatch routine sets Status either to STATUS_SUCCESS or to an appropriate error STATUS_XXX, which can be the value returned by a call to a support routine or, for certain synchronous requests, by a lower driver.
If a lower-level driver returns STATUS_PENDING, a higher-level driver should not call IoCompleteRequest with an IRP unless it calls IoMarkIrpPending with that IRP first. However, a higher-level driver's Dispatch routine is unlikely to complete any IRP for which lower driver(s) return STATUS_PENDING.
·It sets Information to the number of bytes successfully transferred if a request to transfer data, such as a read or write request, was satisfied.
·It sets Information to a value that varies according to the specific request for other IRPs that it completes with STATUS_SUCCESS.
·It sets Information to a value that varies according to the specific request for IRPs that it completes with a warning STATUS_XXX. For example, it would set Information to the number of bytes transferred for such a warning as STATUS_BUFFER_OVERFLOW.
·Usually, it sets Information to zero for requests that it completes with an error STATUS_XXX.
2.Calls IoCompleteRequest with the IRP and the PriorityBoost IO_NO_INCREMENT.
3.Returns the appropriate STATUS_XXX that it already set in the I/O status block. Note that a call to IoCompleteRequest makes the given IRP inaccessible by the caller, so the return value from a Dispatch routine cannot be set from the I/O status block of an already completed IRP.
NT driver writers should follow this implementation guideline for calling IoCompleteRequest with an IRP:
Always release any spin lock(s) the driver is holding before calling IoCompleteRequest.
It takes an indeterminate amount of time to complete an IRP, particularly in a chain of layered NT drivers. Moreover, a deadlock can occur if a higher-level driver's IoCompletion routine sends an IRP back down to a lower driver that is holding a spin lock.