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

Re: Dispatch and Completion routine synchronisation by Don

Don
Fri Feb 01 12:36:05 CST 2008

Comments inline:

"Carl" <pleasedo@notemail.me> wrote in message
news:VrJoj.76$zg.59@newsfe5-win.ntli.net...
> 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).

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.

> 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.

Yes you need to complete the request, your presumptions are correct.

> 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.
>

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



Re: Dispatch and Completion routine synchronisation by Carl

Carl
Fri Feb 01 13:26:31 CST 2008

Don,

Many thanks, that cleared everything up!

Carl

"Don Burn" <burn@stopspam.windrvr.com> wrote in message
news:e37wQFQZIHA.4828@TK2MSFTNGP05.phx.gbl...
> Comments inline:
>
> "Carl" <pleasedo@notemail.me> wrote in message
> news:VrJoj.76$zg.59@newsfe5-win.ntli.net...
>> 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).
>
> 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.
>
>> 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.
>
> Yes you need to complete the request, your presumptions are correct.
>
>> 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.
>>
>
> 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
>
>

Re: Dispatch and Completion routine synchronisation by Doron

Doron
Mon Feb 04 14:47:45 CST 2008

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


--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"Carl" <pleasedo@notemail.me> wrote in message
news:HnKoj.354$zg.334@newsfe5-win.ntli.net...
> Don,
>
> Many thanks, that cleared everything up!
>
> Carl
>
> "Don Burn" <burn@stopspam.windrvr.com> wrote in message
> news:e37wQFQZIHA.4828@TK2MSFTNGP05.phx.gbl...
>> Comments inline:
>>
>> "Carl" <pleasedo@notemail.me> wrote in message
>> news:VrJoj.76$zg.59@newsfe5-win.ntli.net...
>>> 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).
>>
>> 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.
>>
>>> 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.
>>
>> Yes you need to complete the request, your presumptions are correct.
>>
>>> 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.
>>>
>>
>> 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
>>
>>


Re: Dispatch and Completion routine synchronisation by Carl

Carl
Tue Feb 05 03:38:33 CST 2008

Ah... changing code now...

Thank you!

"Doron Holan [MSFT]" <doronh@online.microsoft.com> wrote in message
news:e9#gy82ZIHA.5784@TK2MSFTNGP03.phx.gbl...
> 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
>
>
> --
> Please do not send e-mail directly to this alias. this alias is for
> newsgroup purposes only.
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Carl" <pleasedo@notemail.me> wrote in message
> news:HnKoj.354$zg.334@newsfe5-win.ntli.net...
>> Don,
>>
>> Many thanks, that cleared everything up!
>>
>> Carl
>>
>> "Don Burn" <burn@stopspam.windrvr.com> wrote in message
>> news:e37wQFQZIHA.4828@TK2MSFTNGP05.phx.gbl...
>>> Comments inline:
>>>
>>> "Carl" <pleasedo@notemail.me> wrote in message
>>> news:VrJoj.76$zg.59@newsfe5-win.ntli.net...
>>>> 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).
>>>
>>> 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.
>>>
>>>> 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.
>>>
>>> Yes you need to complete the request, your presumptions are correct.
>>>
>>>> 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.
>>>>
>>>
>>> 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
>>>
>>>
>