PendingReturned in completion routine

hi, all

As we know, that when a completion routine is called by system, it means that the Irp is completed by all the lower level driver.

But I was wonder about this completion routine:

CompletionRoutine(…)
{
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);

…//other code

return STATUS_CONTINUE_COMPLETION;
}

  1. What mean of PendingReturned?
  2. if completion routine is called, which means the Irp is completed by lower driver, why IoMarkIrpPending needed to this irp?
  3. In the upper code, does the Irp complete or not by the following driver, when completion routine called?
  4. If the answer is not, when will the Irp be completed?

This has been discussed here (and elsewhere) many, many times. Try searching
the archives and reading this article:

http://www.osronline.com/article.cfm?id=83

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

There are two code paths: one is going down the stack with IoCallDriver calls, each returning either STATUS_PENDING, or some other status, and the completion code path, which starts when some lower driver ultimately calls IoCompleteRequest.

For user-originated IO, the completed request needs some post-processing done in the calling thread context. It can either be done when the top-level IoCallDriver returns with other than STATUS_PENDING, or, if STATUS_PENDING was returned, the completion path will need to post an APC (asynchronous procedure call) to the originating thread.

Now, the completion path doesn’t know what status was returned from IoCallDriver. To let it know that, there is a SL_PENDING_RETURNED flag in each IO_STACK_LOCATION of the IRP.

At every IO_STACK_LOCATION, SL_PENDING_RETURNED flag should match the status returned by the corresponding dispatch routine.

If a dispatch routine explicitly returns STATUS_PENDING, it needs to call IoMarkIrpPending before returning (actually, before any point the IRP may be completed asynchronously, such as queuing it to the internal execution queue).

If a dispatch routine passes the IRP to a lower driver by IoCallDriver and returns its status from its dispatch routine, it can’t know what status will be returned. This is what PendingReturned flag serves for. Before your completion routine is called, PendingReturned is set to the state of SL_PENDING_RETURNED flag of the lower stack location. Your completion routine marks your stack location then.

workingmailing wrote:

As we know, that when a completion routine is called by system, it
means that the Irp is completed by all the lower level driver.

But I was wonder about this completion routine:

CompletionRoutine(…)
{
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
…//other code
return STATUS_CONTINUE_COMPLETION;
}

  1. What mean of PendingReturned?
  2. if completion routine is called, which means the Irp is completed
    by lower driver, why IoMarkIrpPending needed to this irp?
  3. In the upper code, does the Irp complete or not by the following
    driver, when completion routine called?
  4. If the answer is not, when will the Irp be completed?

Again, we have a failure to Google.
http://msdn.microsoft.com/en-us/library/ms810023.aspx

It’s not our job to worry about what the upper drivers will do. That
completion routine tells the I/O manager that we have done our job, and
the next driver up should get it’s chance. It’s up to that driver to
decide what to do next.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

To add what Alex said:

During stack unwinding, I/O manager will propagate the pending flag (do you
a favor) up to the stack location only if there was no completion routine
set for that IO stack location.

So if you
1 set an completion routine and
2 you returned anything other than SMPR and
3 you are not the one who built and sent the IRP,

you will need to propagate the pending flag in your completion.

Well, nobody should need to worry about this mess becasue we are supposed to
use KMDF:)

Good luck,
Calvin

On Thu, Jun 16, 2011 at 9:25 AM, wrote:

> There are two code paths: one is going down the stack with IoCallDriver
> calls, each returning either STATUS_PENDING, or some other status, and the
> completion code path, which starts when some lower driver ultimately calls
> IoCompleteRequest.
>
> For user-originated IO, the completed request needs some post-processing
> done in the calling thread context. It can either be done when the top-level
> IoCallDriver returns with other than STATUS_PENDING, or, if STATUS_PENDING
> was returned, the completion path will need to post an APC (asynchronous
> procedure call) to the originating thread.
>
> Now, the completion path doesn’t know what status was returned from
> IoCallDriver. To let it know that, there is a SL_PENDING_RETURNED flag in
> each IO_STACK_LOCATION of the IRP.
>
> At every IO_STACK_LOCATION, SL_PENDING_RETURNED flag should match the
> status returned by the corresponding dispatch routine.
>
> If a dispatch routine explicitly returns STATUS_PENDING, it needs to call
> IoMarkIrpPending before returning (actually, before any point the IRP may be
> completed asynchronously, such as queuing it to the internal execution
> queue).
>
> If a dispatch routine passes the IRP to a lower driver by IoCallDriver and
> returns its status from its dispatch routine, it can’t know what status will
> be returned. This is what PendingReturned flag serves for. Before your
> completion routine is called, PendingReturned is set to the state of
> SL_PENDING_RETURNED flag of the lower stack location. Your completion
> routine marks your stack location then.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Tim Roberts wrote:

It’s not our job to worry about what the upper drivers will do. That
completion routine tells the I/O manager that we have done our job, and
the next driver up should get it’s chance. It’s up to that driver to
decide what to do next.

And I’m embarrassed to discover that I committed an apostrophe fault in
my second sentence. Since I harangue against that on a regular basis, I
am especially aggrieved.

“…the next driver up should get its chance.”


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

If you want people to Google their problems away, you’ve got to stop
providing truly excellent, technically correct, well-summarized responses to
their questions. What search engines don’t provide (at least not very well)
is judgment on what to leave out of the response. This is exactly the
service you *are* providing.

(By the way, I’m hoping you don’t stop.)

Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group

This post implies no warranties and confers no rights.


“Tim Roberts” wrote in message news:xxxxx@ntdev…

Again, we have a failure to Google.
http://msdn.microsoft.com/en-us/library/ms810023.aspx

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.