IoMarkIrpPending

Hi Everyone,

According to DDK doc of the IoMarkIrpPending routine
“Unless a driver calls IoCompleteRequest from its
Dispatch routine with a given IRP or passes the IRP on
to lower drivers, it must call IoMarkIrpPending
with the IRP.”

In the USB LOOPBACK sample of the Oney’s book (1st ed)
or the Bulkusb driver of WinXP DDK, the ReadWrite
dispatch routine calls IoMarkIrpPending() then passes
the IRP down to the bus driver. This contradicts the
above DDK statement. Would anyone clarify this for me?

BulkUsb_DispatchReadWrite(
{

IoMarkIrpPending(Irp);
ntStatus = IoCallDriver

(deviceExtension>TopOfStackDeviceObject,
Irp);

return STATUS_PENDING;
}

Thanks in advance
P. Ho


Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

If you read that carefully you’ll see that the documentation states when you
MUST call IoMarkIrpPending. It doesn’t say anything about when you may want
to call IoMarkIrpPending. When you pass an IRP down you may or may not have
to call IoMarkIrpPending… notice that the sample is returning
STATUS_PENDING. So calling IoMarkIrpPending makes sense here.

From: Peter Ho
>Reply-To: “NT Developers Interest List”
>To: “NT Developers Interest List”
>Subject: [ntdev] IoMarkIrpPending
>Date: Fri, 4 Apr 2003 09:16:09 -0800 (PST)
>
>Hi Everyone,
>
>According to DDK doc of the IoMarkIrpPending routine
>“Unless a driver calls IoCompleteRequest from its
>Dispatch routine with a given IRP or passes the IRP on
>to lower drivers, it must call IoMarkIrpPending
>with the IRP.”
>
>In the USB LOOPBACK sample of the Oney’s book (1st ed)
>or the Bulkusb driver of WinXP DDK, the ReadWrite
>dispatch routine calls IoMarkIrpPending() then passes
>the IRP down to the bus driver. This contradicts the
>above DDK statement. Would anyone clarify this for me?
>
>
>BulkUsb_DispatchReadWrite(
>{
> …
> IoMarkIrpPending(Irp);
> ntStatus = IoCallDriver
>
>(deviceExtension>TopOfStackDeviceObject,
> Irp);
> …
> return STATUS_PENDING;
>}
>
>Thanks in advance
>P. Ho
>
>
>Do you Yahoo!?
>Yahoo! Tax Center - File online, calculators, forms, and more
>http://tax.yahoo.com
>
>
>—
>You are currently subscribed to ntdev as: xxxxx@hotmail.com
>To unsubscribe send a blank email to xxxxx@lists.osr.com

_______________
MSN 8 with e-mail virus protection service: 2 months FREE*
http://join.msn.com/?page=features/virus

The documentation in the ddk remains misleading as it ignores the rule: “if
your dispatch routine returns STATUS_PENDING you must call
IoMarkIrpPending.”

if you code your dispatch routine this way:


Status = IoCallDriver(dev, irp);
return Status; /// oops this could be STATUS_PENDING
}

You may very well violate the above rule.

Walter’s code sample correctly handles the case where your dispatch routine
calls IoCallDriver, and some driver down the stack returns STATUS_PENDING.

Note of course that it is too late to call IoMarkIrpPending after calling
IoCallDriver.

-----Original Message-----
From: greg jacklin [mailto:xxxxx@hotmail.com]
Sent: Friday, April 04, 2003 12:59 PM
To: NT Developers Interest List
Subject: [ntdev] Re: IoMarkIrpPending

If you read that carefully you’ll see that the documentation
states when you
MUST call IoMarkIrpPending. It doesn’t say anything about
when you may want
to call IoMarkIrpPending. When you pass an IRP down you may
or may not have
to call IoMarkIrpPending… notice that the sample is returning
STATUS_PENDING. So calling IoMarkIrpPending makes sense here.

>From: Peter Ho
> >Reply-To: “NT Developers Interest List”
> >To: “NT Developers Interest List”
> >Subject: [ntdev] IoMarkIrpPending
> >Date: Fri, 4 Apr 2003 09:16:09 -0800 (PST)
> >
> >Hi Everyone,
> >
> >According to DDK doc of the IoMarkIrpPending routine
> >“Unless a driver calls IoCompleteRequest from its
> >Dispatch routine with a given IRP or passes the IRP on
> >to lower drivers, it must call IoMarkIrpPending
> >with the IRP.”
> >
> >In the USB LOOPBACK sample of the Oney’s book (1st ed)
> >or the Bulkusb driver of WinXP DDK, the ReadWrite
> >dispatch routine calls IoMarkIrpPending() then passes
> >the IRP down to the bus driver. This contradicts the
> >above DDK statement. Would anyone clarify this for me?
> >
> >
> >BulkUsb_DispatchReadWrite(
> >{
> > …
> > IoMarkIrpPending(Irp);
> > ntStatus = IoCallDriver
> >
> >(deviceExtension>TopOfStackDeviceObject,
> > Irp);
> > …
> > return STATUS_PENDING;
> >}
> >
> >Thanks in advance
> >P. Ho
> >
> >
> >Do you Yahoo!?
> >Yahoo! Tax Center - File online, calculators, forms, and more
> >http://tax.yahoo.com
> >
> >
> >—
> >You are currently subscribed to ntdev as: xxxxx@hotmail.com To
> >unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
_______________
> MSN 8 with e-mail virus protection service: 2 months FREE*
> http://join.msn.com/?page=features/virus
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@stratus.com To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>

It’s rather complicated to explain frankly, you really need to understand
how the SL_PENDING_FLAG in the IRP’s stack location and the PendingReturned
flag in the IRP itself are used together to ensure that the pending
condition of the request is always propagated up the stack correctly. This
isn’t easy to follow I will grant you.

That said, the DDK docs are not incorrect, just somewhat incomplete through
omission. If you are going to send an IRP down to a lower driver with no
completion routine, then what the docs say is correct. If you are going to
send the IRP down with a completion routine, and that completion routine
will complete processing of the IRP, then the docs are correct as well.
But, if you are going to send an IRP down with a completion routine and that
completion routine may not complete processing of the IRP (may return
STATUS_MORE_PROCESSING_REQUIRED) then you should mark the IRP pending in the
dispatch routine before sending it down and return STATUS_PENDING from the
dispatch routine.

If you send the IRP down with a completion routine and that completion
routine will complete processing of the IRP, then the dispatch routine
should return whatever status is returned from IoCallDriver, and the
completion routine must check the PendingReturned flag in the IRP and call
IoMarkIrpPending accordingly.

If IoMarkIrpPending is called from the dispatch routine, and STATUS_PENDING
is returned from the dispatch routine, then no check of the IRP’s
PendingReturned flag is necessary in the completion routine.

Clear as mud now?


Bill McKenzie

“Peter Ho” wrote in message news:xxxxx@ntdev…
>
> Hi Everyone,
>
> According to DDK doc of the IoMarkIrpPending routine
> “Unless a driver calls IoCompleteRequest from its
> Dispatch routine with a given IRP or passes the IRP on
> to lower drivers, it must call IoMarkIrpPending
> with the IRP.”
>
> In the USB LOOPBACK sample of the Oney’s book (1st ed)
> or the Bulkusb driver of WinXP DDK, the ReadWrite
> dispatch routine calls IoMarkIrpPending() then passes
> the IRP down to the bus driver. This contradicts the
> above DDK statement. Would anyone clarify this for me?
>
>
> BulkUsb_DispatchReadWrite(
> {
> …
> IoMarkIrpPending(Irp);
> ntStatus = IoCallDriver
>
> (deviceExtension>TopOfStackDeviceObject,
> Irp);
> …
> return STATUS_PENDING;
> }
>
> Thanks in advance
> P. Ho
>
> __________________________________________________
> Do you Yahoo!?
> Yahoo! Tax Center - File online, calculators, forms, and more
> http://tax.yahoo.com
>
>
>

Thanks to Bill, Mark and Greg.
It’s clearer.
thanks

— Bill McKenzie wrote:
> It’s rather complicated to explain frankly, you
> really need to understand
> how the SL_PENDING_FLAG in the IRP’s stack location
> and the PendingReturned
> flag in the IRP itself are used together to ensure
> that the pending
> condition of the request is always propagated up the
> stack correctly. This
> isn’t easy to follow I will grant you.
>
> That said, the DDK docs are not incorrect, just
> somewhat incomplete through
> omission. If you are going to send an IRP down to a
> lower driver with no
> completion routine, then what the docs say is
> correct. If you are going to
> send the IRP down with a completion routine, and
> that completion routine
> will complete processing of the IRP, then the docs
> are correct as well.
> But, if you are going to send an IRP down with a
> completion routine and that
> completion routine may not complete processing of
> the IRP (may return
> STATUS_MORE_PROCESSING_REQUIRED) then you should
> mark the IRP pending in the
> dispatch routine before sending it down and return
> STATUS_PENDING from the
> dispatch routine.
>
> If you send the IRP down with a completion routine
> and that completion
> routine will complete processing of the IRP, then
> the dispatch routine
> should return whatever status is returned from
> IoCallDriver, and the
> completion routine must check the PendingReturned
> flag in the IRP and call
> IoMarkIrpPending accordingly.
>
> If IoMarkIrpPending is called from the dispatch
> routine, and STATUS_PENDING
> is returned from the dispatch routine, then no check
> of the IRP’s
> PendingReturned flag is necessary in the completion
> routine.
>
> Clear as mud now?
>
> –
> Bill McKenzie
>
>
>
> “Peter Ho” wrote in message
> news:xxxxx@ntdev…
> >
> > Hi Everyone,
> >
> > According to DDK doc of the IoMarkIrpPending
> routine
> > “Unless a driver calls IoCompleteRequest from its
> > Dispatch routine with a given IRP or passes the
> IRP on
> > to lower drivers, it must call IoMarkIrpPending
> > with the IRP.”
> >
> > In the USB LOOPBACK sample of the Oney’s book (1st
> ed)
> > or the Bulkusb driver of WinXP DDK, the ReadWrite
> > dispatch routine calls IoMarkIrpPending() then
> passes
> > the IRP down to the bus driver. This contradicts
> the
> > above DDK statement. Would anyone clarify this for
> me?
> >
> >
> > BulkUsb_DispatchReadWrite(
> > {
> > …
> > IoMarkIrpPending(Irp);
> > ntStatus = IoCallDriver
> >
> > (deviceExtension>TopOfStackDeviceObject,
> > Irp);
> > …
> > return STATUS_PENDING;
> > }
> >
> > Thanks in advance
> > P. Ho
> >
> >
> > Do you Yahoo!?
> > Yahoo! Tax Center - File online, calculators,
> forms, and more
> > http://tax.yahoo.com
> >
> >
> >
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
xxxxx@lists.osr.com


Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

Oops, should have been SL_PENDING_RETURNED flag in the IRP stack location :slight_smile:


Bill McKenzie

“Bill McKenzie” wrote in message
news:xxxxx@ntdev…
>
> It’s rather complicated to explain frankly, you really need to understand
> how the SL_PENDING_FLAG in the IRP’s stack location and the
PendingReturned
> flag in the IRP itself are used together to ensure that the pending
> condition of the request is always propagated up the stack correctly.
This
> isn’t easy to follow I will grant you.
>
> That said, the DDK docs are not incorrect, just somewhat incomplete
through
> omission. If you are going to send an IRP down to a lower driver with no
> completion routine, then what the docs say is correct. If you are going
to
> send the IRP down with a completion routine, and that completion routine
> will complete processing of the IRP, then the docs are correct as well.
> But, if you are going to send an IRP down with a completion routine and
that
> completion routine may not complete processing of the IRP (may return
> STATUS_MORE_PROCESSING_REQUIRED) then you should mark the IRP pending in
the
> dispatch routine before sending it down and return STATUS_PENDING from the
> dispatch routine.
>
> If you send the IRP down with a completion routine and that completion
> routine will complete processing of the IRP, then the dispatch routine
> should return whatever status is returned from IoCallDriver, and the
> completion routine must check the PendingReturned flag in the IRP and call
> IoMarkIrpPending accordingly.
>
> If IoMarkIrpPending is called from the dispatch routine, and
STATUS_PENDING
> is returned from the dispatch routine, then no check of the IRP’s
> PendingReturned flag is necessary in the completion routine.
>
> Clear as mud now?
>
> –
> Bill McKenzie
>
>
>
> “Peter Ho” wrote in message news:xxxxx@ntdev…
> >
> > Hi Everyone,
> >
> > According to DDK doc of the IoMarkIrpPending routine
> > “Unless a driver calls IoCompleteRequest from its
> > Dispatch routine with a given IRP or passes the IRP on
> > to lower drivers, it must call IoMarkIrpPending
> > with the IRP.”
> >
> > In the USB LOOPBACK sample of the Oney’s book (1st ed)
> > or the Bulkusb driver of WinXP DDK, the ReadWrite
> > dispatch routine calls IoMarkIrpPending() then passes
> > the IRP down to the bus driver. This contradicts the
> > above DDK statement. Would anyone clarify this for me?
> >
> >
> > BulkUsb_DispatchReadWrite(
> > {
> > …
> > IoMarkIrpPending(Irp);
> > ntStatus = IoCallDriver
> >
> > (deviceExtension>TopOfStackDeviceObject,
> > Irp);
> > …
> > return STATUS_PENDING;
> > }
> >
> > Thanks in advance
> > P. Ho
> >
> > __________________________________________________
> > Do you Yahoo!?
> > Yahoo! Tax Center - File online, calculators, forms, and more
> > http://tax.yahoo.com
> >
> >
> >
>
>
>
>

> In the USB LOOPBACK sample of the Oney’s book (1st ed)

or the Bulkusb driver of WinXP DDK, the ReadWrite
dispatch routine calls IoMarkIrpPending() then passes
the IRP down to the bus driver. This contradicts the
above DDK statement. Would anyone clarify this for me?

No, Walter’s code is correct, though sub-optimal. What is incorrect
is:

IoMarkIrpPending(Irp);
return IoCallDriver(…);

And this is correct and suboptimal:

IoMarkIrpPending(Irp);
IoCallDriver(…)
return STATUS_PENDING;

And this is just correct:

return IoCallDriver(…);

The thing is that “return STATUS_PENDING” and “IoMarkIrpPending” must
be either used both, or neither of them must be used (consider this as
The Main Law Of IRP Processing). Whether or not IoCallDriver is called
is not relevant here.
The first sample is bad because, if the driver below will return
non-pending status, then a Violation Of The Main Law Of IRP Processing
will occur.

The first sample is a known bug in NT4’s CLASS2, which was not hit
only because SCSIPORT always returned STATUS_PENDING. The authors of
full SCSI port drivers were confused though.

Max

“Maxim S. Shatskih” wrote:

No, Walter’s code is correct, though sub-optimal.

> And this is just correct:
>
> return IoCallDriver(…);

Not in this particular context, Max. You need to read the whole sample,
perhaps. The problem being solved with the “suboptimal” code is that the
completion routine will return STATUS_MORE_PROCESSING_REQUIRED an
indeterminate number of times before returning STATUS_SUCCESS. The
bookkeeping for deciding whether and when to call IoMarkIrpPending in
the completion routine was too complicated to be worthwhile.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Now teaming with John Hyde for USB Device Engineering Seminars
Check out our schedule at http://www.oneysoft.com

> completion routine will return STATUS_MORE_PROCESSING_REQUIRED an

indeterminate number of times before returning STATUS_SUCCESS. The
bookkeeping for deciding whether and when to call IoMarkIrpPending
in
the completion routine was too complicated to be worthwhile.

Well, in such a context I surely agree that forcing the IO completion
APC is worthwile.

Max