IoBuildDeviceIoControlRequest & IoFreeIrp

Hi,

WDK documentation says:

IRPs that are created by *IoBuildDeviceIoControlRequest* must be completed
by a driver’s call to
*IoCompleteRequest*<k104_79ea2b93-3ce8-46eb-990b-ca3e56d3e3a8.xml.htm>.
A driver that calls IoBuildDeviceIoControlRequest must not call IoFreeIrp
<k104_fc262cc4-a482-4a92-9f8e-1e5765c9b1d4.xml.htm>, because the I/O
manager frees these synchronous IRPs after IoCompleteRequest has been
called.

I guess here the assumption is implied that after calling
IoBuildDeviceIoControlRequest
the IRP is passed to IoCallDriver. But in
case I find out that I should not call IoCallDriver for some reason, then
who should call IoFreeIRP. To be precise who should free that IRP and HOW?
Can I call IoCompleteRequest without making any call to IoCallDriver on
that IRP.

Thanks and Regards,
----------------------------------------------------------------
Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550</k104_fc262cc4-a482-4a92-9f8e-1e5765c9b1d4.xml.htm></k104_79ea2b93-3ce8-46eb-990b-ca3e56d3e3a8.xml.htm>

You should free it by IoFreeIrp if IoCallDriver is not called.

BUT why do you build it when you do not call IoCallDriver?

Regards

Haibo


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Charansing Rajput
Sent: Friday, April 24, 2009 2:59 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] IoBuildDeviceIoControlRequest & IoFreeIrp

Hi,

WDK documentation says:

IRPs that are created by IoBuildDeviceIoControlRequest must be completed by
a driver’s call to IoCompleteRequest. A driver that calls
IoBuildDeviceIoControlRequest must not call IoFreeIrp, because the I/O
manager frees these synchronous IRPs after IoCompleteRequest has been
called.

I guess here the assumption is implied that after calling
IoBuildDeviceIoControlRequest the IRP is passed to IoCallDriver. But in case
I find out that I should not call IoCallDriver for some reason, then who
should call IoFreeIRP. To be precise who should free that IRP and HOW? Can I
call IoCompleteRequest without making any call to IoCallDriver on that IRP.

Thanks and Regards,

Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550
— 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

On a particular condition i might have to decide not to call IoCallDriver.

And well… for IoFreeIrp I get bugcheck C9 (0x2) which says that “The
driver attempted to free an IRP that is still associated with a thread.”

Thanks and Regards,

Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550

On Fri, Apr 24, 2009 at 1:01 PM, Haibo wrote:

> You should free it by IoFreeIrp if IoCallDriver is not called.
>
> BUT why do you build it when you do not call IoCallDriver?
>
>
>
> Regards
>
> Haibo
> ------------------------------
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Charansing Rajput
> Sent: Friday, April 24, 2009 2:59 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] IoBuildDeviceIoControlRequest & IoFreeIrp
>
>
>
> Hi,
>
> WDK documentation says:
>
> IRPs that are created by IoBuildDeviceIoControlRequest must be completed
> by a driver’s call to IoCompleteRequesthttp:.
> A driver that calls IoBuildDeviceIoControlRequest must not call
> IoFreeIrp
http:,
> because the I/O manager frees these synchronous IRPs after
> IoCompleteRequest
has been called.
>
> I guess here the assumption is implied that after calling
> IoBuildDeviceIoControlRequest
the IRP is passed to IoCallDriver. But in
> case I find out that I should not call IoCallDriver for some reason,
> then who should call IoFreeIRP. To be precise who should free that IRP and
> HOW? Can I call IoCompleteRequest without making any call to
> IoCallDriver
on that IRP.
>
> Thanks and Regards,
> ----------------------------------------------------------------
> Charansing D Deore
> Sr. Software Developer,
> CalSoft Pvt Ltd.
> Baner Road, Pune-411045
> Office: +91 20 40792900 Ext: 3052
> Cell: +91 9850960550
> — 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
></http:></http:>

>>On a particular condition i might have to decide not to call IoCallDriver.

can’t you call IoBuildDeviceIoControlRequest inside this condition, I mean if you are crating a IRP, you must have thought to send it to destination, later you decide not to send and hence not to call IoCallDriver, how about calling IoBuildDeviceIoControlRequest when you are sure about a call to IoCallDriver.

