Valid return values from a completion routine

Hi,

I would like to have some clarifications regarding status values that
can be returned from a completion routine.

I thought that returning ContinueCompletion from a completion routine
propagated the status of the lower driver, but this link:
http://msdn2.microsoft.com/en-us/library/ms798250.aspx recomments to
call IoCompleteRequest and return the same status that was returned by a
lower driver. Which is the right way?

Which of the following completion routine should be used to propagate
the status returned by the lower driver.

static NTSTATUS
Power_SystemPowerCompleted_1(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
NTSTATUS ntStatus;

// …

ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return ntStatus;
}

static NTSTATUS
Power_SystemPowerCompleted_2(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
// …

return ContinueCompletion;
}

static NTSTATUS
Power_HandleSystemPower(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
IoMarkIrpPending(Irp);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(
Irp,
Power_SystemPowerCompleted,
NULL,
TRUE, TRUE, TRUE);

PoCallDriver(GetDeviceExtension(DeviceObject)->LowerDeviceObject, Irp);

return STATUS_PENDING;
}

I think you are confusing dispatch routine rules with completion
routines rules. The pattern of

ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return ntStatus;

is correct for a dispatch routine, not a completion routine. Think of
the return value from a completion routine as a BOOLEAN, not an
NTSTATUS. If TRUE, the return value tells the io manager to continue
completing the request. If FALSE, the return value tells the io manager
to no longer continue completing the request. The NTSTATUS values are
mapped to the BOOLEAN decision like this

if (return NTSTATUS == STATUS_MORE_PROCESSING_REQUIRED), result is FALSE
else (return NSTATUS is any other value), result is TRUE

so given this, let’s look at the snippet again

ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp); <– complete the request once

return ntStatus; <– by returning NTSTATUS !=
STATUS_MORE_PROCESSING_REQUIRED you are telling the io manager to
continue completion, but you already completed the request above! This
will result in corruption or a bugcheck depending on the irp’s state

Both of these snippets are functionally equivalent, they both complete
the request back to the caller
1)
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;

// no call to IoCompleteRequest
return Irp->IoStatus.Status;

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, August 01, 2007 6:56 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Valid return values from a completion routine

Hi,

I would like to have some clarifications regarding status values that
can be returned from a completion routine.

I thought that returning ContinueCompletion from a completion routine
propagated the status of the lower driver, but this link:
http://msdn2.microsoft.com/en-us/library/ms798250.aspx recomments to
call IoCompleteRequest and return the same status that was returned by a
lower driver. Which is the right way?

Which of the following completion routine should be used to propagate
the status returned by the lower driver.

static NTSTATUS
Power_SystemPowerCompleted_1(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
NTSTATUS ntStatus;

// …

ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return ntStatus;
}

static NTSTATUS
Power_SystemPowerCompleted_2(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
// …

return ContinueCompletion;
}

static NTSTATUS
Power_HandleSystemPower(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
IoMarkIrpPending(Irp);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(
Irp,
Power_SystemPowerCompleted,
NULL,
TRUE, TRUE, TRUE);

PoCallDriver(GetDeviceExtension(DeviceObject)->LowerDeviceObject, Irp);

return STATUS_PENDING;
}


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

Thanks Doron for the clarification,
I was a little confused with this statement from the documentation which is ambiguous, but it’s clear now.


The IoCompletion routine should do the following:

1. Check Irp->IoStatus.Status to ensure that lower drivers have completed the IRP successfully. If any driver has failed the IRP, call IoCompleteRequest to complete the IRP and return the failure status.

[/quote]

Doron,

I am afraid you are giving pretty dangerous misinformation. Look at your statement below:

[begin qioue]

Both of these snippets are functionally equivalent, they both complete
the request back to the caller
1)
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;

// no call to IoCompleteRequest
return Irp->IoStatus.Status;

[end quote]

