PNP remove device question/clarification

I am working on a driver that I did not write. I am reviewing the PNP
handlers. It is a volume filter driver.

In this driver, on PNP remove device, the developer first sends the IRP to
the lower driver synchronously. Upon return, the driver does some device
extension cleanup, and then it calls IoDetachDevice() and then
IoDeleteDevice().

Is this the correct sequence? What if the lower driver deletes its device
object before returning up the chain? How will the IoDetachDevice() handle
this?

Should the driver do its cleanup and detach first, and then send the
request down the stack?

If you look at DiskPerf, it does not send the remove down the stack to the
lower driver.

The MS documentation eludes to some trickiness to handle the remove call,
but it is unclear.


Jamey Kirby
Disrupting the establishment since 1964

*This is a personal email account and as such, emails are not subject to
archiving. Nothing else really matters.*

Ooops. I found where it deletes the device in diskperf and sends to lower
driver. I am not sure how I missed this. Sorry.

//
// Forward the Removal Irp below as per the DDK
// We aren’t required to complete this Irp status should
// be the return status from the next driver in the stack
//
status = DiskPerfSendToNextDriver(DeviceObject, Irp);

//
//Detach us from the stack
//

IoDetachDevice(deviceExtension->TargetDeviceObject);
IoDeleteDevice(DeviceObject);
return status;

On Sun, Dec 27, 2015 at 10:49 AM, Jamey Kirby wrote:

> I am working on a driver that I did not write. I am reviewing the PNP
> handlers. It is a volume filter driver.
>
> In this driver, on PNP remove device, the developer first sends the IRP to
> the lower driver synchronously. Upon return, the driver does some device
> extension cleanup, and then it calls IoDetachDevice() and then
> IoDeleteDevice().
>
> Is this the correct sequence? What if the lower driver deletes its device
> object before returning up the chain? How will the IoDetachDevice() handle
> this?
>
> Should the driver do its cleanup and detach first, and then send the
> request down the stack?
>
> If you look at DiskPerf, it does not send the remove down the stack to the
> lower driver.
>
> The MS documentation eludes to some trickiness to handle the remove call,
> but it is unclear.
>
> –
> Jamey Kirby
> Disrupting the establishment since 1964
>
> This is a personal email account and as such, emails are not subject to
> archiving. Nothing else really matters.

> ᐧ
>


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to
archiving. Nothing else really matters.

Your attach call adds a ref to the lower device which is released when you detach

Sent from Outlook Mailhttp: for Windows 10 phone

From: Jamey Kirbymailto:xxxxx
Sent: Sunday, December 27, 2015 8:06 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] PNP remove device question/clarification

Ooops. I found where it deletes the device in diskperf and sends to lower driver. I am not sure how I missed this. Sorry.

//
// Forward the Removal Irp below as per the DDK
// We aren’t required to complete this Irp status should
// be the return status from the next driver in the stack
//
status = DiskPerfSendToNextDriver(DeviceObject, Irp);

//
//Detach us from the stack
//

IoDetachDevice(deviceExtension->TargetDeviceObject);
IoDeleteDevice(DeviceObject);
return status;