Call

RemoveEntryList( &irp->ThreadListEntry );

InitializeListHead( &irp->ThreadListEntry ) ;

before IoFreeIrp will avoid this bugcheck.

Regards

Haibo


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Charansing Rajput
Sent: Friday, April 24, 2009 3:57 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] IoBuildDeviceIoControlRequest & IoFreeIrp

On a particular condition i might have to decide not to call IoCallDriver.

And well… for IoFreeIrp I get bugcheck C9 (0x2) which says that “The
driver attempted to free an IRP that is still associated with a thread.”

Thanks and Regards,

Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550

On Fri, Apr 24, 2009 at 1:01 PM, Haibo wrote:

You should free it by IoFreeIrp if IoCallDriver is not called.

BUT why do you build it when you do not call IoCallDriver?

Regards

Haibo

_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Charansing Rajput
Sent: Friday, April 24, 2009 2:59 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] IoBuildDeviceIoControlRequest & IoFreeIrp

Hi,

WDK documentation says:

IRPs that are created by IoBuildDeviceIoControlRequest must be completed by
a driver’s call to
http:
IoCompleteRequest. A driver that calls IoBuildDeviceIoControlRequest must
not call http:
IoFreeIrp, because the I/O manager frees these synchronous IRPs after
IoCompleteRequest has been called.

I guess here the assumption is implied that after calling
IoBuildDeviceIoControlRequest the IRP is passed to IoCallDriver. But in case
I find out that I should not call IoCallDriver for some reason, then who
should call IoFreeIRP. To be precise who should free that IRP and HOW? Can I
call IoCompleteRequest without making any call to IoCallDriver on that IRP.

Thanks and Regards,
----------------------------------------------------------------
Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550

— 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

— 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</http:></http:>

>>I get bugcheck C9 (0x2) which says that “The driver attempted to free an IRP that is still associated with a thread.”

Not so sure on this but using IoAllocateIrp and than filling it on your own should avoid this bug.

>I get bugcheck C9 (0x2) which says that "The driver attempted to free an IRP

that is still associated with a thread."

It seems that you don’t have rights to free your irp.
So you should check your code to make sure whether you have rights to free your irp.

WDK doc says that IoAllocateIrp routine does not associate the IRP with
a thread. Driver MUST free the IRP instead of completing it back to the
I/O manager’.

Thanks
wayne

>>It seems that you don’t have rights to free your irp. So you should check your code to make sure whether you have rights to free your irp.

what rights ? OP has created an Irp and is now freeing it, its most probably because IoBuildDeviceIoControlRequest is maintaining some linking of Irp with the thread and IoFreeIrp is checking that. Where do you think rights comes in picture here?

Aditya

Nothing to do with rights, irp->ThreadListEntry is the key point.

From: “Haibo”
> Call
> RemoveEntryList( &irp->ThreadListEntry );
> InitializeListHead( &irp->ThreadListEntry ) ;
> before IoFreeIrp will avoid this bugcheck.

But will potentially lead to a different bug check if the thread is being
terminated at the same time, because you do not have control of the lock on
the thread queue. That is why this field in the IRP is considered opaque.

The suggestion to use IoAllocateIrp is also misguided because, if you DO
call IoCallDriver later on, the IRP will not complete in the normal way for
a synchronous IRP and will not be cancelled automatically if the thread
terminates.

The right answer, then, is to call IoCompleteRequest. The I/O Manager will
cleanup the IRP for you.

Walter Oney
Consulting and Training
www.oneysoft.com

Thanks a lot for the replies.

I have a couple of doubts here:
What status should I set in the IoStatus field of this IRP? or it just wont
matter?
Would IoCancelIrp instead of IoCompleteRequest make any difference?

Thanks and Regards,

Charansing D Deore
Sr. Software Developer,
CalSoft Pvt Ltd.
Baner Road, Pune-411045
Office: +91 20 40792900 Ext: 3052
Cell: +91 9850960550

On Fri, Apr 24, 2009 at 5:49 PM, Walter Oney wrote:

