Attach to arbitrary device interface

Hello

Can I register pnp notification with IoRegisterPlugPlayNotification and from notification callback attach to device for interface with IoAttachDeviceToDeviceStackSafe ?
Is it legal ?
If someone opened interface already and sending requests below me it is ok. I only interested in new open requests.

The short answer is “no”. You can only attach to the top of s driver stack, but even if you were the top, for PnP, you can’t legally attach a driver after the stack has been built. If you’re a filter, why can’t you attach yourself as a normal filter through the registry?

Thank you Tim !

@Tim_Roberts said:
you can’t legally attach a driver after the stack has been built.
Could you please explain why ?

If you’re a filter, why can’t you attach yourself as a normal filter through the registry?
For parallel port PNP filter’s AddDevice called for ParallelPort0. Later function driver creates interface Parallel0. There is no AddDevice calls for interfaces. And LPT1 is actually link to Parallel0 and not ParallelPort0. So I can’t control open requests for parallel port from pnp filter.

Could you please explain why?

Because PnP has already sent all of its initialization and state managment requests down the stack and back up. You don’t have the state information you need.

Later function driver creates interface Parallel0.

I don’t know what that means. Kernel device interfaces are GUIDs. They don’t have names. Are you saying it creates a child device called Parallel0? The child device must have a device ID, and if it has a device ID, you can install a filter driver on it through the registry. Or are you saying it creates a symbolic link?

@Tim_Roberts said:

Could you please explain why?

Because PnP has already sent all of its initialization and state managment requests down the stack and back up. You don’t have the state information you need.

Do I need any state information if I only want to filter open requests ?

Later function driver creates interface Parallel0.

I don’t know what that means. Kernel device interfaces are GUIDs. They don’t have names. Are you saying it creates a child device called Parallel0? The child device must have a device ID, and if it has a device ID, you can install a filter driver on it through the registry. Or are you saying it creates a symbolic link?

I don’t really know much about interfaces but they are created by IoRegisterDeviceInterface. In user-mode I can use Setup API to enumerate device interfaces by interface GUID and open device with the path I got.

An interface is just a symbolic link to an existing device. It doesn’t create a new device. FIle opens to the symbolic link will cause an IRP_MJ_CREATE IRP to the same driver that created the interface.

So, where exactly do you see the names “Parallel0” and “ParallelPort0”? They aren’t hardware IDs and they aren’t interfaces.

@Tim_Roberts said:
So, where exactly do you see the names “Parallel0” and “ParallelPort0”? They aren’t hardware IDs and they aren’t interfaces.

I register my filter as upper filter for
Ports (COM & LPT ports)
Class = Ports
ClassGuid = {4d36e978-e325-11ce-bfc1-08002be10318}

My AddDevice called for stack

!devstack \Device\ParallelPort0
!DevObj !DrvObj !DevExt ObjectName
ffffb70dcf95c060 \Driver\Parport ffffb70dcf95c1b0 ParallelPort0
ffffb70dcf2e4d30 \Driver\ACPI ffffb70dcd972020 0000006c
!DevNode ffffb70dcf2f3c10 :
DeviceInst is “ACPI\PNP0400\1”
ServiceName is “Parport”

And only for that device.

However if someone does CreateFile(“LPT1”) he will open another device:
!object \GLOBAL??\LPT1
Object: ffffdd855ad46470 Type: (ffffb70dcd85b8f0) SymbolicLink
ObjectHeader: ffffdd855ad46440 (new version)
HandleCount: 0 PointerCount: 1
Directory Object: ffffdd855a4321d0 Name: LPT1
Flags: 00000000 ( Local )
Target String is ‘\Device\Parallel0’

0: kd> !devstack \Device\Parallel0
!DevObj !DrvObj !DevExt ObjectName
ffffb70dcffa1070 \Driver\Parport ffffb70dcffa11c0 Parallel0
!DevNode ffffb70dcfc18cb0 :
DeviceInst is “LPTENUM\MicrosoftRawPort\6&1d62032d&0&LPT1”

I could see open requests for \Device\ParallelPort0 (there is none), but can’t see opens for \Device\Parallel0.

So I thought that maybe I can intercept device interface arrival with IoRegisterPlugPlayNotification, open target device (\Device\Parallel0) with symbolic link I get from DEVICE_INTERFACE_CHANGE_NOTIFICATION and attach to that device with IoAttachDeviceToDeviceStackSafe.