IoCompleteRequest() calls completion routines in a loop. This loop is set up in such way that if
completion routine calls IoCompleteRequest() with IRP that it received as a parameter, the overlaying driver will get the target IRP in exactly the same state it would receive it in if a completion routine returned STATUS_CONTINUE_COMPLETION. Therefore, your statement is almost correct - indeed, as far as routines registered by the overlaying drivers are concerned, both code samples are equivalent.

However, there is a “small” detail - the loop runs while ‘Irp->CurrentLocation <= (CCHAR) (Irp->StackCount + 1)’, and ‘Irp->CurrentLocation’ gets incremented upon every iteration of a loop, along with a pointer to the current stack location in IRP and Irp->Tail.Overlay.CurrentStackLocation.
Therefore, both ‘Irp->CurrentLocation’ and stack pointer are supposed to get incremented
‘1+(CCHAR) (Irp->StackCount +1) - Irp->CurrentLocation’ times - any additional incrementation to the stack pointer produces a pointer that is already invalid, i.e. you just run out of stack locations.

IoCompleteRequest() gets the original current stack location from Irp->Tail.Overlay.CurrentStackLocation, and then increments Irp->Tail.Overlay.CurrentStackLocation before starting the loop - this is why both samples that you have shown are equivalent, as far as
completion routines that have been registered by overlaying drivers are concerned. However, Irp->CurrentLocation does not get incremented before the loop starts - it gets incremented only after
every iteration of the loop. It means that if you call IoCompleteRequest() from the completion routine, by the time ‘Irp->CurrentLocation’ gets incremented ‘1+(CCHAR) (Irp->StackCount +1) - Irp->CurrentLocation’ times (i.e. the last time when IoCompleteRequest() accesses a stack pointer), stack pointer will get incremented already ‘2+(CCHAR) (Irp->StackCount +1) - Irp->CurrentLocation’ times, i.e. it will be already invalid. BANG!!!

Anton Bassov

That is indeed incorrect, I will file a bug to get that fixed

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, August 01, 2007 9:03 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Valid return values from a completion routine

Thanks Doron for the clarification,
I was a little confused with this statement from the documentation which
is ambiguous, but it’s clear now.


The IoCompletion routine should do the following:

1. Check Irp->IoStatus.Status to ensure that lower drivers have
completed the IRP successfully. If any driver has failed the IRP, call
IoCompleteRequest to complete the IRP and return the failure status.

[/quote]



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

Anton, if I read your response correctly then you are wrong. If you
were correct that would mean that you could never pend completion of a
PIRP on the way up and would always have to return !=
STATUS_MORE_PROCESSING_REQUIRED from the completion routine. Pattern #1
works perfectly well and there is no issue from the driver POV or the IO
manager POV. In fact, this is what KMDF does when it processes requests
that are completing back to the driver after being sent on a
WDFIOTARGET.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Wednesday, August 01, 2007 11:44 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Valid return values from a completion routine

Doron,

I am afraid you are giving pretty dangerous misinformation. Look at your
statement below:

[begin qioue]

Both of these snippets are functionally equivalent, they both complete
the request back to the caller
1)
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;

// no call to IoCompleteRequest
return Irp->IoStatus.Status;

[end quote]

IoCompleteRequest() calls completion routines in a loop. This loop is
set up in such way that if
completion routine calls IoCompleteRequest() with IRP that it received
as a parameter, the overlaying driver will get the target IRP in exactly
the same state it would receive it in if a completion routine returned
STATUS_CONTINUE_COMPLETION. Therefore, your statement is almost correct

  • indeed, as far as routines registered by the overlaying drivers are
    concerned, both code samples are equivalent.