> From: “Haibo”
>
>> Call
>> RemoveEntryList( &irp->ThreadListEntry );
>> InitializeListHead( &irp->ThreadListEntry ) ;
>> before IoFreeIrp will avoid this bugcheck.
>>
>
> But will potentially lead to a different bug check if the thread is being
> terminated at the same time, because you do not have control of the lock on
> the thread queue. That is why this field in the IRP is considered opaque.
>
> The suggestion to use IoAllocateIrp is also misguided because, if you DO
> call IoCallDriver later on, the IRP will not complete in the normal way for
> a synchronous IRP and will not be cancelled automatically if the thread
> terminates.
>
> The right answer, then, is to call IoCompleteRequest. The I/O Manager will
> cleanup the IRP for you.
>
> Walter Oney
> Consulting and Training
> www.oneysoft.com
>
> —
>
> 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
>

@Walter Oney

>The suggestion to use IoAllocateIrp is also misguided because,

my bad, I confused IoAllocateIrp with IoInitializeIrp on a allocated memory,

what I was trying to suggest as an alternative is that allocate the Irp (with ExAllocatePool) and when you are sure to call the driver call IoInitializeIrp else free the memory allocated through ExAllocatePool.

> if you DO call IoCallDriver later on, the IRP will not complete in the normal way for a synchronous IRP and will not be cancelled automatically if the thread terminates.

I call IoAllocateIrp to get an Irp, sets the fields of Irp, sets completion routine with 3 true, and call IoCallDriver. Isn’t this the usual way? I missed some point or does your statement meant that sending Irp this way is not good?

Here I respectfully want to state that I am not at all objecting, I know if *you* are stating something it has to be true, but I thought this is a straight, simple flow, what is wrong here or what exactly I am missing?

kindly suggest?

Thanks
Aditya

Why are you doing so much of overhead?

If you do not want to call IoCallDriver(…), do not allocate IRP (that is,
do not call IoBuildDeviceIoControlRequest ). It is better to have a little
more code in terms of size than to do unnecessary things: allocate IRP, at
certain point call unnessary IoCallDriver and so on which slows down your
code in terms of speed. Keep it simple and fast.


Volodymyr M. Shcherbyna, blog: http://www.shcherbyna.com/
(This posting is provided “AS IS” with no warranties, and confers no
rights)
“Charansing Rajput” wrote in message
news:xxxxx@ntdev…
> Thanks a lot for the replies.
>
> I have a couple of doubts here:
> What status should I set in the IoStatus field of this IRP? or it just
> wont
> matter?
> Would IoCancelIrp instead of IoCompleteRequest make any difference?
>
> Thanks and Regards,
> ----------------------------------------------------------------
> Charansing D Deore
> Sr. Software Developer,
> CalSoft Pvt Ltd.
> Baner Road, Pune-411045
> Office: +91 20 40792900 Ext: 3052
> Cell: +91 9850960550
>
>
> On Fri, Apr 24, 2009 at 5:49 PM, Walter Oney
> wrote:
>
>> From: “Haibo”
>>
>>> Call
>>> RemoveEntryList( &irp->ThreadListEntry );
>>> InitializeListHead( &irp->ThreadListEntry ) ;
>>> before IoFreeIrp will avoid this bugcheck.
>>>
>>
>> But will potentially lead to a different bug check if the thread is being
>> terminated at the same time, because you do not have control of the lock
>> on
>> the thread queue. That is why this field in the IRP is considered opaque.
>>
>> The suggestion to use IoAllocateIrp is also misguided because, if you DO
>> call IoCallDriver later on, the IRP will not complete in the normal way
>> for
>> a synchronous IRP and will not be cancelled automatically if the thread
>> terminates.
>>
>> The right answer, then, is to call IoCompleteRequest. The I/O Manager
>> will
>> cleanup the IRP for you.
>>
>> Walter Oney
>> Consulting and Training
>> www.oneysoft.com
>>
>> —
>>
>> 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
>>
>

From:
> I call IoAllocateIrp to get an Irp, sets the fields of Irp, sets
> completion routine with 3 true, and call IoCallDriver. Isn’t this the
> usual way? I missed some point or does your statement meant that sending
> Irp this way is not good?