[https://mailfoogae.appspot.com/t?sender=aa2lyYnkuamFtZXlAZ21haWwuY29t&type=zerocontent&guid=ce5d5d27-f455-44bc-bdcd-e8774efa44de]?

On Sun, Dec 27, 2015 at 10:49 AM, Jamey Kirby > wrote:
I am working on a driver that I did not write. I am reviewing the PNP handlers. It is a volume filter driver.

In this driver, on PNP remove device, the developer first sends the IRP to the lower driver synchronously. Upon return, the driver does some device extension cleanup, and then it calls IoDetachDevice() and then IoDeleteDevice().

Is this the correct sequence? What if the lower driver deletes its device object before returning up the chain? How will the IoDetachDevice() handle this?

Should the driver do its cleanup and detach first, and then send the request down the stack?

If you look at DiskPerf, it does not send the remove down the stack to the lower driver.

The MS documentation eludes to some trickiness to handle the remove call, but it is unclear.


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to archiving. Nothing else really matters.
[https://mailfoogae.appspot.com/t?sender=aa2lyYnkuamFtZXlAZ21haWwuY29t&type=zerocontent&guid=0317ce14-8228-4b75-9e33-10e29ecd9c6b]?


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to archiving. Nothing else really matters.
— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at</mailto:xxxxx></mailto:xxxxx></http:>

Got it. Thanks.

On Sun, Dec 27, 2015 at 11:35 AM, Doron Holan
wrote:

> Your attach call adds a ref to the lower device which is released when you
> detach
>
>
>
> Sent from Outlook Mail http:
> for Windows 10 phone
>
>
>
>
> *From: *Jamey Kirby
> *Sent: *Sunday, December 27, 2015 8:06 AM
> *To: *Windows System Software Devs Interest List
> *Subject: *Re: [ntdev] PNP remove device question/clarification
>
>
> Ooops. I found where it deletes the device in diskperf and sends to lower
> driver. I am not sure how I missed this. Sorry.
>
> //
> // Forward the Removal Irp below as per the DDK
> // We aren’t required to complete this Irp status should
> // be the return status from the next driver in the stack
> //
> status = DiskPerfSendToNextDriver(DeviceObject, Irp);
>
> //
> //Detach us from the stack
> //
>
> IoDetachDevice(deviceExtension->TargetDeviceObject);
> IoDeleteDevice(DeviceObject);
> return status;
>
>
> ᐧ
>
> On Sun, Dec 27, 2015 at 10:49 AM, Jamey Kirby
> wrote:
>
>> I am working on a driver that I did not write. I am reviewing the PNP
>> handlers. It is a volume filter driver.
>>
>> In this driver, on PNP remove device, the developer first sends the IRP
>> to the lower driver synchronously. Upon return, the driver does some device
>> extension cleanup, and then it calls IoDetachDevice() and then
>> IoDeleteDevice().
>>
>> Is this the correct sequence? What if the lower driver deletes its device
>> object before returning up the chain? How will the IoDetachDevice() handle
>> this?
>>
>> Should the driver do its cleanup and detach first, and then send the
>> request down the stack?
>>
>> If you look at DiskPerf, it does not send the remove down the stack to
>> the lower driver.
>>
>> The MS documentation eludes to some trickiness to handle the remove call,
>> but it is unclear.
>>
>> –
>> Jamey Kirby
>> Disrupting the establishment since 1964
>>
>> This is a personal email account and as such, emails are not subject to
>> archiving. Nothing else really matters.

>> ᐧ
>>
>
>
>
> –
> Jamey Kirby
> Disrupting the establishment since 1964
>
> This is a personal email account and as such, emails are not subject to
> archiving. Nothing else really matters.

> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at
>


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to
archiving. Nothing else really matters.
</http:>

Since the KMDF sources are now on Github, perhaps Microsoft would also make public the detailed PNP/power state diagrams they have shown at talks, but in the past would not make public.

On Sun, Dec 27, 2015 at 7:49 AM -0800, “Jamey Kirby” > wrote:

I am working on a driver that I did not write. I am reviewing the PNP handlers. It is a volume filter driver.

In this driver, on PNP remove device, the developer first sends the IRP to the lower driver synchronously. Upon return, the driver does some device extension cleanup, and then it calls IoDetachDevice() and then IoDeleteDevice().

Is this the correct sequence? What if the lower driver deletes its device object before returning up the chain? How will the IoDetachDevice() handle this?

Should the driver do its cleanup and detach first, and then send the request down the stack?

If you look at DiskPerf, it does not send the remove down the stack to the lower driver.

The MS documentation eludes to some trickiness to handle the remove call, but it is unclear.


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to archiving. Nothing else really matters.
[https://mailfoogae.appspot.com/t?sender=aa2lyYnkuamFtZXlAZ21haWwuY29t&amp;type=zerocontent&amp;guid=0317ce14-8228-4b75-9e33-10e29ecd9c6b]?
— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at

> perhaps Microsoft would also make
public the detailed PNP/power state diagrams

Maybe they hide it for a reason. Maybe seeing it can be harmful for rest of us… like hinted here:

https://www.youtube.com/watch?v=xhk2LBrY91I

:wink:

I think you can have a look at this awesome explanation
http://www.wd-3.com/031504/AboutRemovalRelations.htm#line106

Cheers:)

Good read. Thanks!

On Tue, Dec 29, 2015 at 12:06 AM, wrote:

> I think you can have a look at this awesome explanation
> http://www.wd-3.com/031504/AboutRemovalRelations.htm#line106
>
> Cheers:)
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>


Jamey Kirby
Disrupting the establishment since 1964

This is a personal email account and as such, emails are not subject to
archiving. Nothing else really matters.
</http:>

for this special exist Remove Locks. read
https://msdn.microsoft.com/en-us/library/windows/hardware/ff565504(v=vs.85).aspx
and
https://msdn.microsoft.com/en-us/library/windows/hardware/ff549567(v=vs.85).aspx

“To allow queued I/O operations to complete, each driver should call IoReleaseRemoveLockAndWait AFTER it passes the IRP_MN_REMOVE_DEVICE request to the next-lower driver, and before it releases memory, calls IoDetachDevice, or calls IoDeleteDevice.”

interesting that early in documentation was error
“each driver should call IoReleaseRemoveLockAndWait BEFORE it passes the IRP_MN_REMOVE_DEVICE request to the next-lower driver”

really this may hang, if lower DeviceObject have not completed IRPs and complete it only when received IRP_MN_REMOVE_DEVICE
and your driver call IoAcquireRemoveLock on this Irp, set Completion routine and pass this Irp down - you call IoReleaseRemoveLock only when this IRP is complete, but it never complete, because lower DeviceObject never got IRP_MN_REMOVE_DEVICE - if you call IoReleaseRemoveLockAndWait BEFORE

also read this (first reply of Scott Noone)
http://www.osronline.com/showthread.cfm?link=250749

interesting if look for http://www.wd-3.com/031504/AboutRemovalRelations.htm
construction like
98: IoSkipCurrentIrpStackLocation(Irp);
99: status = IoCallDriver(devExt->nextLowerDevice, Irp);
100: IoReleaseRemoveLock(&devExt->RemoveLock, Irp);
incorrect (if Irp was not completed synchronous). IoReleaseRemoveLock need call only from CompletionRoutine and never call IoSkipCurrentIrpStackLocation (except IRP_MN_REMOVE_DEVICE)
and 85-88 lines:
here really need
86: Irp->IoStatus.Status = status:
87: IoSkipCurrentIrpStackLocation(Irp);// only here this is correct
88: status = IoCallDriver(devExt->nextLowerDevice, Irp);
85: IoReleaseRemoveLockAndWait(&devExt->removeLock, Irp); // after !!
89: sendDown = FALSE;

so usual case Filter and FDO deviceses:

// IoReleaseRemoveLockAndWait(&devExt->removeLock, Irp); //not before, can be hang here !!
Irp->IoStatus.Status = status:
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->nextLowerDevice, Irp);
IoReleaseRemoveLockAndWait(&devExt->removeLock, Irp); // after !!
IoDetachDevice(devExt->nextLowerDevice);
IoDeleteDevice(DeviceObject);

