Retrieve interface number in Windows driver

In my INF file I write following line to load interface number 01 from my composite USB device:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”

Now how do I retrieve this interface number in my driver? I can access the device instace ID by IWDFDevice::RetrieveDeviceInstanceId which would give me the interface number packed in a string:

“USB\VID_XXXX&PID_XXXX&MI_01\6&336AF67A&0&0002”

I could extract it from this string but there must be a more elegant way?

Make the INF set a registry value and read it in the driver.

This would blow up the content and decrease readability and maintainability of my INF file since it is written in a generic way because my driver supports several USB devices. I would have to define an install section an all neccessary subsequent sections for only the USB composite device.

Does your driver need to tell a composite device from non-composite one, or it need to tell an instance loaded on interface 1 from different interface number?

You should be able to retrieve to configuration descriptor, parse it to locate the interface descriptor and use the ‘bInterfaceNumber’.

xxxxx@igt.com wrote:

You should be able to retrieve to configuration descriptor, parse it to locate the interface descriptor and use the ‘bInterfaceNumber’.

It’s not that easy. If your INF matches a single interface, like MI_02,
the USB driver stack rewrites your configuration descriptor on your
behalf to fool you into thinking that you are the only interface on the
device.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I have more than one interface in the configuration descriptor. That is why
I have to know in advance which one i have to locate.

2017-06-30 17:52 GMT+02:00 :

> You should be able to retrieve to configuration descriptor, parse it to
> locate the interface descriptor and use the ‘bInterfaceNumber’.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

xxxxx@gmail.com wrote:

In my INF file I write following line to load interface number 01 from my composite USB device:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”

Now how do I retrieve this interface number in my driver?

Why do you care? Your driver is supposed to support the functionality
of that interface. Whether it is the only interface, or interface 1 of
7, or interface 6 of 7, none of that changes the functionality. Your
driver should not need that information.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> It’s not that easy. If your INF matches a single interface, like MI_02,

the USB driver stack rewrites your configuration descriptor on your
behalf to fool you into thinking that you are the only interface on the
device.

In fact this would be nice so I would only have one interface and could
pick this one. But USB driver stack does not rewrite configurations.
I see both interface in both instances of my driver. That is why I want to
differenciate between them by fetching the passed MI_0x value.

2017-06-30 18:36 GMT+02:00 Tim Roberts :

> xxxxx@igt.com wrote:
> > You should be able to retrieve to configuration descriptor, parse it to
> locate the interface descriptor and use the ‘bInterfaceNumber’.
>
> It’s not that easy. If your INF matches a single interface, like MI_02,
> the USB driver stack rewrites your configuration descriptor on your
> behalf to fool you into thinking that you are the only interface on the
> device.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Johnny Dakovo wrote:

> It’s not that easy. If your INF matches a single interface, like MI_02,
> the USB driver stack rewrites your configuration descriptor on your
> behalf to fool you into thinking that you are the only interface on the
> device.

In fact this would be nice so I would only have one interface and
could pick this one. But USB driver stack does not rewrite configurations.
I see both interface in both instances of my driver. That is why I
want to differenciate between them by fetching the passed MI_0x value.

Then you’ve done something wrong. This has been a fundamental feature
of USBCCGP.SYS from the very beginning. Do you, perhaps, match both the
composite device and the interface in your INF? For example, do you
have something like this in your INF?

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX”
“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”
“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_02”

If so, then you will always match for the composite device, and your
driver is expected to handle ALL of the interfaces.

Is it possible you started out using this as a single interface device,
and then switched to multi-interface? If so, you can get crud left over
in the registry that causes the system to load you for the composite
device. That is very difficult to clean up.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

In my INF file I have:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_00”
“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”

And yes at some point for this USB device there was only this line in my
INF file:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX”

So you mean I should never see more than one interface in my driver
instance when defining “…&MI_xx”?

2017-06-30 18:49 GMT+02:00 Tim Roberts :

> Johnny Dakovo wrote:
> > > It’s not that easy. If your INF matches a single interface, like
> MI_02,
> > > the USB driver stack rewrites your configuration descriptor on your
> > > behalf to fool you into thinking that you are the only interface on the
> > > device.
> >
> > In fact this would be nice so I would only have one interface and
> > could pick this one. But USB driver stack does not rewrite
> configurations.
> > I see both interface in both instances of my driver. That is why I
> > want to differenciate between them by fetching the passed MI_0x value.
>
> Then you’ve done something wrong. This has been a fundamental feature
> of USBCCGP.SYS from the very beginning. Do you, perhaps, match both the
> composite device and the interface in your INF? For example, do you
> have something like this in your INF?
>
> “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX”
> “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”
> “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_02”
>
> If so, then you will always match for the composite device, and your
> driver is expected to handle ALL of the interfaces.
>
> Is it possible you started out using this as a single interface device,
> and then switched to multi-interface? If so, you can get crud left over
> in the registry that causes the system to load you for the composite
> device. That is very difficult to clean up.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Johnny Dakovo wrote:

In my INF file I have:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_00”
“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”

And yes at some point for this USB device there was only this line in
my INF file:

“%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX”

So you mean I should never see more than one interface in my driver
instance when defining “…&MI_xx”?

Exactly, yes![1] You have been burned by a very nasty Windows problem.
It does not handle the case of a device that is first seen as a
single-interface device, and later transitions on the same system to a
multi-interface device. If you go into the registry in
CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx, the subkey that has your
device still has a Service name that identifies your service. Your
later INF added additional entries, but it didn’t touch that existing
composite entry, and because the system looks there first, that’s the
one that wins.

This is a difficult problem to clean up. What you’d like to do is
delete the VID_xxxx&PID_xxxx key (and its children), plus all of the
VID_xxxx&PID_xxxx&MI_xx keys (and their children). But for reasons that
are not entirely clear to me, even administrator does not have
permission to view or delete the Properties subkey. It is possible to
change the permissions to allow that, but it is a tedious process.
There are ways to load “regedit” as the LOCAL_SYSTEM user that can do it.

If this is a disposable machine where you can easily reinstall Windows
from scratch, that is the safest path. With a clean registry, the
problem will not occur.

As a hacky alternative, you can go into the first subkey of
Enum\USB\VID_xxxx&PID_xxx, and change the Service value to “usbccgp”.
Then, either reboot, or unplug and replug. That should do it as well.


[1} For the pedants in the audience, there are exceptions. If you have
an IAD descriptor that groups multiple interfaces together, or if you
are an audio-class or video-class device where interfaces are grouped
together, then usbccgp will hand you both interfaces. They will stay in
the same order as in the original descriptor, so the driver can tell
which is which.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hello Tim,

thanks for the explanation. I just checked it on a freshly installed
Windows 10 (so my driver was never installed before without MI_0X specifier
in its INF file) and my driver seems to always see both interfaces in both
instances. Maybe I am accessing it the wrong way. What I am doing is (UMDF
1.11; simplified code):

CComPtr m_FxDevice; //already initialized

CComPtr usbFactory = NULL;
CComPtr m_UsbTargetDevice = NULL;
CComPtr usbInterface = NULL;

m_FxDevice->QueryInterface(IID_PPV_ARGS(&usbFactory)); // getting usb
factory interface

usbFactory->CreateUsbTargetDevice(&m_UsbTargetDevice); // create usb
target device

// here I need to know which of the two interfaces i have to select
(bIndex)
// therefor I need to know which interface index was passed to my
driver instance
m_UsbTargetDevice->RetrieveUsbInterface(bIndex, &usbInterface);

// …

2017-06-30 19:33 GMT+02:00 Tim Roberts :

> Johnny Dakovo wrote:
> > In my INF file I have:
> >
> > “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_00”
> > “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX&MI_01”
> >
> > And yes at some point for this USB device there was only this line in
> > my INF file:
> >
> > “%DeviceName%=Device_Install, USB\VID_XXXX&PID_XXXX”
> >
> > So you mean I should never see more than one interface in my driver
> > instance when defining “…&MI_xx”?
>
> Exactly, yes![1] You have been burned by a very nasty Windows problem.
> It does not handle the case of a device that is first seen as a
> single-interface device, and later transitions on the same system to a
> multi-interface device. If you go into the registry in
> CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx, the subkey that has your
> device still has a Service name that identifies your service. Your
> later INF added additional entries, but it didn’t touch that existing
> composite entry, and because the system looks there first, that’s the
> one that wins.
>
> This is a difficult problem to clean up. What you’d like to do is
> delete the VID_xxxx&PID_xxxx key (and its children), plus all of the
> VID_xxxx&PID_xxxx&MI_xx keys (and their children). But for reasons that
> are not entirely clear to me, even administrator does not have
> permission to view or delete the Properties subkey. It is possible to
> change the permissions to allow that, but it is a tedious process.
> There are ways to load “regedit” as the LOCAL_SYSTEM user that can do it.
>
> If this is a disposable machine where you can easily reinstall Windows
> from scratch, that is the safest path. With a clean registry, the
> problem will not occur.
>
> As a hacky alternative, you can go into the first subkey of
> Enum\USB\VID_xxxx&PID_xxx, and change the Service value to “usbccgp”.
> Then, either reboot, or unplug and replug. That should do it as well.
>
> - - -
>
> [1} For the pedants in the audience, there are exceptions. If you have
> an IAD descriptor that groups multiple interfaces together, or if you
> are an audio-class or video-class device where interfaces are grouped
> together, then usbccgp will hand you both interfaces. They will stay in
> the same order as in the original descriptor, so the driver can tell
> which is which.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Johnny Dakovo wrote:

thanks for the explanation. I just checked it on a freshly installed
Windows 10 (so my driver was never installed before without MI_0X
specifier in its INF file) and my driver seems to always see both
interfaces in both instances. Maybe I am accessing it the wrong way.
What I am doing is (UMDF 1.11; simplified code):

Nothing in your code is going to affect this. Can you post your
descriptors? Do you have an IAD? Is it a well-known device class?

If you go into Device Manager, Properties, Details, Hardware IDs, does
your device ID include the MI_xx modifier?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.