As I learned while writing chapter 5 of my book, there are “synchronous” and
“asynchronous” IRPs. Synchronous IRPs belong to a particular thread, whereas
asynchronous IRPs don’t. You build a synchronous IRP when you plan to block
the owning thread waiting for it to complete. There are two DDIs for
creating synchronous IRPs: IoBuildSynchronousFsdRequest and
IoBuildDeviceIoControlRequest. For whatever reason, Microsoft chose not to
implement a DDI for building an asynchronous control request – people often
use IoBuildAsynchronousFsdRequest to create, say, an IRP_MJ_SHUTDOWN, and
then fill in the MajorFunction and Parameters of the 1st stack location by
hand.

Presumably, the OP read and considered an explanation like the one I wrote
on pp. 223-25 and made a deliberate choice to call
IoBuildDeviceIoControlRequest, which has the restriction he noted and found
out about the hard way.

Walter Oney
Consulting and Training
www.oneysoft.com

from filespy sample in wdk, fspylib.c used IoAllocateIrp as follows

irp = IoAllocateIrp( NextDeviceObject->StackSize, FALSE );

//
// Set our current thread as the thread for this
// IRP so that the IO Manager always knows which
// thread to return to if it needs to get back into
// the context of the thread that originated this
// IRP.
//

irp->Tail.Overlay.Thread = PsGetCurrentThread();

//
// Set the IRP_SYNCHRONOUS_API to denote that this
// is a synchronous IO request.
//

irp->Flags = IRP_SYNCHRONOUS_API;

some more field setting or more processing

status = IoCallDriver( NextDeviceObject, irp );

What is wrong with this piece of code, or when can we have a situation where the following statement holds true,

"…if you DO call IoCallDriver later on, the IRP will not complete in the normal way for a synchronous IRP and will not be cancelled automatically if the thread terminates. "

Why(or when) this Irp can not be completed as a normal synchronize Irp ? I have used this several time for different FS operations and this is working absolutely fine and this is what making me curious about this.

Thanks,
Aditya

>>There are two DDIs for creating synchronous IRPs: IoBuildSynchronousFsdRequest and IoBuildDeviceIoControlRequest. For whatever reason, Microsoft chose not to implement a DDI for building an asynchronous control request – people often use IoBuildAsynchronousFsdRequest to create, say, an IRP_MJ_SHUTDOWN, and then fill in the MajorFunction and Parameters of the 1st stack location by hand.

I guess they are all just wrappers to save the developer’s time, in fact they do not support all IRPs, for example if you have to send a IRP_MJ_SET_INFORMATION to a filesyetm synchronously you can not use IoBuildSynchronousFsdRequest as per WDK docs. So the option is to use IoAllocateIrp or allocate an Irp and call IoInitalizeIrp on that; specify the IRP_SYNCHRONOUS_API in flags and send it to the destination. And this is where I got confused by your statement mainly " the IRP will not complete in the normal way for a synchronous IRP".

Thanks
Aditya

I satisfied my query partially by reading Nagar’s book.

IoAllocateIrp routine does not queue the returned IRP to the linked list of outstanding IRP’s for the current thread. Therefore, when a cancel request is posted, the IRP will not be found among the lists of IRPs for the thread.

But for other part I am still not getting it as why Irps allocated by IoAllocateIrp are not normal synchronous. Specially as windbg reveals that all these IoBuildXXXAPI in turns uses IoAllocateIrp.

Any clues?

Thanks
Aditya

IoBuildDeviceIoControlRequest calls IoAllocateIrp inside and does a lot more work. But it comes with certain assumption that you have to complete the IRP in normal way. For that IRP, you need to do more than just FreeIrp. If you don’t send it to a driver, you’ll need to call oCompleteRequest on it, and the completion routine installed by IBDIOCR will do the rest.

IoAllocateIrp only does what it says: allocates the IRP. It’s paired with IoFreeIrp.

>I guess here the assumption is implied that after calling IoBuildDeviceIoControlRequest the IRP is

passed to IoCallDriver. But in case I find out that I should not call IoCallDriver for some reason

This is just plain prohibited. After IoBuildDeviceIoControlRequest, you must call IoCallDriver with it.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com