However, there is a “small” detail - the loop runs while
‘Irp->CurrentLocation <= (CCHAR) (Irp->StackCount + 1)’, and
‘Irp->CurrentLocation’ gets incremented upon every iteration of a loop,
along with a pointer to the current stack location in IRP and
Irp->Tail.Overlay.CurrentStackLocation.
Therefore, both ‘Irp->CurrentLocation’ and stack pointer are supposed to
get incremented
‘1+(CCHAR) (Irp->StackCount +1) - Irp->CurrentLocation’ times - any
additional incrementation to the stack pointer produces a pointer that
is already invalid, i.e. you just run out of stack locations.

IoCompleteRequest() gets the original current stack location from
Irp->Tail.Overlay.CurrentStackLocation, and then increments
Irp->Tail.Overlay.CurrentStackLocation before starting the loop - this
is why both samples that you have shown are equivalent, as far as
completion routines that have been registered by overlaying drivers are
concerned. However, Irp->CurrentLocation does not get incremented before
the loop starts - it gets incremented only after
every iteration of the loop. It means that if you call
IoCompleteRequest() from the completion routine, by the time
‘Irp->CurrentLocation’ gets incremented '1+(CCHAR) (Irp->StackCount +1)

  • Irp->CurrentLocation’ times (i.e. the last time when
    IoCompleteRequest() accesses a stack pointer), stack pointer will get
    incremented already ‘2+(CCHAR) (Irp->StackCount +1) -
    Irp->CurrentLocation’ times, i.e. it will be already invalid. BANG!!!

Anton Bassov


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

Doron,

Anton, if I read your response correctly then you are wrong. If you
were correct that would mean that you could never pend completion of a
PIRP on the way up and would always have to return !=
STATUS_MORE_PROCESSING_REQUIRED from the completion routine.

Actually, the only thing I am saying is that, in my opinion, your example is missing quite important line - I think it just has to increment Irp->CurrentLocation before calling IoCompleteRequest() from the completion routine. If it does so, everything will work *exactly* the same way as if it has just returned STATUS_CONTINUE_COMPLETION instead of calling IoCompleteRequest().
Apparently, when you return STATUS_MORE_PROCESSING_REQUIRED from the completion routine,
Io Manager just does it for you behind the scenes…

Could you please check the sources and tell me whether my suggestion is correct.

Anton Bassov

This may be the single most confusing thread that I’ve read on this list in the past year.

Anton: No, if I understand what you’re saying (which is far from assured) your suggestion is not correct. When you’re called in your completion routine, the IRP is set up correctly – The current I/O Stack Location is YOUR DRIVER’s I/O Stack Location. You don’t need to bump any pointers.

When you return STATUS_MORE_PROCESSING_REQUIRED (gosh, I *hate* that “continue completion” thing… just more stuff to confuse people), the I/O Manager CAN NOT TOUCH THE IRP. Ownership of the IRP has been given to your driver. The IRP could, in fact, be gone.

In addition, note that to be able to (correctly) return STATUS_MORE_PROCESSING_REQUIRED from your completion routine, your dispatch entry point for that IRP must either (a) return STATUS_PENDING, or (b) block, waiting to reclaim and continue processing the IRP. Otherwise, you get double IRP completions.

Did that help or make things even more confusing? I don’t know…

Peter
OSR

Doron and Peter,

I double-checked it - indeed , I was wrong. In actuality, IoCompleteRequest() increments Irp->CurrentLocation before starting the loop, i.e. there is no mismatch between Irp->Tail.Overlay.CurrentStackLocation and Irp->CurrentLocation. Therefore, calling IoCompleteRequest() from the completion routine is fine, but you should not increment
Irp->CurrentLocation before doing it (i.e. taking the step that I suggested in my previous post ) - if you do it, then you will, indeed, cause a mismatch between Irp->Tail.Overlay.CurrentStackLocation and Irp->CurrentLocation, with understandable consequences…

Anton Bassov

