It’s still not right in this specific case. The problem is that the lower
driver can return something other than STATUS_PENDING, so just doing
return IoCallDriver() could return a non-pending status, regardless of
what your completion handler does.
Meanwhile the completion handler might or might not flob the IRP off to a
worker thread. The rule is that if your completion routine can complete
an IO request on a different thread from that on which it received the
request, then its dispatch routine or IoCompletion routine must call
IoMarkIrpPending, and its dispatch routine must return STATUS_PENDING.
Consider the case where the driver above the OP’s does the following:
IoSetCompletionHandler(…); // sets event on completion
Status = IoCallDriver(…); // to the OP’s driver
if (Status == STATUS_PENDING) {
// we don’t get here if status != STATUS_PENDING, right?
waitForSomeEventToFire();
}
// correct but very bad for the OP’s driver:
SendIrpBackToWhereverItWasAllocatedFrom();
// ouch the OP is off in a worker thread processing this IRP.
In his case he must take the brute force approach in his dispatch routine:
IoMarkIrpPending(…);
IoSetCompletionHandler(…);
(void) IoCallDriver(…);
return STATUS_PENDING;
Anything else will eventually catch the window where his worker thread
runs after the Irp is recycled.
===========================
Mark Roddy
Consultant, Microsoft DDK MVP
Hollis Technology Solutions
xxxxx@hollistech.com
www.hollistech.com
603-321-1032
-----Original Message-----
From: “Maxim S. Shatskih”
To: “Windows System Software Devs Interest List”
Date: Fri, 7 Nov 2003 01:57:41 +0300
Subject: [ntdev] Re: Queuing IRP’s from completion routine
> Yes, thanks for correcting me.
>
> The rule must be: - always do if( Irp->PendingReturned )
> IoMarkIrpPending(Irp); in a completion routine which is logically
> coupled with
> “return IoCallDriver” sequence, even if this completion returns SMPR.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> ----- Original Message -----
> From: “Nick Ryan”
> Newsgroups: ntdev
> To: “Windows System Software Devs Interest List”
> Sent: Thursday, November 06, 2003 9:35 PM
> Subject: [ntdev] Re: Queuing IRP’s from completion routine
>
>
> > Let’s say that your completion routine aborts completion processing
> by
> > returning STATUS_MORE_PROCESSING_REQUIRED, also queueing the IRP for
> > later completion in a worker thread. If your dispatch routine then
> > returns IoCallDriver() instead of STATUS_PENDING, and if the lower
> > driver does it work immediately and returns STATUS_SUCCESS from its
> > dispatch routine, your caller will see STATUS_SUCCESS and will
> > incorrectly assume that the IRP has been fully completed. His next
> step
> > may be to free the IRP, and BSOD ensues.
> >
> > Maxim S. Shatskih wrote:
> >
> > > Why?
> > >
> > > The following:
> > >
> > > IoSetCompletionRoutine()
> > > return IoCallDriver()
> > >
> > > will also work.
> > >
> > > Maxim Shatskih, Windows DDK MVP
> > > StorageCraft Corporation
> > > xxxxx@storagecraft.com
> > > http://www.storagecraft.com
> > >
> > >
> > > ----- Original Message -----
> > > From: “Nick Ryan”
> > > Newsgroups: ntdev
> > > To: “Windows System Software Devs Interest List”
>
> > > Sent: Thursday, November 06, 2003 5:12 AM
> > > Subject: [ntdev] Re: Queuing IRP’s from completion routine
> > >
> > >
> > >
> > >>If he’s queueing the IRP in his completion routine and returning
> > >>STATUS_MORE_PROCESSING_REQUIRED, he definitely must mark the IRP
> pending
> > >>and return STATUS_PENDING from his dispatch routine (unless he
> ensures
> > >>that the IRP is post-processed and completed in his worker thread
> or in
> > >>the dispatch thread before returning).
> > >>
> > >>Maxim S. Shatskih wrote:
> > >>
> > >>
> > >>>>I need to do passive or APC-level processing on IRP’s from my
> completion
> > >>>>routine. My thought is to return STATUS_MORE_PROCESSING_REQUIRED
> and
> > >>>>queue the IRP.
> > >>>
> > >>>
> > >>>This is OK.
> > >>>
> > >>>
> > >>>
> > >>>>But what about pending the IRP? If I understand right, my
> > >>>>dispatch routine needs to mark the IRP pending and return
> STATUS_PENDING
> > >>>>if I’m going to ever queue the IRP, whether at dispatch or
> completion.
> > >>>
> > >>>
> > >>>No, your dispatch routine needs to call IoCallDriver in order for
> the IRP
> > >
> > > to go
> > >
> > >>>to the completion routine 
> > >>>Completion routines are called by lower drivers.
> > >>>
> > >>>So, just:
> > >>>
> > >>> IoSetCompletionRoutine()
> > >>> return IoCallDriver()
> > >>>
> > >>>in the dispatch routine, and queue in the completion. No marking
> as
> > >
> > > pending.
> > >
> > >>>Maxim Shatskih, Windows DDK MVP
> > >>>StorageCraft Corporation
> > >>>xxxxx@storagecraft.com
> > >>>http://www.storagecraft.com
> > >>>
> > >>>
> > >>>
> > >>
> > >>–
> > >>Nick Ryan (MVP for DDK)
> > >>
> > >>
> > >>—
> > >>Questions? First check the Kernel Driver FAQ at
> > >
> > > http://www.osronline.com/article.cfm?id=256
> > >
> > >>You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> > >>To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> > >
> > >
> > >
> > >
> >
> > –
> > Nick Ryan (MVP for DDK)
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@hollistech.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com