IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO

Hi everyone,

Has anyone been able to successfully use
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO to 'bypass' the generic composite
device driver?

When I try with the code below, it returns STATUS_NOT_IMPLEMENTED
((NTSTATUS)0xC0000002L)

Any ideas?

DISCLAIMER:

I know it's not a pretty thing to do, but it seems Microsoft's
usbaudio.sys driver uses this so it can match 1 interface, and still
access other interfaces on the device.

This is unfortunately how usb class devices are enumerated - with one
audio control endpoint and several audio streaming (isoch) endpoints
which are functionally related.

Matching the device is not an option since there may be other endpoints
(e.g. MIDI)

-nick

/* IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO

This IOCTL is used internally by the hub driver this API will
return the PhysicalDeviceObject of the root hub enumerated by the
controller.

Parameters.Others.Argument1 =
pointer to be filled in with PDO for the root hub;
Parameters.Others.Argument2 =
pointer to be filled in with FDO of the USB Host Controller;

*/

PDEVICE_OBJECT root_pdo = 0;
PDEVICE_OBJECT root_fdo = 0;

PIRP Irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
pdo, // DeviceObject
NULL, 0, // InputBuffer
NULL, 0, // OutputBuffer
TRUE, // Internal
&event,
&iostatus);

PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
stack->Parameters.Others.Argument1 = (PVOID) &root_pdo;
stack->Parameters.Others.Argument2 = (PVOID) &root_fdo;

NTSTATUS status = IoCallDriver(pdo, Irp);

Are there are any other functions on your device that require the usb
composite driver to load? If not, then just have your driver load on
the FDO instead of usbgcccp and forget about this workaround. Also,
depending on your OS requirements (XP SP2 and later) and if you can
control your firmware, you can use the interface association descriptor
(IAD) to tell usbgccp how to group all your interfaces together into one
function.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Nick Dowell
Sent: Monday, September 18, 2006 10:23 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO

Hi everyone,

Has anyone been able to successfully use
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO to 'bypass' the generic composite
device driver?

When I try with the code below, it returns STATUS_NOT_IMPLEMENTED
((NTSTATUS)0xC0000002L)

Any ideas?

DISCLAIMER:

I know it's not a pretty thing to do, but it seems Microsoft's
usbaudio.sys driver uses this so it can match 1 interface, and still
access other interfaces on the device.

This is unfortunately how usb class devices are enumerated - with one
audio control endpoint and several audio streaming (isoch) endpoints
which are functionally related.

Matching the device is not an option since there may be other endpoints
(e.g. MIDI)

-nick

/* IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO

This IOCTL is used internally by the hub driver this API will
return the PhysicalDeviceObject of the root hub enumerated by the
controller.

Parameters.Others.Argument1 =
pointer to be filled in with PDO for the root hub;
Parameters.Others.Argument2 =
pointer to be filled in with FDO of the USB Host Controller;

*/

PDEVICE_OBJECT root_pdo = 0;
PDEVICE_OBJECT root_fdo = 0;

PIRP Irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
pdo, // DeviceObject
NULL, 0, // InputBuffer
NULL, 0, // OutputBuffer
TRUE, // Internal
&event,
&iostatus);

PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
stack->Parameters.Others.Argument1 = (PVOID) &root_pdo;
stack->Parameters.Others.Argument2 = (PVOID) &root_fdo;

NTSTATUS status = IoCallDriver(pdo, Irp);


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at

Those IADs sound like just the ticket! Unfortunately some of the existing hardware I need to support does not use them, and the firmware is not upgradable.

And yes, our devices have MIDI class compliant interfaces too, which means I need to have the system match the MIDI interface and load usbaudio.sys on just that. I want to avoid having to re-implement usbaudio.sys’ MIDI support, as I’m sure you can appreciate.

The only other solution I can see is to write a custom equivalent to usbgcccp to allow usbaudio.sys to run alongside our custom audio driver, but then that’s even less documented!

Is there something wrong with the code sample I posted, or has this really been un-implemented?

Regards,

-nick

I don’t know. It’s internal, I can’t speak for the usb core team, but the IOCTL could disappear on the next release if they so choose. Another way to do this is to install a lower filter below usbgccp and alter the config descriptor being reported by the device so that it contains the IADs. This is certainly easier then implementing your own usbgccp replacement driver. Writing such a driver in KMDF would be a days work, where most of your time will be spent in figuring out how to alter the config descriptor.

d

What I find strange is that when my driver matches the Audio Control
interface, fetching the configuration descriptor DOES return information
about the Audio Streaming interfaces (but filters out any other
interfaces on the device).

I can then try to select the interfaces and alternative settings as if I
were matching the usb device using USBD_CreateConfigurationRequestEx /
URB_FUNCTION_SELECT_CONFIGURATION, which returns no error.

However after this the PUSBD_INTERFACE_LIST_ENTRY::Interface entries
returned are not filled in for the audio streaming endpoints.

Any ideas about this behaviour?

-n

xxxxx@Microsoft.com wrote:

I don’t know. It’s internal, I can’t speak for the usb core team, but the IOCTL could disappear on the next release if they so choose. Another way to do this is to install a lower filter below usbgccp and alter the config descriptor being reported by the device so that it contains the IADs. This is certainly easier then implementing your own usbgccp replacement driver. Writing such a driver in KMDF would be a days work, where most of your time will be spent in figuring out how to alter the config descriptor.

d

Let’s say you have N interfaces, you need to call select interface on the 2-N interfaces to get the endpoint information (due to a bug in usbgccp). You will always get the interface info for the first interface, so for a select config on a multi interface device for a singular interface, there is no addtional work

d

Wow, that did the trick! I like 1-line fixes :slight_smile:
Priceless information, lucky for me there are guys like you on this group…
Many thanks Doran.

-n

Nick Dowell wrote:

Wow, that did the trick! I like 1-line fixes :slight_smile:
Priceless information, lucky for me there are guys like you on this
group…
Many thanks Doran.

Doron!
Sorry!

-n

Doron Holan wrote:

Let’s say you have N interfaces, you need to call select interface on the 2-N
interfaces to get the endpoint information (due to a bug in usbgccp). You will
always get the interface info for the first interface, so for a select config on
a multi interface device for a singular interface, there is no addtional work

Does KMDF contain this workaround?

yes, it does. that is why i know the workaround is required ;).

d