WinUSB, accessing different interfaces from different processes

Dear ntdev members,

I’m currently trying to fully understand the limitations of the WinUSB
driver development related to a - maybe - future scenario.
I have problems to clarify one last question and hope to get some more
information on this list here.

If we have a USB device with 2 interfaces (composite device), providing
an IAD, it seems we have to replace the windows composite device driver
(usbccgp.sys) to access all interfaces.
Regarding the future scenario we might have one process accessing both
interfaces, but we might also have 2 processes instead, each one using
exactly one of these interfaces.

Having a look at
https://msdn.microsoft.com/en-us/library/windows/hardware/dn376885(v=vs.85).aspx
I find the info that

  • WinUSB functions allow one application at a time to communicate with
    the device
    but also that
  • For multifunction devices, you can use the device’s INF file to
    specify either an in-box kernel-mode driver or Winusb.sys for each USB
    function separately

Having a look at https://www.osronline.com/article.cfm?article=532 I
find the info that a WinUSB limitation is that it does not support
multiple concurrent applications.

After this I’m not sure: Is it possible to use WinUSB in combination
with 2 processes accessing the device, but each one using another
interface? I mean… it’s not really a concurrent application then.
If this is possible, where can I find more information about the
necessary inf file adaptions described at the msdn page above?
(especially for replacing the usbccgp)

Maybe someone can point me into the right direction?
Thank you,
Matthias

You conclusion is correct i.e. you cannot concurrently access two different interfaces of the same function from two different Winusb applications using the inbox usbccgp.
However, the question is that why is the device tying the interfaces into one function then? If these interfaces are truly related and need to be coordinated, it does make sense for one entity (be that a winusb app or some other driver) to control both of these interfaces.
It is correct that winusb doesn’t provide concurrent access to apps because it doesn’t know the right multiplexing policy for the function (for e.g. you might need to have multiple readers- one writer, or multiple writers) . If your scenario does require multiple apps concurrently accessing the same function (regardless of how many interfaces are there in the function), you should consider writing a WDF (hopefully UMDF) driver that can then expose the right interface for the apps and multiplex their access in the desired manner.

To: xxxxx@lists.osr.com
From: xxxxx@lauterbach.com
Subject: [ntdev] WinUSB, accessing different interfaces from different processes
Date: Fri, 15 Jan 2016 11:20:18 +0100

Dear ntdev members,

I’m currently trying to fully understand the limitations of the WinUSB
driver development related to a - maybe - future scenario.
I have problems to clarify one last question and hope to get some more
information on this list here.

If we have a USB device with 2 interfaces (composite device), providing
an IAD, it seems we have to replace the windows composite device driver
(usbccgp.sys) to access all interfaces.
Regarding the future scenario we might have one process accessing both
interfaces, but we might also have 2 processes instead, each one using
exactly one of these interfaces.

Having a look at
https://msdn.microsoft.com/en-us/library/windows/hardware/dn376885(v=vs.85).aspx
I find the info that

  • WinUSB functions allow one application at a time to communicate with
    the device
    but also that
  • For multifunction devices, you can use the device’s INF file to
    specify either an in-box kernel-mode driver or Winusb.sys for each USB
    function separately

Having a look at https://www.osronline.com/article.cfm?article=532 I
find the info that a WinUSB limitation is that it does not support
multiple concurrent applications.

After this I’m not sure: Is it possible to use WinUSB in combination
with 2 processes accessing the device, but each one using another
interface? I mean… it’s not really a concurrent application then.
If this is possible, where can I find more information about the
necessary inf file adaptions described at the msdn page above?
(especially for replacing the usbccgp)

Maybe someone can point me into the right direction?
Thank you,
Matthias


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

Matthias Bußjäger wrote:

If we have a USB device with 2 interfaces (composite device), providing
an IAD, it seems we have to replace the windows composite device driver
(usbccgp.sys) to access all interfaces.

Have you tried this? Usbccgp.sys does have some understanding of IADs.
If you have a UVC or UAC device, for example, it assigns all of the
related interfaces to a single driver. It used to have special code
specifically for UVC and UAC, but I thought that had been generalized to
all IAD devices.

You then use WinUsb_GetAssociatedInterface to switch between interfaces.

Regarding the future scenario we might have one process accessing both
interfaces, but we might also have 2 processes instead, each one using
exactly one of these interfaces.

If the interfaces can be used separately, then it seems to me it is a
design flaw for you to have an IAD.

Having a look at https://www.osronline.com/article.cfm?article=532 I
find the info that a WinUSB limitation is that it does not support
multiple concurrent applications.

That’s not terribly hard to work around. You can write a server app or
Windows service to own the device, and have a simple interface DLL that
communicates with the server using one of the many interprocess
communication schemes. Even an out-of-process COM server would work.
If you really like the driver model, you can write a UMDF driver, which
can talk to multiple applications on top, and route to WinUSB below.

If this is possible, where can I find more information about the
necessary inf file adaptions described at the msdn page above?
(especially for replacing the usbccgp)

That’s easy. Remember the process that Device Manager goes through.
Say you have a device with VID = 1234 and PID = 5678, with 4
interfaces. The USB hub driver creates a PDO called
USB\VID_1234&PID_5678, and Device Manager goes out to the INF database
to find a driver. If it finds one (like your custom driver), it loads
one, and the driver process is finished. If it doesn’t find one, then
for a composite device it tries the compatible device ID USB\COMPOSITE.
That ID matches usbccgp.sys. Usbccgp.sys will then enumerate the
individual interfaces, and create PDOs called
USB\VID_1234&PID_5678&MI_00 and USB\VID_1234&PID_5678&MI_01, etc.
Device Manager then goes out to look for each of those, and will find
your individual interface drivers.

So, if you want usbccgp.sys, don’t match USB\VID_1234&PID_5678.
Instead, match the individual interfaces (…&MI_00). If you don’t want
usbccgp.sys, then write your INF to match the composite device,
USB\VID_1234&PID_5678. At that point, it’s entirely up to your driver
to decide what to do with the interfaces.

Note, however, that you can’t easily switch back and forth. Once you’ve
made the choice, it gets cached.


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

Thank you Vivek and Tim for your answers!
Please also see my comments below.

> If we have a USB device with 2 interfaces (composite device), providing
> an IAD, it seems we have to replace the windows composite device driver
> (usbccgp.sys) to access all interfaces.
Have you tried this? Usbccgp.sys does have some understanding of IADs.
If you have a UVC or UAC device, for example, it assigns all of the
related interfaces to a single driver. It used to have special code
specifically for UVC and UAC, but I thought that had been generalized to
all IAD devices.

You then use WinUsb_GetAssociatedInterface to switch between interfaces.
Hmmm, i tried this… windows automatically installed the usbccgp.sys
and added an unknown device in the device manager.
I tried different inf files, e.g. with the usage of MI_00 and MI_01 or
without, but I wasn’t able to get access to another interface than 0 or
install a driver for another interface than this one.
In the registry (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB) I
just found one entry VID_xxxx&PID_xxxx&MI_00.
Might this be related to the described behaviour and maybe a reason that
I needed to replace the usbccgp.sys?
> Regarding the future scenario we might have one process accessing both
> interfaces, but we might also have 2 processes instead, each one using
> exactly one of these interfaces.
If the interfaces can be used separately, then it seems to me it is a
design flaw for you to have an IAD.
OK, this was not the very best example.
But it works with 3 interfaces, doesn’t it? Two handled by the IAD and
used by one process, the third interface handled by another process?
> Having a look at https://www.osronline.com/article.cfm?article=532 I
> find the info that a WinUSB limitation is that it does not support
> multiple concurrent applications.
That’s not terribly hard to work around. You can write a server app or
Windows service to own the device, and have a simple interface DLL that
communicates with the server using one of the many interprocess
communication schemes. Even an out-of-process COM server would work.
If you really like the driver model, you can write a UMDF driver, which
can talk to multiple applications on top, and route to WinUSB below.
I don’t like the driver model, but I also thought about the possibility
to use a kind of server. Thank you.
> If this is possible, where can I find more information about the
> necessary inf file adaptions described at the msdn page above?
> (especially for replacing the usbccgp)
That’s easy. Remember the process that Device Manager goes through.
Say you have a device with VID = 1234 and PID = 5678, with 4
interfaces. The USB hub driver creates a PDO called
USB\VID_1234&PID_5678, and Device Manager goes out to the INF database
to find a driver. If it finds one (like your custom driver), it loads
one, and the driver process is finished. If it doesn’t find one, then
for a composite device it tries the compatible device ID USB\COMPOSITE.
That ID matches usbccgp.sys. Usbccgp.sys will then enumerate the
individual interfaces, and create PDOs called
USB\VID_1234&PID_5678&MI_00 and USB\VID_1234&PID_5678&MI_01, etc.
Device Manager then goes out to look for each of those, and will find
your individual interface drivers.

So, if you want usbccgp.sys, don’t match USB\VID_1234&PID_5678.
Instead, match the individual interfaces (…&MI_00). If you don’t want
usbccgp.sys, then write your INF to match the composite device,
USB\VID_1234&PID_5678. At that point, it’s entirely up to your driver
to decide what to do with the interfaces.

Note, however, that you can’t easily switch back and forth. Once you’ve
made the choice, it gets cached.

As I wrote above, only (USB\VID_1234&PID_5678 and)
USB\VID_1234&PID_5678&MI_00 are created, nothing for the other interface.
But of course the first try of driver installation was wrong and due to
the fact that you write it is cached this problem might be related to
this cache.
I used usbdeview to ensure the driver is completely removed.
Additionally to this tool I deleted all USB\VID_1234&PID_5678 entries in
the registry. I hope this “cache” is deleted then!?

Matthias Bußjäger wrote:

Hmmm, i tried this… windows automatically installed the usbccgp.sys
and added an unknown device in the device manager.
I tried different inf files, e.g. with the usage of MI_00 and MI_01 or
without, but I wasn’t able to get access to another interface than 0 or
install a driver for another interface than this one.
In the registry (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB) I
just found one entry VID_xxxx&PID_xxxx&MI_00.

If you have an IAD, then this is exactly what I would expect. The MI_00
driver will be given ownership of both interfaces, and you should be
able to use WinUsb_GetAssociatedInterface to switch between them. This
is exactly how UAC and UVC drivers work.

OK, this was not the very best example.
But it works with 3 interfaces, doesn’t it? Two handled by the IAD and
used by one process, the third interface handled by another process?

Sure. That would be two separate drivers: one for MI_00 handling 0 and
1, and one for MI_02 handling 2.

I used usbdeview to ensure the driver is completely removed.
Additionally to this tool I deleted all USB\VID_1234&PID_5678 entries in
the registry. I hope this “cache” is deleted then!?

Maybe. It’s always dangerous to dink in the Enum tree. You should do a
superstitious reboot afterward.


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