Detachuing a specific DeviceObject from a Device stack

Is there a way to specify the device object to detach from a device stack thus undoing IoAttachDeviceToDeviceStack()?

IoDetachDevice() says ‘releases an attachment between the caller’s device object and a lower driver’s device object.’ but you might not necessarily want the callers DeviceObject to be detached but the one specified in the call to IoAttachDeviceToDeviceStack().

In the PnP kernel it is perfectly legal to create devices and attach them to stacks to filter many devices so lets say you have a driver that registers for PnP events and on device arrival of every instance of a class of device creates a device and attaches it to that stack how does it detach a specific filter device? Does the call to IoDetachDevice() have to happen in the instance of IRP_MN_REMOVE_DEVICE specific to that FDO?

Yes, for pnp stacks the only allowable context to detach is in processing remove device.

Bent by my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@hotmail.com
Sent: Friday, November 11, 2016 4:45:52 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Detachuing a specific DeviceObject from a Device stack

Is there a way to specify the device object to detach from a device stack thus undoing IoAttachDeviceToDeviceStack()?

IoDetachDevice() says ‘releases an attachment between the caller’s device object and a lower driver’s device object.’ but you might not necessarily want the callers DeviceObject to be detached but the one specified in the call to IoAttachDeviceToDeviceStack().

In the PnP kernel it is perfectly legal to create devices and attach them to stacks to filter many devices so lets say you have a driver that registers for PnP events and on device arrival of every instance of a class of device creates a device and attaches it to that stack how does it detach a specific filter device? Does the call to IoDetachDevice() have to happen in the instance of IRP_MN_REMOVE_DEVICE specific to that FDO?


NTDEV is sponsored by OSR

Visit the list online at: http:

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

What problem exactly are you trying to solve?

>In the PnP kernel it is perfectly legal to create devices and attach them to stacks to filter many devices so lets say you have a driver that registers for PnP events and on device arrival of every instance of a class of device creates a device and attaches it to that stack how does it detach a specific filter device?

Sorry, but I do not agree, filters are registered with the registry. When a filter driver is registered with the registry, the filter’s EvtDriverDeviceAdd is called by the PNP Manager (for a PNP device) and that is where the filter driver tells the framework that it is a filter driver by calling WdfFdoInitSetFilter. The filter than calls WdfDeviceCreate and the framework does the attachement on top of the underrlying PDO’s stack for the filter driver. You do not need to worry about detachment then.

https://msdn.microsoft.com/en-us/windows/hardware/drivers/install/installing-a-filter-driver

You cannot detach a filter randomly, there is no way to know if another
filter attached above you. Your understanding of the PnP model is flawed,
the only safe time to remove a filter is when IRP_MN_REMOVE device is
active.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Friday, November 11, 2016 7:46 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Detachuing a specific DeviceObject from a Device stack

Is there a way to specify the device object to detach from a device stack
thus undoing IoAttachDeviceToDeviceStack()?

IoDetachDevice() says ‘releases an attachment between the caller’s device
object and a lower driver’s device object.’ but you might not necessarily
want the callers DeviceObject to be detached but the one specified in the
call to IoAttachDeviceToDeviceStack().

In the PnP kernel it is perfectly legal to create devices and attach them to
stacks to filter many devices so lets say you have a driver that registers
for PnP events and on device arrival of every instance of a class of device
creates a device and attaches it to that stack how does it detach a specific
filter device? Does the call to IoDetachDevice() have to happen in the
instance of IRP_MN_REMOVE_DEVICE specific to that FDO?


NTDEV is sponsored by OSR

Visit the list online at:
http:

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

@Don “Your understanding of the PnP model is flawed,
the only safe time to remove a filter is when IRP_MN_REMOVE device is
active.”

Which is what I said. Try to read the whole question before criticising.

@Doran, thanks, that’s what I thought.

@D.T Interesting reply.
A filter driver registered in the registry allows you to insert your filter at a specific point in the stack. However, if your driver called IoAttachDeviceToDeviceStack() from a non registered filter driver it would just be the top level DO. What problems do you foresee doing this?

@Alex Just trying out a few ideas to help define an architecture.

1 components in the stack that capture top of attack earlier will not see your device
2 already open handles and in flight io will bypass your device
3 components that precomputed the required StackSize for the stack will not update to account for your device

And the list goes on…

Get Outlook for Android


From: xxxxx@lists.osr.com on behalf of xxxxx@hotmail.com
Sent: Monday, November 21, 2016 1:55:13 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Detachuing a specific DeviceObject from a Device stack