Your suggestion is incorrect. There is no need for the driver to
manually adjust the current stack location. When you return SMPR,
IoCompleteRequest does an immediate return, no further processing. Think
of it this way, when your io completion routine is run, the IRP’s stack
location is in exactly the same state as when then irp arrived in your
dispatch routine. What do you when you complete a request in your
dispatch routine? You just call IoCompleteRequest and do not touch the
current stack location. So, the same applies to your io completion
routine. You can easily call IoCompleteRequest (iff you tell the
caller, IoCompleteRequest, to stop further processing by return SMPR).

Test this out for yourself and see.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Thursday, August 02, 2007 2:08 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Valid return values from a completion routine

Doron,

Anton, if I read your response correctly then you are wrong. If you
were correct that would mean that you could never pend completion of a
PIRP on the way up and would always have to return !=
STATUS_MORE_PROCESSING_REQUIRED from the completion routine.

Actually, the only thing I am saying is that, in my opinion, your
example is missing quite important line - I think it just has to
increment Irp->CurrentLocation before calling IoCompleteRequest() from
the completion routine. If it does so, everything will work *exactly*
the same way as if it has just returned STATUS_CONTINUE_COMPLETION
instead of calling IoCompleteRequest().
Apparently, when you return STATUS_MORE_PROCESSING_REQUIRED from the
completion routine,
Io Manager just does it for you behind the scenes…

Could you please check the sources and tell me whether my suggestion is
correct.

Anton Bassov


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

Doron,

Test this out for yourself and see

Actually, at this point there is even no need to do any tests - as I said already, my earlier posts were based upon the wrong assumption that Irp->CurrentLocation does not get incremented before the loop starts…

Anton Bassov

xxxxx@osr.com wrote:

This may be the single most confusing thread that I’ve read on this list in the past year.

Yes, indeed.

In addition, note that to be able to (correctly) return STATUS_MORE_PROCESSING_REQUIRED from your completion routine, your dispatch entry point for that IRP must either (a) return STATUS_PENDING, or (b) block, waiting to reclaim and continue processing the IRP. Otherwise, you get double IRP completions.

I agree with your advice, but I’m not sure about your conclusion. In
that case, won’t the result be an IRP that is never completed, rather
than a double completion? If I return STATUS_MORE_PROCESSING_REQUIRED,
but no one is hanging around to do the “more processing”, the IRP will
be orphaned. Or have I misunderstood your scenario?


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

Tim,

> This may be the single most confusing thread that I’ve read on this list in the past year.

It looks like any thread that discusses various possibilities of IRP handling and completion is just bound to be confusing, because it seems to be one of the most confusing issues in WDK. Therefore,
ironically, after having said this, Peter immediately made the thread even more confusing by mentioning the scenario that is discussed below ( unless he meant yet another possible scenario that I am currently just unaware of)…

I agree with your advice, but I’m not sure about your conclusion. In
that case, won’t the result be an IRP that is never completed, rather
than a double completion? If I return STATUS_MORE_PROCESSING_REQUIRED,
but no one is hanging around to do the “more processing”, the IRP will
be orphaned. Or have I misunderstood your scenario?

Actually, I was a bit puzzled about Peter’s statement about returning STATUS_PENDING as well - indeed, who is going to complete the request if there is no one to do processing???

After thinking about it, I came to the conclusion that Peter meant the scenario when your Dispatch() routine marks IRP as a pending one before sending it down the stack. In this case you have to return STATUS_PENDING from your Dispatch() routine - even if IoCallDriver() returns the final completion status, i.e. IRP has been completed synchronously, your Dispatch() routine still has to return STATUS_PENDING and not the one returned by IoCallDriver(). Therefore, if, in this scenario, completion routine calls IoCompleteRequest() and returns STATUS_MORE_PROCESSING_REQUIRED, Dispatch() routine still has to return STATUS_PENDING.

Anton Bassov

Anton:

