About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

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

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

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

If I could recall, "A fundamental paradigm is that I/O mgr holds a ref.count
to the device object when ( and as long as the irp did not finish ), so the
driver could not go away just like that, so in essense in the irp dispatch
path is ref counted ( sort of ). If this is correct, then David is correct,
there must be something in your code .

BTW, what are the bug codes you are seeing ?

-pro
----- Original Message -----
From: “Shahar Talmi”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Tuesday, April 19, 2005 7:34 PM
Subject: Re:[ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

> 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@garlic.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

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

The driver does not closes handles to itself. The apps must do this. Query
remove will fail if there are open handles, possibly even fail early without
generating the IRP.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

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

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

Hello 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


This message was scanned for spam and viruses by BitDefender.
For more information please visit http://linux.bitdefender.com/

Hi Andrei,
Yes. I disable the device interface before removing the device. Why do you
think this should make a difference?

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_DEVICE

Hello 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


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@safend.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

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:

  1. The pnp manager should report device interface notifications only after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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/

If the device interface is off, the create against your driver will not
succeed.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 2:47 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICE

Hi Andrei,
Yes. I disable the device interface before removing the device. Why do
you
think this should make a difference?

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_DEVICE

Hello 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


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@safend.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: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

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:

  1. The pnp manager should report device interface notifications only
    after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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

Yes, but the create dispatch might already start and complete before I turn
off the device interface…

Shahar

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, April 20, 2005 5:36 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

If the device interface is off, the create against your driver will not
succeed.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 2:47 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

Hi Andrei,
Yes. I disable the device interface before removing the device. Why do you
think this should make a difference?

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_DEVICE

Hello 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


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@safend.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: 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

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:

  1. The pnp manager should report device interface notifications only after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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

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:

  1. The pnp manager should report device interface notifications only
    after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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

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:

  1. The pnp manager should report device interface notifications only after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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

If pnp holds the state of the device while it’s calling interface
arrival notifications then you could open the device knowing that the
state won’t change.

By posting to a worker thread you would be giving up that protection.

Note that I said If at the start. I don’t know that it does, but you
asked what race might exist.

Also - it’s still not clear to me which driver in the stack is reporting
a problem in query-device-state. Is it yours? Or some other driver?
If it’s yours, have you considered using the first query-device-state as
a trigger to request another one and reporting your problem there
instead? Then you’d probably get a surprise remove.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 11:07 AM
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:

  1. The pnp manager should report device interface notifications only
    after IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

I tested this out on my machine. You should send the create from the
pnp notification callback indicating interface arrival and then register
for pnp notifications on the fileobject. You will get a removal
notification on the file handle after the query state has been processed
and you should close your handle in that notification.

You will get a notification callback indicating that the interface is
gone, but that will be after the stack has been torn down. I would
assume that by the time the notification is sent, the symbolic link has
been deleted already.

The initial interface arrival callback is guarded by a change in the pnp
state, but you can’t rely on that b/c this only occurs (AFAIK) for newly
arrived interfaces. You don’t know if you are getting notification
about a new interface arrival or an existing interface.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Wednesday, April 20, 2005 10:33 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICE

If pnp holds the state of the device while it’s calling interface
arrival notifications then you could open the device knowing that the
state won’t change.

By posting to a worker thread you would be giving up that protection.

Note that I said If at the start. I don’t know that it does, but you
asked what race might exist.

Also - it’s still not clear to me which driver in the stack is reporting
a problem in query-device-state. Is it yours? Or some other driver?
If it’s yours, have you considered using the first query-device-state as
a trigger to request another one and reporting your problem there
instead? Then you’d probably get a surprise remove.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 11:07 AM
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:

  1. The pnp manager should report device interface notifications only
    after IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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@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

This is a good work around, sadly I have no control over the driver that
sends the creates.

Shahar

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, April 20, 2005 7:46 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

I tested this out on my machine. You should send the create from the pnp
notification callback indicating interface arrival and then register for pnp
notifications on the fileobject. You will get a removal notification on the
file handle after the query state has been processed and you should close
your handle in that notification.

You will get a notification callback indicating that the interface is gone,
but that will be after the stack has been torn down. I would assume that by
the time the notification is sent, the symbolic link has been deleted
already.

The initial interface arrival callback is guarded by a change in the pnp
state, but you can’t rely on that b/c this only occurs (AFAIK) for newly
arrived interfaces. You don’t know if you are getting notification about a
new interface arrival or an existing interface.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Wednesday, April 20, 2005 10:33 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and IRP_MN_REMOVE_DEVICE

If pnp holds the state of the device while it’s calling interface arrival
notifications then you could open the device knowing that the state won’t
change.

By posting to a worker thread you would be giving up that protection.

Note that I said If at the start. I don’t know that it does, but you asked
what race might exist.

Also - it’s still not clear to me which driver in the stack is reporting a
problem in query-device-state. Is it yours? Or some other driver?
If it’s yours, have you considered using the first query-device-state as a
trigger to request another one and reporting your problem there instead?
Then you’d probably get a surprise remove.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 11:07 AM
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:

  1. The pnp manager should report device interface notifications only after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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@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: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Fail the create in your filter driver and do not send it down the stack.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 12:17 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICE

This is a good work around, sadly I have no control over the driver that
sends the creates.

Shahar

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, April 20, 2005 7:46 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICE

I tested this out on my machine. You should send the create from the
pnp
notification callback indicating interface arrival and then register for
pnp
notifications on the fileobject. You will get a removal notification on
the
file handle after the query state has been processed and you should
close
your handle in that notification.

You will get a notification callback indicating that the interface is
gone,
but that will be after the stack has been torn down. I would assume
that by
the time the notification is sent, the symbolic link has been deleted
already.

The initial interface arrival callback is guarded by a change in the pnp
state, but you can’t rely on that b/c this only occurs (AFAIK) for newly
arrived interfaces. You don’t know if you are getting notification
about a
new interface arrival or an existing interface.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Wednesday, April 20, 2005 10:33 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] About IoGetDeviceObjectPointer and
IRP_MN_REMOVE_DEVICE

If pnp holds the state of the device while it’s calling interface
arrival
notifications then you could open the device knowing that the state
won’t
change.

By posting to a worker thread you would be giving up that protection.

Note that I said If at the start. I don’t know that it does, but you
asked
what race might exist.

Also - it’s still not clear to me which driver in the stack is reporting
a
problem in query-device-state. Is it yours? Or some other driver?
If it’s yours, have you considered using the first query-device-state as
a
trigger to request another one and reporting your problem there instead?
Then you’d probably get a surprise remove.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Wednesday, April 20, 2005 11:07 AM
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:

  1. The pnp manager should report device interface notifications only
    after
    IRP_MN_QUERY_PNP_DEVICE_STATE completes with no error flags set.
  2. 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. :slight_smile:
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_DEVICE

Hello 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@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: 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