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:
-
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.
-
Calls IoCompleteRequest with the IRP and the PriorityBoost
IO_NO_INCREMENT.
-
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.