Personally, I think these partial quotes you seem found of really don’t
help things, and they certainly don’t help anyone with his or her
problems. I would never want to have to make the argument that one who
quotes like this is trying to help people. You do have a tendency to
mix and match. I’m not the only one to note this; I believe that I’m
third this week. For example, look at this post. It is addressed to
Tim, but the first quote comes from Peter. You then say “Peter
immediately made the thread even more confusing by mentioning the
scenario that is discussed below ( unless he meant yet another possible
scenario that I am currently just unaware of)…,” and follow it with a
quote from Tim, not Peter. I’m not attributing anything to this, and
I’m not even saying that the way you wrote it here isn’t necessarily
consistent. I have my doubts, but thing is that I just don’t really
care all that much anymore.

You have excellent knowledge, but you seem to spend most of your time
defending not what you say, but what you actually meant, and in
particular how other’s should have known that in the first place, all in
response to a critical post of yours not being well received. This is
disingenious at times. For example, you quoted MSDN in part the other
day in your defense, and then later citied it’s ambiguity, also in your
defense. This confuses the hell out of people, as was the case for the
dev on the MSDN thread, because they lose track of what the point of the
whole exercise in the first place.

Your not alone, we all do this, but recently you really seem to have
stepped it up. It’s your right, but, speaking for myself only, I’m
tired of reading e-mail’s like this, and I’m tempted to just stop
reading yours, because it takes a long time to get through this list,
and much of this list consists of threads like this. Don’t get me
wrong; I’m not suggesting that this ought to be important to you. It’s
that it would be unfortunate because you have a lot to offer when you
don’t do this, which, on the hand, is the vast majority of threads to
which you respond, but on the other, the minority of time, at least
recently.

One man’s opinion,

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Friday, August 03, 2007 20:16
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Valid return values from a completion routine

Tim,

> This may be the single most confusing thread that I’ve read on this
list in the past year.

It looks like any thread that discusses various possibilities of IRP
handling and completion is just bound to be confusing, because it seems
to be one of the most confusing issues in WDK. Therefore,
ironically, after having said this, Peter immediately made the thread
even more confusing by mentioning the scenario that is discussed below (
unless he meant yet another possible scenario that I am currently just
unaware of)…

I agree with your advice, but I’m not sure about your conclusion. In
that case, won’t the result be an IRP that is never completed, rather
than a double completion? If I return
STATUS_MORE_PROCESSING_REQUIRED,
but no one is hanging around to do the “more processing”, the IRP will
be orphaned. Or have I misunderstood your scenario?

Actually, I was a bit puzzled about Peter’s statement about returning
STATUS_PENDING as well - indeed, who is going to complete the request if
there is no one to do processing???

After thinking about it, I came to the conclusion that Peter meant the
scenario when your Dispatch() routine marks IRP as a pending one before
sending it down the stack. In this case you have to return
STATUS_PENDING from your Dispatch() routine - even if IoCallDriver()
returns the final completion status, i.e. IRP has been completed
synchronously, your Dispatch() routine still has to return
STATUS_PENDING and not the one returned by IoCallDriver(). Therefore,
if, in this scenario, completion routine calls IoCompleteRequest() and
returns STATUS_MORE_PROCESSING_REQUIRED, Dispatch() routine still has to
return STATUS_PENDING.

Anton Bassov


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

Two man’s opinion. Well said, Martin. I wanted to write something like this several times but always refused this idea because I couldn’t find such gentle words.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Martin O’Brien[SMTP:xxxxx@evitechnology.com]
Reply To: Windows System Software Devs Interest List
Sent: Saturday, August 04, 2007 3:20 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Valid return values from a completion routine

Anton:

Personally, I think these partial quotes you seem found of really don’t
help things, and they certainly don’t help anyone with his or her
problems. I would never want to have to make the argument that one who
quotes like this is trying to help people. You do have a tendency to
mix and match. I’m not the only one to note this; I believe that I’m
third this week. For example, look at this post. It is addressed to
Tim, but the first quote comes from Peter. You then say “Peter
immediately made the thread even more confusing by mentioning the
scenario that is discussed below ( unless he meant yet another possible
scenario that I am currently just unaware of)…,” and follow it with a
quote from Tim, not Peter. I’m not attributing anything to this, and
I’m not even saying that the way you wrote it here isn’t necessarily
consistent. I have my doubts, but thing is that I just don’t really
care all that much anymore.

