OSRLogoOSRLogoOSRLogo x Seminar Ad

Everything Windows Driver Development

GoToHomePage xLoginx

    Thu, 14 Mar 2019     118020 members


  Online Dump Analyzer
OSR Dev Blog
The NT Insider
The Basics
File Systems
ListServer / Forum
  Express Links
  · The NT Insider Digital Edition - May-June 2016 Now Available!
  · Windows 8.1 Update: VS Express Now Supported
  · HCK Client install on Windows N versions
  · There's a WDFSTRING?
  · When CAN You Call WdfIoQueueP...ously

Rules for Irp Dispatching and Completion Routines

IRP Dispatching and Handling

  • If a dispatch routine returns STATUS_PENDING, the IRP passed into the
    dispatch routine must be marked pending with IoMarkIrpPending().
  • If an IRP is marked pending with IoMarkIrpPending() in a dispatch routine,
    that dispatch routine must return STATUS_PENDING.
  • If an IRP is to be marked pending, IoMarkIrpPending must be called before
    the IRP is accessible from any context in which it might be completed.
  • If you complete the IRP in the dispatch routine, you must:
    • Fill Irp->IoStatus.Status with the IRP's completion status (this may NOT be STATUS_PENDING)
    • Fill Irp->IoStatus.Information with the number of bytes read or written by the request if the request is being completed with a success status (for data transfer operations and IOCTLs), and
    • Call IoCompleteRequest().

On return from the dispatch routine, you must return the same status that you filled into Irp->IoStatus.Status. Note that in some cases Irp-> IoStatus.Information can hold a pointer.

  • Once you call IoCompleteRequest(), you no longer "own" the IRP, and must not refer to any of its contents.
  • Irp->IoStatus.Status must be filled before calling IoCompleteRequest. In some cases, you can use Irp->IoStatus as a temporary storage before this, assuming you do not pass the IRP to another driver. However, this does not apply to IRPs for IRP_MJ_PNP, because these IRPs arrive from the PnP Manager with a default status already filled into the IoStatus.Status field.
  • Because of special logic in the I/O Manager's completion handling code, drivers can also pass an IRP to another by "return IoCallDriver(...)" without setting a completion routine in the IRP. In this case, IoMarkIrpPending must not be called.
  • The following sequence is also valid, though slower. It is necessary as a
    workaround for filtering some buggy drivers like CDFS in NT V4.0):

    (VOID)IoCallDriver(BottomDeviceObject, Irp);
    return STATUS_PENDING;

I/O Completion Routines

  • There are only three valid return codes from an I/O Completion Routine:
  •  STATUS_MORE_PROCESSING_REQUIRED means that IoCompleteRequest returns to its caller immediately. No further completion routines are called, and IRP is not returned to the I/O Manager.
  • If and only if the completion routine returns STATUS_SUCCESS (or
    STATUS_CONTINUE_COMPLETION) , then it must do the following:

    if( Irp->PendingReturned ) {
  • If you set a completion routine into an IRP that's passed into your driver, and if that completion routine returns STATUS_MORE_PROCESSING_REQUIRED, your dispatch routine for that IRP must either return STATUS_PENDING or it must block until the completion routine has run (for example, waiting on an event
    that is set from within the completion routine).

Related Articles
Properly Pending IRPs - IRP Handling for the Rest of Us
The Truth About Cancel - IRP Cancel Operations (Part II)
That's Just the Way It Is - How NT Describes I/O Requests
The Truth About Cancel - IRP Cancel Operations (Part I)
Secrets of the Universe Revealed! - How NT Handles I/O Completion
What's in a Name? - Cracking Rename Operations
Rolling Your Own - Building IRPs to Perform I/O
Beyond IRPs: Driver to Driver Communications

User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

Post Your Comments.
Print this article.
Email this article.
bottom nav links