however exist (for my think) else one variant - i always register FastIoDetachDevice and call IoDetachDevice/IoDeleteDevice in this function. so in DispatchPNP i have only this code:

case IRP_MN_REMOVE_DEVICE:
IoSkipCurrentIrpStackLocation(Irp);
return IofCallDriver(devExt->nextLowerDevice, Irp);

and
VOID FastIoDetachDevice(PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice)
{
DEV_EXTENSION* pExt = DEV_EXTENSION::get(SourceDevice);
IoReleaseRemoveLockAndWait(pExt, 0);
IoDetachDevice(TargetDevice);
IoDeleteDevice(SourceDevice);
}
// FastIoDetachDevice called from IoDeleteDevice for TargetDevice

Your attach call adds a ref to the lower device which is released when you detach
this not exactly true DeviceObject->ReferenceCount is incremented when FileObject created on Device, but not on Attach. however until DeviceObject->AttachedDevice not zero - DeviceObject will be not deleted. so in wide sence this is true

I actually forgot I wrote that.

Mark Roddy

On Tue, Dec 29, 2015 at 12:06 AM, wrote:

> I think you can have a look at this awesome explanation
> http://www.wd-3.com/031504/AboutRemovalRelations.htm#line106
>
> Cheers:)
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

@Mark :stuck_out_tongue: :smiley: