Upper filter for USB hub

Hi everyone.
I wrote an upper filter driver for a USB hub.
In dispatch functions for IRP_MJ_PNP and IRP_MJ_POWER, I simply skip the current stack location and pass the request down to the underlying driver (the hub's functional driver).
For other IRPs, I use a defaultdispatch function that completes the current IRP.
However, I don't quite understand why the USB hub continues to function fully given that I am completing the request and thereby stopping further data transmission.(When I plug USB flash memory on, I can read and write to(from) flash)

How all USB packets (IRP_MJ_INTERNAL_DEVICE_CONTROL) reach the USB hub?
Only dispatch routines for pnp and power are invoked.

The hub HARDWARE continues to operate just fine. It doesn't care about drivers. Remember, you're only seeing traffic from above you. The hub driver submits URBs to listen for activity from the hub hardware. When new devices are plugged in, that causes traffic that completes one of its requests. In response, it creates a new device object, which in turn triggers a series of IRP_MJ_PNP requests and eventually loads a new driver.

Once that new driver has been loaded and initialized, only then will it start to send URBs to the hub driver. That's the first traffic from above, so it's the first point where you are interfering.

Which drivers are you filtering?

Thank you, Mr. Tim.
Could you explain how an IRP reaches the upper filter of a bus driver?
When a device (for example, a USB device) is connected, the bus driver (the hub function driver) creates a PDO for this new device. IRPs containing data (e.g., for a USB flash drive) pass through the device's own drivers (FDOs), then through the PDO created by the hub driver, and finally reach the hub driver (the FDO at the hub device node). How does an IRP end up in my filter driver? I attached my filter to the hub driver using IoAttachDeviceToDeviceStack() within my filter driver's AddDevice routine; however, when the hub driver creates a PDO for connected devices, how does it position my filter between the PDO and the FDO?
I ask this because, with my filter driver installed, DbgView displays all IRPs passing through it; yet, I do not see any IRP_MJ_INTERNAL_DEVICE_CONTROL requests (which I assume should handle URBs), nor any other IRP_MJ_INTERNAL_DEVICE_CONTROL requests reaching my dispatch functions. Meanwhile, the USB devices continue to function normally. I therefore conclude that these IRPs are not reaching my filter driver.
By the way, why does DbgView display messages from the AddDevice routine before those from DriverEntry? I did not observe this behavior when I was developing an NDIS filter driver.
And one final question:
In the DispatchPnp routine, an IRP_MJ_PNP request shows a minor code of 0x18. At the same time, Driver Verifier is not enabled.

Your FDO filter does not see any IRPs destined for the PDOs enumerated by the FDO. Each PDO is the start of a separate device stack with its own FDO. If you need to filter those PDOs you either have a FDO filter driver for each device type enumerated by the bus FDO, or have your bus FDO filter attach to each PDO on creation as a bus filter driver. The bus filter driver is the correct approach. It can be done using WDF as the base for the bus FDO filter, and then a WDM portion for the PDO filters.

Thank You Mr.Mark.That is exactly what I was hoping to hear. mr.Mark. I can not find any tutorial for writing filter drivers. My only book is microsoft WDM doc. Why You suggest to write using WDF. I already have writen a filter for bus FDO using WDM. I have done it using source code of WinPcap. Is it nessesary to do using WDF? I do not know WDF very wel yet.
Mr.Mark. If the bus FDO filter does not see IRPs designed for PDOs enumerated by the bus FDO, in that time for what is the bus upper FDO filter.

It is not uncommon for a PDO and FDO to be handled by the same driver, and in many cases the transmission from PDO to FDO is done by a function call, rather than another IoCallDriver call.

Despite using the same name, NDIS filter drivers are NOT PnP filter drivers. They're non-PnP drivers that the NDIS driver manages as a stack of filters. They don't sit in the IRP stream. The same rules do not apply.

The AVStream stack also uses the term "filter" as a third unrelated meaning.

Can anyone say what the second parameter (PhysicalDeviceObject) represents for the AddDevice function of an FDO upper filter?

NTSTATUS UsbHubFilterAddDevice(_In_ PDRIVER_OBJECT  driverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)

Is it pointer to PDO, FDO or may be another upper FiDO?
Thanks.

It will be whatever driver is below you in the stack. You need to pass this to IoAttachDeviceToDeviceStack after you IoCreateDevice.

HOWEVER, you should be using WDF, which takes care of all of this for you.

1 Like

WDF will not take care of adding a filter device object to a PDO. If @Arsen is trying to filter PDOs he needs to use WDM.

1 Like

Thank you for your replies. Mr. Tim, I output the value of PhysicalDeviceObject and the value returned by IoAttachDeviceToDeviceStack — they turned out to be different.
The documentation states: "The IoAttachDeviceToDeviceStack routine attaches the caller's device object to the highest device object in the chain and returns a pointer to the previously highest device object." I suspect that the second parameter of IoAttachDeviceToDeviceStack (TargetDevice) and second parameter of UsbHubFilterAddDevice (PhysicalDeviceObject) is not necessarily the object located immediately below, but rather something else within the device node(may be PDO). Am I correct?

Something I faund in book "Programming the microsoft windows driver model" by Walter Oney, page 21, Figure 2-9. It is possible that URB requests bypass the hub.

@Arsen Take a look at this:

Maybe it also makes sense to you.

Right. You send your IRPs to whatever IoAttachDeviceToDeviceStack returns. The PDO is the base of the stack of drivers, but that API will bubble up through the current stack to find the one currently at the top.