You have excellent knowledge, but you seem to spend most of your time
defending not what you say, but what you actually meant, and in
particular how other’s should have known that in the first place, all in
response to a critical post of yours not being well received. This is
disingenious at times. For example, you quoted MSDN in part the other
day in your defense, and then later citied it’s ambiguity, also in your
defense. This confuses the hell out of people, as was the case for the
dev on the MSDN thread, because they lose track of what the point of the
whole exercise in the first place.

Your not alone, we all do this, but recently you really seem to have
stepped it up. It’s your right, but, speaking for myself only, I’m
tired of reading e-mail’s like this, and I’m tempted to just stop
reading yours, because it takes a long time to get through this list,
and much of this list consists of threads like this. Don’t get me
wrong; I’m not suggesting that this ought to be important to you. It’s
that it would be unfortunate because you have a lot to offer when you
don’t do this, which, on the hand, is the vast majority of threads to
which you respond, but on the other, the minority of time, at least
recently.

One man’s opinion,

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Friday, August 03, 2007 20:16
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Valid return values from a completion routine

Tim,

>> This may be the single most confusing thread that I’ve read on this
list in the past year.

It looks like any thread that discusses various possibilities of IRP
handling and completion is just bound to be confusing, because it seems
to be one of the most confusing issues in WDK. Therefore,
ironically, after having said this, Peter immediately made the thread
even more confusing by mentioning the scenario that is discussed below (
unless he meant yet another possible scenario that I am currently just
unaware of)…

> I agree with your advice, but I’m not sure about your conclusion. In
> that case, won’t the result be an IRP that is never completed, rather>
> than a double completion? If I return
STATUS_MORE_PROCESSING_REQUIRED,
> but no one is hanging around to do the “more processing”, the IRP will
> be orphaned. Or have I misunderstood your scenario?

Actually, I was a bit puzzled about Peter’s statement about returning
STATUS_PENDING as well - indeed, who is going to complete the request if
there is no one to do processing???

After thinking about it, I came to the conclusion that Peter meant the
scenario when your Dispatch() routine marks IRP as a pending one before
sending it down the stack. In this case you have to return
STATUS_PENDING from your Dispatch() routine - even if IoCallDriver()
returns the final completion status, i.e. IRP has been completed
synchronously, your Dispatch() routine still has to return
STATUS_PENDING and not the one returned by IoCallDriver(). Therefore,
if, in this scenario, completion routine calls IoCompleteRequest() and
returns STATUS_MORE_PROCESSING_REQUIRED, Dispatch() routine still has to
return STATUS_PENDING.

Anton Bassov


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


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

Martin,

You do have a tendency to mix and match.

******

For example, look at this post. It is addressed to Tim, but the first quote comes from Peter. You > then say “Peter immediately made the thread even more confusing by mentioning the
scenario that is discussed below ( unless he meant yet another possible scenario
that I am currently just unaware of)…,” and follow it with a quote from Tim, not Peter.

I see your point…

The thing is, Tim had some doubts upon the scenario that Peter described, so that I provided my vision of what Peter actually meant. Certainly, in addition to the excerpt with Tim’s question I should have provided Peter’s original statement as well.

In any case, thank you for your advice - I am DEFINITELY going to take it into consideration and try my best to make my posts easier to read and understand…

You have excellent knowledge,

Thanks a lot. However, I am afraid you are much too optimistic - there is an awful lot of things that
I still have to learn from other posters…

Antn Bassov

Michal ,

I wanted to write something like this several times but always refused this idea
because I couldn’t find such gentle words.

Why did not you write it then??? Look - I don’t mind any objective criticism, so that I would have taken your words into consideration…

Anton Bassov