IOCTL_USB_GET_NODE_INFORMATION and composite devices?

Hi,

I’m looking for a way to ask a composite device about the number of
children it has, akin to asking a hub about its number of ports.

In the usbview sample, IOCTL_USB_GET_NODE_INFORMATION is sent to a USB hub
device (GUID_DEVINTERFACE_USB_HUB) and it retrieves information about the
USB hub it is sent to – i.e. the returned
u.HubInformation.HubDescriptor.bNumberOfPorts is its own, not its parent’s.

However, MSDN keeps using this “parent” terminology:

On output, AssociatedIrp.SystemBuffer points to a USB_NODE_INFORMATION
structure that holds information about the parent device.

Now, even if I assume MSDN is misleading about the “parent” tidbit, how do
you use IOCTL_USB_GET_NODE_INFORMATION on a composite device? MSDN suggests
you should send it to GUID_DEVINTERFACE_USB_HUB (composite devices don’t
offer this interface!). I tried sending a IOCTL_USB_GET_NODE_INFORMATION
with NodeType = UsbMIParent to a composite device through
GUID_DEVINTERFACE_USB_DEVICE (the only devinterface composite devices seem
to offer), but all I got back was an empty reply (success, BytesReturned =
0).

So how are you supposed to use this IOCTL with composite devices? It seems
to be related.

P.S. Cross-posting from
http://stackoverflow.com/questions/8425450/ioctl-usb-get-node-information-and-composite-devices

Why not just enumerate the number of enumerated children with the CM_Xxx APIs? No need to query the driver. The MSDN docs talk about parent on terms of a pnp tree, not in USB spec terms

d

debt from my phone


From: Ilya Konstantinov
Sent: 12/7/2011 7:03 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] IOCTL_USB_GET_NODE_INFORMATION and composite devices?

Hi,

I’m looking for a way to ask a composite device about the number of children it has, akin to asking a hub about its number of ports.

In the usbview sample, IOCTL_USB_GET_NODE_INFORMATION is sent to a USB hub device (GUID_DEVINTERFACE_USB_HUB) and it retrieves information about the USB hub it is sent to – i.e. the returned u.HubInformation.HubDescriptor.bNumberOfPorts is its own, not its parent’s.

However, MSDN keeps using this “parent” terminology:

On output, AssociatedIrp.SystemBuffer points to a USB_NODE_INFORMATION structure that holds information about the parent device.

Now, even if I assume MSDN is misleading about the “parent” tidbit, how do you use IOCTL_USB_GET_NODE_INFORMATION on a composite device? MSDN suggests you should send it to GUID_DEVINTERFACE_USB_HUB (composite devices don’t offer this interface!). I tried sending a IOCTL_USB_GET_NODE_INFORMATION with NodeType = UsbMIParent to a composite device through GUID_DEVINTERFACE_USB_DEVICE (the only devinterface composite devices seem to offer), but all I got back was an empty reply (success, BytesReturned = 0).

So how are you supposed to use this IOCTL with composite devices? It seems to be related.

P.S. Cross-posting from http://stackoverflow.com/questions/8425450/ioctl-usb-get-node-information-and-composite-devices

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

You’re not supposed to. To the best of my knowledge, this IOCTL is supported only for hubs.

A composite USB device is NOT the same as a hub, and a hub is not a composite USB device. Sure, you can make a logical comparison of the two… but they’re not in any way the same from a USB standpoint.

A composite USB device is effectively two devices (two separate interfaces) that are simultaneously accessible within the same package. In general, these two separate interfaces are enumerated (in the PnP sense) by Windows as separate devices so that separate drivers can be loaded on each interface. There’s a bus driver that’s responsible for this… the USBCCGP driver.

What you need to do is retrieve the USB device descriptor, and then the interface descriptors. I have no clue how you do this from an application, if that’s what you’re trying to do.

Peter
OSR

On Thu, Dec 8, 2011 at 5:08 AM, Doron Holan wrote:

> Why not just enumerate the number of enumerated children with the CM_Xxx
> APIs? No need to query the driver. The MSDN docs talk about parent on terms
> of a pnp tree, not in USB spec terms
>

Doron, while my example was in usermode, I’m actually trying to get this
information from kernel mode (where walking devnodes is undocumented :).

I’m filtering the USB class. I need to know the maximum number of children
my device can have, in order to know the size to allocate for some array.
When I’m on top of a hub, I query the NumberOfPorts (through the above
IOCTL). Now, for composite devices, since this IOCTL won’t help me
(according to you and Peter), I’d request the configuration descriptor and
use bNumInterfaces ().

