As it is your driver that is responding to IRP_MN_QUERY_PNP_DEVICE_STATE,
your driver could abolish the race condition by disabling the interface
before responding to the PnP request. It looks like you have identified a
legitimate bug, but if you just want a safe work-around I think the solution
is fairly obvious.
=====================
Mark Roddy
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 2:07 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
I didn’t understand your statement about the race condition.
Are you saying you think the bug check is avoidable if I will not use a work
item?
This can’t help me since I’m only a filter driver on some device stacks and
have no control over who ever is calling IoGetDeviceObjectPointer() and
whether he uses a work item or not, but still - What race might exist from
me using a work item, and how can not using one solve this problem?
Shahar
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, April 20, 2005 6:25 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
IoGetDeivceObjectPointer from a pnp notification callback will deadlock the
pnp manager *only if* the resulting create results in a pnp enumerate/state
change. For instance, if you open an audio device enumerated by KS, that
open will actually enumerate a PDO to handle the create and deadlock pnp. A
create to stack which does not do any pnp on behalf of the create (which is
probably 99% of the stacks out there) can be done w/in the callback. Since
you are opening an interface, you know the guidelines for that interface and
make that call.
Perhaps your workitem is racing with the pnp callback indicating that the
interface has gone away.
d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 10:11 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
The difference between start failing on the way up to pnp and query device
failing after start succeeded, is that no notifications are sent if start
fails.
From my observations I am now sure that pnp sends notifications and that
creates succeed before query device state is completed.
As for the work item, I’m pretty sure someone told me a long time ago that
calling IoGetDeviceObjectPointer() from a pnp notification callback will
deadlock the pnp manager…
Shahar
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, April 20, 2005 5:39 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
From a driver POV, the start failing or start succeeding and then query
device state failing appear to be the same. For instance, if an upper
filter failed start, the lower driver will have succeeded start and then get
a remove…which is exactly what happens if start succeeds all the way back
to pnp and then query device state fails.
I have fwd’ed this thread to the pnp team. It could be that device
interfaces are enabled after start but before query device state has been
sent.
Also, why are you queueing a work item to open the device interface instead
of just opening the device in the arrival notification callback?
d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 8:09 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
But even if it did wait, the other driver still got the device object and it
still might call IoCallDriver() on it…
I believe this is a design bug. This can be solved in one of two ways:
- The pnp manager should report device interface notifications only after
IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set. - The pnp manager should send an IRP_MN_SURPRISE_REMOVAL to the device
before sending the IRP_MN_REMOVE_DEVICE in case
IRP_MN_QUERY_PNP_DEVICE_STATE completed with error flags set.
There is also the documentation to fix, according to the DDK docs a
IRP_MN_REMOVE_DEVICE with no IRP_MN_QUERY_REMOVE_DEVICE or
IRP_MN_SURPRISE_REMOVE coming before it can only happen when an
IRP_MN_START_DEVICE is failed. Nothing is mentioned about
IRP_MN_QUERY_PNP_DEVICE_STATE completing with an error flag set…
Shahar
-----Original Message-----
From: Andrei Zlate-Podani [mailto:xxxxx@bitdefender.com]
Sent: Wednesday, April 20, 2005 3:49 PM
To: xxxxx@safend.com
Subject: Re: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE
Shahar Talmi wrote:
Hi Andrei,
Yes. I disable the device interface before removing the device. Why do
you think this should make a difference?
Well, that was one of the things the driver had to take care before
completing that IRP.
If create operations are in progress, I think that IoSetDeviceInterfaceState
would wait for them to finish.
Thanks,
Andrei
Shahar
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Andrei
Zlate-Podani
Sent: Wednesday, April 20, 2005 10:39 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICEHello Shahar,
Do you call IoSetDeviceInterfaceState to disable the interface before
completing the IRP_MN_REMOVE_DEVICE?Andrei
Shahar Talmi wrote:
>David,
>Now you are just offending me.
>It’s not possible for a driver to prevent itself from unloading using
>only it’s own locks. What will you say about a scenario where two
>dispatch function are called at the same time - one to process I/O and
>one to remove the device, and then the remove dispatch finishes before
>the I/O dispatch has run even one source line. In this case no matter
>what internal lock mechanism I’m using, the driver will still unload
>before I get the chance to acquire it.
>
>Think about it, some one “from above” must make sure that there are no
>open handles to the device before sending the remove request and must
>make sure that the device is not handling a remove request when
>calling the create dispatch.
>
>The only one with this power is the I/O manager, no code that I write
>can prevent this stuff from happening. In the “failed start” scenario
>I’m talking about, my belief is that the I/O manager does not handle
>the case correctly.
>
>As for your comment about using the samples - I am using a sample from
>the Oney book with one simple change - I’m setting the
>PNP_DEVICE_FAILED flag in the information field of the
>IRP_MN_QUERY_PNP_DEVICE_STATE request. If I try to start the device
>enopugh times, I’m getting the 0xCE bugcheck. All the events I talked
>about in the first message are just for timing the execution so the
>
>
bugcheck will be generated in every time I start the device.>Shahar
>
>
>“David J. Craig” wrote in message
>>news:xxxxx@ntdev…
>>
>>
>>
>>
>>>You have to take locks when you are processing an IRP and don’t allow
>>>the PNP logic to cause you to unload. Look at the samples and take a
>>>course from OSR. You have to keep your driver in memory until it is
>>>not
>>>
>>>
>needed.
>
>
>>>You may under some circumstances, having a timer, remain in memory,
>>>but you should let go of your hardware so you can be plug and play.
>>>Microsoft says that there is no safe way to undo a timer and leave
>>>memory
>>>
>>>
>cleanly.
>
>
>>>I think there should be a way to do it, but they said no.
>>>
>>>“Shahar Talmi” wrote in message
news:xxxxx@ntdev…
>>>
>>>
>>>
>>>
>>>>David,
>>>>Your judgimg too quickly:
>>>>The device is unloading while/after processing an IRP_MJ_CREATE. The
>>>>responsibility of preventing the device from unloading is the
>>>>callers responsibility (in this case IoGetDeviceObjectPointers()‘s).
>>>>If the pnp manager would have waited with the IRP_MN_REMOVE_DEVICE
>>>>until all references are released, then no premature unlopading
would
happen.
>>>>How can my pnp dispach function know that there are still references
>>>>to the device? In my opinion this is a pnp manager bug. Do you think
>>>>there is something missing in my dispatch functions? How would you
>>>>
>>>>
>explain this?
>
>
>>>>Shahar
>>>>
>>>>“David J. Craig” wrote in message
>>>>news:xxxxx@ntdev…
>>>>
>>>>
>>>>
>>>>
>>>>>How can your device unload when processing an IRP? Only bad code
>>>>>can do this.
>>>>>
>>>>>“Shahar Talmi” wrote in message
news:xxxxx@ntdev…
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>Hi,
>>>>>>
>>>>>>The DDK states that an IRP_MN_REMOVE_DEVICE is issued in three
cases:
>>>>>>a) Remove after successful IRP_MN_QUERY_REMOVE_DEVICE
>>>>>>b) Remove after IRP_MN_SURPRISE_REMOVAL
>>>>>>c) Remove after failed IRP_MN_START_DEVICE
>>>>>>
>>>>>>I’m wondering about what happens to all the open handles to the
device:
>>>>>>in case “a”: IRP_MN_QUERY_REMOVE_DEVICE will fail unless the
>>>>>>driver can close the handles, I guess.
>>>>>>in case “b”: The DDK states that the IRP_MN_REMOVE_DEVICE will be
>>>>>>sent only after all handles are closed.
>>>>>>in case “c”: My guess is that no checks are done since no handles
>>>>>>should be open to the device at this state (except for other
>>>>>>devices in the device stack, which will detach anyway while
>>>>>>handling the IRP_MN_REMOVE_DEVICE).
>>>>>>
>>>>>>Well, I have a little problem with case “c”:
>>>>>>
>>>>>>
>>>>>>From my personal experience I can say that the DDK statement is
>>>>>>not
>>>>>
>>>>>
>>>>>>accurate. If a driver completes IRP_MN_START_DEVICE successfully,
>>>>>>but sets the PNP_DEVICE_FAILED flag in the information field of
>>>>>>the IRP_MN_QUERY_PNP_DEVICE_STATE that follows the successful
>>>>>>start, the device still gets an IRP_MN_REMOVE_DEVICE - no
>>>>>>IRP_MN_SURPRISE_REMOVAL is sent.
>>>>>>
>>>>>>If my guess about the pnp manager assuming that no handles are
>>>>>>open to the device is correct, then we have a problem here:
>>>>>>If the driver registered a device interface, when it completed the
>>>>>>IRP_MN_START_DEVICE successfully some drivers might have received
>>>>>>notifications about the new device and might call
>>>>>>IoGetDeviceObjectPointer()
>>>>>>before the device completes the IRP_MN_REMOVE_DEVICE.
>>>>>>
>>>>>>* Here is an explanation about what my test drivers are doing:
>>>>>>Driver A registers for notification on driver B.
>>>>>>Driver A calls IoGetDeviceObjectPointer() on the device in a work
>>>>>>item when a notification arrives.
>>>>>>Driver B registers with a device interface and completes
>>>>>>IRP_MN_START_DEVICE successfully.
>>>>>>Driver B set the PNP_DEVICE_FAILED flag in the information field
>>>>>>of the IRP_MN_QUERY_PNP_DEVICE_STATE.
>>>>>>
>>>>>>* These two are to make sure the driver handles the IRP_MJ_CREATE
>>>>>>before the
>>>>>>IRP_MN_REMOVE_DEVICE:
>>>>>>Driver B waits on an event before locking the remove lock when
>>>>>>handling IRP_MN_REMOVE_DEVICE Driver B sets the event after
>>>>>>locking the remove lock when handling IRP_MJ_CREATE
>>>>>>
>>>>>>When I execute this test the result that I’m seeing is that driver
>>>>>>B unloads after completing the IRP_MN_REMOVE_DEVICE. A following
>>>>>>call to
>>>>>>IoCallDriver() from driver A with the device it got from
>>>>>>IoGetDeviceObjectPointer() results in a bug check with code 0xCE.
>>>>>>
>>>>>>In some cases, if the handling of IRP_MN_REMOVE_DEVICE completes
>>>>>>before the create dispatch function didn’t return yet, the driver
>>>>>>even bug checks before IoGetDeviceObjectPointer returns (since the
>>>>>>driver unloaded, and the dispatch function is no longer there) - I
>>>>>>tested that by adding a
>>>>>>KeDelayExecutionThread() after releasing the remove lock, but
>>>>>>before returning from the create dispatch function.
>>>>>>
>>>>>>Okay, I hope I made this point clear… Now, is there something I
>>>>>>didn’t understand correctly, or is this a pnp manager bug?
>>>>>>All my tests are done with winxp+sp2 installed.
>>>>>>
>>>>>>Thanks,
>>>>>>Shahar
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@bitdefender.com To
>>unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>
>>
>
>
>–
>Ignorance more frequently begets confidence than does knowledge.
>— Charles Darwin
>
>
>
>
>
–
Ignorance more frequently begets confidence than does knowledge.
— Charles Darwin
–
This message was scanned for spam and viruses by BitDefender.
For more information please visit http://linux.bitdefender.com/
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: unknown lmsubst tag argument:
’'
To unsubscribe send a blank email to xxxxx@lists.osr.com
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@stratus.com To
unsubscribe send a blank email to xxxxx@lists.osr.com