USB composite device driver loading order problem

I have composite USB devices that support multiple protocols: HID and a vendor specific class “A”.
I am using windows 7 x64.

For a given set of VID/PID the device may enumerate in either of the two following configurations:

cfg 1:
VID_xxxx&PID_yyyy&MI_00 = class A
VID_xxxx&PID_yyyy&MI_01 = HID

cfg 2:
VID_xxxx&PID_yyyy&MI_00 = class A
VID_xxxx&PID_yyyy&MI_01 = class A

The fact that two configurations share a unique set of VID/PID is not of my choosing; the host/device applications were originally written for a different OS which “allowed” such scenario. I am porting it to windows.

I developed the functional driver for class A (KMDF).To accommodate both cfgs, I defined the inf file to match cfg 2.

1)When I install the driver package unsigned I observe the following in device manager:

-When I plug in a device exposing cfg 1:
->interface #0 is assigned to class A functional driver.
->interface #1 is assigned to the HID kernel driver.

-When I plug in a device exposing cfg 2:
->interface #0 and #1 are assigned to class A functional driver.

This serves its purpose. Everything works perfectly in user mode also.

2)The problem I am having is when I install the signed driver package.

-When I plug in a device exposing cfg 1:
->interface #0 and #1 are both assigned to class A functional driver.

Under windbg, the configuration descriptors for both interfaces are a “mixed” bag:

for interface #0 it contains:
-interface #1 descriptor data (expect for interface number being 0)
-the HID descriptor.(but not the interrupt endpoint descriptor).

for interface #1 it matches the USB trace. (i.e. interface + HID + interrupt endpoint descriptors)

Is there a way to make the installation of the signed package works like in case 1?. From a user perspective (case 1), I get the windows red warning message asking me if I really want to install the driver because it is not signed. I am wondering if that, somehow, gives the kernel “enough” time to figure out that interface #0 really belongs to the HID class.

For case (2) there is no pause (i.e. windows red warning prompt) in the install so I am wondering if I am just getting lucky in case 1 and such configuration is not allowed under windows. In which case I am screwed. :frowning:
If I tamper with the inf file from case 2 (just removing a comment to cause a signature mismatch) then I get the windows red prompt (just like in case 1) and everything works also like in case 1 as far as driver assignments are concerned. ?

Thank you in advance for any help I may get.

When a new device is detected, Windows looks for an existing devnode and if it finds one, it re-uses that devnode instead of going through a installation process. Since the devnode is identified by the device instance id which does not contain the class/compat id, in this case, Windows is going to use the wrong driver for whichever config shows up later as it is going to try to use the cached devnode. I am guessing that the unsigned case happens to work because Windows probably treats the unsigned driver same as no driver and always goes through a re-installation process. I am not sure if there is some other INF trick by which Windows can be instructed to always look for a re-installation.
If there is flexibility to change the device/firmware, either using a different VID/PID or assigning a different interface number for the second interface in the two configs will work. Assuming it is not feasible to change the device, one option would be to write a replacement for usbccgp which will ensure that the instance id for the second interface is different in two configurations. Since writing a ccgp replacement is considerable work, another option would be to install a custom driver on the second interface which then enumerates a child (again with different instance id for the two configs) on which the actual driver loads. This custom driver can simply pass everything form the child to the parent stack.

Date: Fri, 18 Dec 2015 17:02:21 -0500
From: xxxxx@live.com
To: xxxxx@lists.osr.com
Subject: [ntdev] USB composite device driver loading order problem

I have composite USB devices that support multiple protocols: HID and a vendor specific class “A”.
I am using windows 7 x64.

For a given set of VID/PID the device may enumerate in either of the two following configurations:

cfg 1:
VID_xxxx&PID_yyyy&MI_00 = class A
VID_xxxx&PID_yyyy&MI_01 = HID

cfg 2:
VID_xxxx&PID_yyyy&MI_00 = class A
VID_xxxx&PID_yyyy&MI_01 = class A

The fact that two configurations share a unique set of VID/PID is not of my choosing; the host/device applications were originally written for a different OS which “allowed” such scenario. I am porting it to windows.

I developed the functional driver for class A (KMDF).To accommodate both cfgs, I defined the inf file to match cfg 2.

1)When I install the driver package unsigned I observe the following in device manager:

-When I plug in a device exposing cfg 1:
->interface #0 is assigned to class A functional driver.
->interface #1 is assigned to the HID kernel driver.

-When I plug in a device exposing cfg 2:
->interface #0 and #1 are assigned to class A functional driver.

This serves its purpose. Everything works perfectly in user mode also.

2)The problem I am having is when I install the signed driver package.

-When I plug in a device exposing cfg 1:
->interface #0 and #1 are both assigned to class A functional driver.

Under windbg, the configuration descriptors for both interfaces are a “mixed” bag:

for interface #0 it contains:
-interface #1 descriptor data (expect for interface number being 0)
-the HID descriptor.(but not the interrupt endpoint descriptor).

for interface #1 it matches the USB trace. (i.e. interface + HID + interrupt endpoint descriptors)

Is there a way to make the installation of the signed package works like in case 1?. From a user perspective (case 1), I get the windows red warning message asking me if I really want to install the driver because it is not signed. I am wondering if that, somehow, gives the kernel “enough” time to figure out that interface #0 really belongs to the HID class.

For case (2) there is no pause (i.e. windows red warning prompt) in the install so I am wondering if I am just getting lucky in case 1 and such configuration is not allowed under windows. In which case I am screwed. :frowning:
If I tamper with the inf file from case 2 (just removing a comment to cause a signature mismatch) then I get the windows red prompt (just like in case 1) and everything works also like in case 1 as far as driver assignments are concerned. ?

Thank you in advance for any help I may get.


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

@ Vivek Gupta

>another option would be to install a custom driver on the second interface which then enumerates a child (again with different instance id for the two configs) on which the actual
driver loads. This custom driver can simply pass everything form the child to the parent stack. <<

Could you please elaborate on this and point me to some example (if any) or reading ? I am not clear on what this actually work to do. thank you.

I am not sure if there is an example for it but what I am suggesting is the following: Write a function driver that matches on VID_xxxx&PID_yyyy&MI_01. From this driver, enumerate a PDO that inherits all properties of the parent stack except the hardware id. The hardware ID of the child should be different based on whether the second interface is for HID or class A. Perhaps add a suffix to the parent hardware id. The compat id should be same as the parent. The real function driver (HID or class A) gets installed on the child stack.
All IO and Query Interface requests received on the child PDO should be passed to the parent FDO stack. The parent stack should be setup for S0Idle such that it goes to idle whenever the child stack is in Dx.

Date: Fri, 18 Dec 2015 21:10:27 -0500
From: xxxxx@live.com
To: xxxxx@lists.osr.com
Subject: RE:[ntdev] USB composite device driver loading order problem

@ Vivek Gupta
>>another option would be to install a custom driver on the second interface which then enumerates a child (again with different instance id for the two configs) on which the actual
driver loads. This custom driver can simply pass everything form the child to the parent stack. <<

Could you please elaborate on this and point me to some example (if any) or reading ? I am not clear on what this actually work to do. thank you.


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