Dispatch and Completion routine synchronisation

Discussion in 'Windows Vista Drivers' started by Carl, Feb 1, 2008.

  1. Carl

    Carl Guest

    Dear all,

    I am a little confused because I keep finding contradicting information
    about this issue.

    In a dispatch routine, I set a completion routine and then forward the Irp
    to the lower driver. Something like this:

    IoSetCompletionRoutine(Irp, CompletionRoutine, &Event, NULL, NULL, NULL);
    Status = IoCallDriver(...);
    if (Status == STATUS_PENDING)
    KeWaitForSingleObject(...);

    .... Do some processing...

    IoCompleteRequest(...);
    return (Status);

    So, at the moment my completion routine is tiny and looks a little like
    this:

    KeSetEvent(...);
    return (STATUS_MORE_PROCESSING_REQUIRED);

    Requirements for the completion routine is to just signal an event so my
    dispatch routine has an opportunity to do some processing.

    I've looked at lots of sample code, DDK docs and newsgroup postings and I
    still am not exactly sure what I should do in terms of what I do in the
    completion routine and what NTSTATUS value I return from the dispatch
    routine.

    1. Should I check for Irp->PendingReturned and call IoMarkIrpPending(Irp) in
    the completion routine? (The WDK docs imply that I do not because my
    completion routine is just signalling an event, but other resources state
    that the synchronicity of the Irp must be propogated).
    2. I assume that because I have halted completion processing with
    STATUS_MORE_PROCESSING_REQUIRED) , I need to call IoCompleteRequest(...) to
    allow completion processing to continue.
    3. What do I return from my dispatch routine? The status of IoCallDriver or
    Irp->IoStatus.Status? It feels like I have changed the synchronicity of the
    Irp so it should be Irp->IoStatus.Status.

    Many thanks in advance!

    Carl
     
    Carl, Feb 1, 2008
    #1
    1. Advertisements

  2. Carl

    Don Burn Guest

    Comments inline:

    No you don't need to since the completion routine only gets called when the
    IRP is completed so the lower drivers have completed the request and are
    handing it to you.
    Yes you need to complete the request, your presumptions are correct.
    Again, you have this correct return Irp->IoStatus.Status.



    --
    Don Burn (MVP, Windows DDK)
    Windows 2k/XP/2k3 Filesystem and Driver Consulting
    Website: http://www.windrvr.com
    Blog: http://msmvps.com/blogs/WinDrvr
    Remove StopSpam to reply
     
    Don Burn, Feb 1, 2008
    #2
    1. Advertisements

  3. Carl

    Carl Guest

    Don,

    Many thanks, that cleared everything up!

    Carl
     
    Carl, Feb 1, 2008
    #3
  4. note that you cannot do this

    IoCompleteRequest(irp, IO_NO_INCREMENT);
    return irp->IoStatus.Status;

    becuase irp is now an invalid pointer as you have completed it. instead you
    need to capture the status in a local var, complete the request and then
    return the value of the local var. You should enable driver verifier on
    your driver as well, it can find many of these common mistakes.

    NTSTATUS status;

    status = irp->IoStatus.Status;
    IoCompleteRequest(irp, IO_NO_INCREMENT);
    return status;

    d
     
    Doron Holan [MSFT], Feb 4, 2008
    #4
  5. Carl

    Carl Guest

    Ah... changing code now...

    Thank you!

     
    Carl, Feb 5, 2008
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.