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