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.
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
> 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 > IoFreeIrphttp:, > 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.
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.”
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.
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’.
>>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?
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.
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?
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 >
>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?
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.
//
// 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.
>>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".
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.
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.