So ok, problem solved. I was just wondering what the MSDN meant with all
its UsbMIParent talk, cause this documentation led me on a wild goose
chase, and if it’s misleading, I’d love to send the MSDN maintainers a
correction.

(
) No composite device would have more children than interfaces, right?

I find the terminology you’re using confusing, and I’m not sure what you really want to do. You probably want to be sure to read the WDK docs on enumerating composite devices. Specifically, I’m confused by what you mean about “Children”… children in what respect?

As I tried to explain, composite devices don’t have “children” – A USB “device” is a physical container. For a composite device, that physical container contains one or more configurations, one of which has multiple Interfaces, and each interface can be used simultaneously (this is always true of USB Interfaces, btw… but not USB configurations).

SOME devices with multiple interfaces (depending on how the device is set up) are enumerated by the Windows USBCCGP bus driver (PnP parent). This driver enumerates each interface as if it were its own device, creating a PDO for each interface, allowing separate drivers to claim each of these PDOs (each of which is a PnP child) and create their own unique FDO. This allows standard drivers to work on each of these devices, without the knowledge of the other.

But USBCCGP isn’t *always* used for every multi-interface device. There can be multi-interface devices where the device, and ALL its existing interfaces, are claimed and services by a single driver. In PnP terms, you then have the USB Hub driver (which enumerates the device) as the Parent, creating only one, single, Child PDO that’s directly claimed by the function driver (and one, single FDO is created).

Now, if your question really doesn’t have anything to do with parents and children, and you just want to know the interfaces available or in use for a given composite device, you can filter that device and determine the interfaces from the descriptor data, as I mentioned previously.

I hope that clarifies the situation a bit,

Peter
OSR

>I’m filtering the USB class. I need to know the maximum number of children my device can have, in

order to know the size to allocate for some array.

Use list instead of array, or re-implement STL-style container (vector or unordered_set) in the kernel.

Isn’t this easier then doing undocumented hacks which will, among the other things, require excessive testing on several Windows versions?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

On Thu, Dec 8, 2011 at 3:56 PM, wrote:

> I find the terminology you’re using confusing, and I’m not sure what you
> really want to do. You probably want to be sure to read the WDK docs on
> enumerating composite devices. Specifically, I’m confused by what you mean
> about “Children”… children in what respect?
>

Children in the PnP sense; in NT parlance, devnodes of the Composite
Device’s devnode.

> As I tried to explain, composite devices don’t have “children” – A USB
> “device” is a physical container. For a composite device, that physical
> container contains one or more configurations, one of which has multiple
> Interfaces, and each interface can be used simultaneously (this is always
> true of USB Interfaces, btw… but not USB configurations).
>

Yes, I’m perfectly aware of all that. The usbhub driver, when enumerating
its children, reports a USB\COMPOSITE compatible ID for devices matching a
certain pattern (as described in the MSDN article[1]), and unless there’s a
driver with a better rank for the device (e.g. matching by Hardware ID),
the USBCCGP will be the FDO for that device, subsequently creating PDOs for
every interface (or collection of interfaces – again, complex rules
described in the MSDN) upon receiving IRP_MN_QUERY_BUS_RELATIONS.

The PDOs will forward pretty much all URBs to the composite device itself,
except for:
- GetDescriptor requests for configuration descriptors: it will override
the reply and return only the interface and endpoints relevant to the
specific PDO,
- USB resets/cycles, which will be swallowed

Now, if your question really doesn’t have anything to do with parents and
> children, and you just want to know the interfaces available or in use for
> a given composite device…

“Composite device” is a Windows concept. Down on the USB level, it’s just
multiple interfaces. Same as Windows has “USB pipes” while USB only has
endpoints. I just hoped to have the ability to ask a USBCCGP device how
many child PDOs is it planning to return upon
the IRP_MN_QUERY_BUS_RELATIONS (if to put it in precise technical terms).

I do have other options (as Maxim said, I could just use a list), so my
second question was simply about how to understand the confusing MSDN
documentation and whether I have grounds to mail the MSDN team some
improvements for the documentation.

[1]
http://msdn.microsoft.com/en-us/library/windows/hardware/ff537109(v=vs.85).aspx

Ilya Konstantinov wrote:

On Thu, Dec 8, 2011 at 3:56 PM, > mailto:xxxxx> wrote:
>
> I find the terminology you’re using confusing, and I’m not sure
> what you really want to do. You probably want to be sure to read
> the WDK docs on enumerating composite devices. Specifically, I’m
> confused by what you mean about “Children”… children in what
> respect?
>
>
> Children in the PnP sense; in NT parlance, devnodes of the Composite
> Device’s devnode.

The default composite driver (usbccgp.sys) creates one PDO per
interface. That puts an upper limit on the number of PDOs.

A custom driver for a composite device could create its own bus with
hundreds of devices, of course.

> Now, if your question really doesn’t have anything to do with
> parents and children, and you just want to know the interfaces
> available or in use for a given composite device…
>
>
> “Composite device” is a Windows concept. Down on the USB level, it’s
> just multiple interfaces.

Not true – it’s a USB concept. Section 5.2.3 of the USB spec says “A
device that has multiple interfaces controlled independently of each
other is referred to as a composite device.”


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</mailto:xxxxx>

No. Neither “composite device” NOR “pipe” is a Windows concept. Both are defined terms in the USB specification.

In terms of “composite devices”, these are both described and differentiated from “compound devices” – See Figure 3-4 in the USB 3 spec. Very attractive description.

In terms of pipes, see 3.2.8 of the USB 3 spec:

“Data transfers occur between host software and a particular endpoint on a device. The endpoint
is associated with a particular function on the device. These associations between host software
to endpoints related to a particular function are called pipes.”

Now THAT would have a MUCH easier question to understand… assuming of course you’re willing consider only those compound devices that are claimed by USBCCGP.

But I’m not sure what the answer would BE, to be honest… because by the time you could ask USBCCGP how many child PDOs he *would* create he would probably already have created them. If you’re in the stack below USBCCGP, then you could determine how many PDOs USBCCGP *will* create when he instantiates… but then you won’t be doing that by asking USBCCGP, you’ll be doing it by parsing the descriptors.

In any case, I think you’ve gotten your answer at this point, so there’s probably no need to belabor the terminology discussion…

Hope I’ve been helpful in at least some way,

Peter
OSR

On Thu, Dec 8, 2011 at 10:22 PM, wrote:

> No. Neither “composite device” NOR “pipe” is a Windows concept. Both are
> defined terms in the USB specification.
>

Ok, ok, I won’t make such unchecked statements in front of OSR again :slight_smile:

Peter, Maxim, Tim and Doron - thanks for your help.
As to what the MSDN meant re UsbMIParent, that’ll forever remain a mystery.

> But I’m not sure what the answer would BE, to be honest… because by the
> time you could ask USBCCGP how many child PDOs he would create he would
> probably already have created them.

USBCCGP likely creates them IRP_MN_QUERY_BUS_RELATIONS. My filter driver
processes this IRP, so basically I will know for sure all the PDOs it
creates. So yeah, problem solved. I don’t even know why I was trying to
create those arrays ahead of time :slight_smile:

Are you writing a bus filter and attaching to each of these PDOs?

d

debt from my phone


From: Ilya Konstantinov
Sent: 12/9/2011 4:05 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] IOCTL_USB_GET_NODE_INFORMATION and composite devices?

On Thu, Dec 8, 2011 at 10:22 PM, > wrote:
No. Neither “composite device” NOR “pipe” is a Windows concept. Both are defined terms in the USB specification.

Ok, ok, I won’t make such unchecked statements in front of OSR again :slight_smile:

Peter, Maxim, Tim and Doron - thanks for your help.
As to what the MSDN meant re UsbMIParent, that’ll forever remain a mystery.

But I’m not sure what the answer would BE, to be honest… because by the time you could ask USBCCGP how many child PDOs he would create he would probably already have created them.

USBCCGP likely creates them IRP_MN_QUERY_BUS_RELATIONS. My filter driver processes this IRP, so basically I will know for sure all the PDOs it creates. So yeah, problem solved. I don’t even know why I was trying to create those arrays ahead of time :slight_smile:
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

On Fri, Dec 9, 2011 at 5:21 PM, Doron Holan wrote:

> Are you writing a bus filter and attaching to each of these PDOs?
>

Yup.

I’m developing something akin to Microsoft’s USB Device Redirection[1] in
Windows 7, only I’m targeting Windows XP as well. It has been functional
for a while, and now I’m adding composite device support (i.e. selectively
redirecting specific children of the composite device).

[1] http://msdn.microsoft.com/en-us/library/ff539290(v=VS.85).aspx