@Don “Your understanding of the PnP model is flawed,
the only safe time to remove a filter is when IRP_MN_REMOVE device is
active.”

Which is what I said. Try to read the whole question before criticising.

@Doran, thanks, that’s what I thought.

@D.T Interesting reply.
A filter driver registered in the registry allows you to insert your filter at a specific point in the stack. However, if your driver called IoAttachDeviceToDeviceStack() from a non registered filter driver it would just be the top level DO. What problems do you foresee doing this?


NTDEV is sponsored by OSR

Visit the list online at: http:

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

@Doron, #1 True, but so would a filter lower down the stack, so not a problem in itself. #2 same as #1 but from the other perspective. #3 Since you aren’t in the stack below that component (as we know from #1) then the stack size below that component isn’t affected.

Anyway, its a moot point, I was only trying a few things out, but it doesn’t work for one very good reason, you cant insert your filter exactly where its needed.

What I was trying to do was insert a filter above the child PDO created by a USB bus driver FROM the USB bus driver, ie, after a QUERY RELATIONS where the list of child PDOs is exposed. Problem is the timing, you cant get the filter on that PDO reliably so I will use a variety of class filters instead.

>I was trying to do was insert a filter above the child PDO created by a USB
bus driver FROM the USB bus driver

You need to be on top of the USB FDO and process QUERY_RELATIONS, then you’ll be able attach the filter immediately before the new PDOs are reported to PNP.

>What problems do you foresee doing this?

I’ve made a test for a disk filter driver. When the PNP notification callback is invoked, a lot of PNP and IOCTL IRPs are already gone.

@Alex Yeah, that’s what I was doing. The problem is QUERY_RELATIONS gets called often, each time a device is removed from/added to, the hub, and it seems at random times by Windows during initialisation. Each time the child PDOs might vary, so the first thing the bus upper filter has to do is detach existing child PDO upper filters, then get the new list of child PDOs created, and attach to those. It was the detaching from the child PDOs that prompted this question, which isn’t possible, since the detach can only take place in the context of the child’s REMOVE_DEVICE event.

It just going to be easier to lower filter each class of device the requirements call for and check the USB stack for the USB version supported (the filters are only to be active on devices attached to a USB 3 HCD).

Anyway, its always an interesting exercise fiddling around to see what is and isn’t possible.

You’re doing it all wrong. You should keep track of all PDO reported; attach your PDO filter when the PDO is first reported, and delete it on REMOVE_DEVICE. That’s all.

@Alex, ‘You’re doing it all wrong’ Odd. You did read my question didn’t you? That’s exactly what I said in it.

Anyway, thanks for clarifying that Alex.

>Each time the child
PDOs might vary, so the first thing the bus upper filter has to do is detach
existing child PDO upper filters, then get the new list of child PDOs created,
and attach to those.

You don’t detach and reattach filter DO. You create new DO when necessary, and delete them on REMOVE_DEVICE (after detaching them by REMOVE_DEVICE rules).

Yes, I thought that was the way to do it when I asked ‘Does the call to IoDetachDevice() have to happen in the instance of
IRP_MN_REMOVE_DEVICE specific to that FDO?’

So again, thanks for confirming that Alex.

Interestingly the WDK says about IRP_MN_QUERY_DEVICE_RELATIONS: "BusRelations
When the PnP manager queries for the bus relations (child devices) of an adapter or controller, the bus driver must return a list of pointers to the PDOs of any devices physically present on the bus. The bus driver reports all devices, regardless of whether they have been started.

Warning A device object cannot be passed to any routine that takes a PDO as an argument until the PnP manager creates a device node (devnode) for that object. (If the driver does pass a device object, the system will bug check with Bug Check 0xCA: PNP_DETECTED_FATAL_ERROR.) The PnP manager creates the devnode in response to the IRP_MN_QUERY_DEVICE_RELATIONS request. The driver can safely assume that the PDO’s devnode has been created when it receives an IRP_MN_QUERY_RESOURCE_REQUIREMENTS request."

A function such as IoAttachDeviceToDeviceStack() for example. Yet it doesn’t BSOD.

@Alex, I am going to move the IoAttachToDeviceStack() to the return from IRP_MN_QUERY_RESOURCE_REQUIREMENTS just in case this is an issue.

IoAttachDeviceToDeviceStack() attaches a device object to any stack, whether it’s managed to PNP or not. It doesn’t care whether the stack starts on a PDO or on a custom device object.