Windows下USB百科
+ -

USB设备总线拓扑结构生成原理及方法

2024-02-06 29 0

在Windows系统的内核中,USB堆栈提供了一系列的API接口。内核或者应用程序可以使用这些API接口来确定USB总线的拓扑结构和相关的USB设备信息。

我们常用的USBTreeViewe是基于微软开源usbview二次开发的,而usbview就是使用这些API接口来实现USB总线拓扑结构和USB设备信息的获取的。

USB设备分类

USB设备一般挂在USB集线器上,USB集线器也可以挂在他的上一层USB集线器上,但最终是挂在USB根集线器上的,USB根集线器是由USB主机控制器来创建的。所以USB的设备总共可以分为三类:

  • USB主机控制器
  • USB集线器(包括根集线器)
  • USB普通设备
    当然,在USB规范中,也将USB集线器归为USB设备.USB集线器也占用USB地址。

USB总线枚举

在Windows系统中,USB根集线器的设备名遵循HCD0,HCD1…HCD9 的命名规则。我们可以使用如下的方式来枚举系统中所有USB主机控制器。

    TCHAR        HCName[16];
    for (int HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
    {
        _stprintf_s(HCName, sizeof(HCName) / sizeof(HCName[0]), _T("\\\\.\\HCD%d"), HCNum);
        printf("%s\n", HCName);

        HANDLE hHCDev = CreateFile(HCName,
            GENERIC_WRITE,
            FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
        if (hHCDev != INVALID_HANDLE_VALUE)
        {
            EnumerateHostController(hHCDev);
            CloseHandle(hHCDev);
        }
    }

实际在使用过程中,我们使用SETUPAPI函数枚举GUID_DEVINTERFACE_USB_HOST_CONTROLLER的设备类型

/* 3ABF6F2D-71C4-462a-8A92-1E6861E6AF27 */
DEFINE_GUID(GUID_DEVINTERFACE_USB_HOST_CONTROLLER, 0x3abf6f2d, 0x71c4, 0x462a, 0x8a, 0x92, 0x1e, \
    0x68, 0x61, 0xe6, 0xaf, 0x27);

获取根集线器

应用程序获取了USB主机控制器的句柄后,可以向其下发 USB_GET_ROOT_HUB_NAME来获取其下的USB根集线器名称。其参数为:

typedef struct _USB_ROOT_HUB_NAME {
    ULONG ActualLength;     /* OUTPUT */
    /* NULL terminated unicode symbolic name for the root hub */
    WCHAR RootHubName[1];   /* OUTPUT */
} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;

其中ActualLength指定的是整个结构体的大小,而非RootHubName的大小。
获取的USB根集线器名称一般为这样的:

USB#ROOT_HUB30#4&31789dfb&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}

我们对其加上设备前导头好可得到:

\\.\USB#ROOT_HUB30#4&31789dfb&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}

这样的字符串。使用该字符串可以使用CreateFile来打开根集线器。

USB根集线器的枚举

当然,和USB根集控器一样,我们也可以通过SETUPAPI使用GUID_DEVINTERFACE_USB_HUB枚举系统中所有USB集线器(包括根集线器和扩展集线器)。

/* f18a0e88-c30c-11d0-8815-00a0c906bed8 */
DEFINE_GUID(GUID_DEVINTERFACE_USB_HUB,    0xf18a0e88, 0xc30c, 0x11d0, 0x88, 0x15, 0x00, \
             0xa0, 0xc9, 0x06, 0xbe, 0xd8);

对于USB集线器,比较关注的是是其下有多少个下游端口,其连接状态是什么。这可以通过IOCTL_USB_GET_NODE_INFORMATION来获取到。获取到的数据结构USB_NODE_INFORMATION如下:

typedef struct _USB_HUB_DESCRIPTOR {
    UCHAR   bDescriptorLength;
    UCHAR   bDescriptorType;
    UCHAR   bNumberOfPorts;
    USHORT  wHubCharacteristics;
    UCHAR   bPowerOnToPowerGood;
    UCHAR   bHubControlCurrent;
    UCHAR   bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;

typedef struct _USB_HUB_INFORMATION {
    /*
       copy of data from hub descriptor
    */
    USB_HUB_DESCRIPTOR HubDescriptor;

    BOOLEAN HubIsBusPowered;

} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;

typedef struct _USB_NODE_INFORMATION {
    USB_HUB_NODE NodeType;        /* hub, mi parent */
    union {
        USB_HUB_INFORMATION HubInformation;
        USB_MI_PARENT_INFORMATION MiParentInformation;
    } u;
} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;

通过解析USB集线器描述符中的bNumberOfPorts即可获取USB集线器的端口数。
USB集线器的数据编号从1开始,到bNumberOfPorts。这时可以通过IOCTL_USB_GET_NODE_CONNECTION_INFORMATION来获取指定USB端口下设备的连接信息。

typedef struct _USB_NODE_CONNECTION_INFORMATION {
    ULONG ConnectionIndex;  /* INPUT */
    /* usb device descriptor returned by this device
       during enumeration */
    USB_DEVICE_DESCRIPTOR DeviceDescriptor; /* OUTPUT */
    UCHAR CurrentConfigurationValue;/* OUTPUT */
    BOOLEAN LowSpeed;/* OUTPUT */
    BOOLEAN DeviceIsHub;/* OUTPUT */
    USHORT DeviceAddress;/* OUTPUT */
    ULONG NumberOfOpenPipes;/* OUTPUT */
    USB_CONNECTION_STATUS ConnectionStatus;/* OUTPUT */
    USB_PIPE_INFO PipeList[0];/* OUTPUT */
} USB_NODE_CONNECTION_INFORMATION, *PUSB_NODE_CONNECTION_INFORMATION;
  • 对于普通设备,可通过IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION来获取USB设备的相关描述符内容。
  • 对于USB集线器,可通过IOCTL_USB_GET_NODE_CONNECTION_NAME来获取其扩展集线器的名称。其后就和根集器的过程一样。
HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

UVC 拓扑结构
UVC规范描述了以下类型的标准单元和终端,这些单元和终端被认为足以代表当前和近期可用的大多数视频功能:输入端子(ST)输出端子(OT)选择器单元(SU)处理单元(PU)编码单元(EU)扩展单元(XU)此外,还有一些特殊的终端扩展了基本输入和输出终端的功能。这些特殊终端支持特定于这些终端提供的扩展功能......
USBTreeView遇到连续的转换接口描述符不解释情况说明
今天拿到一个USB摄像头,对其进行数据格式分析,出现了一个令人迷惑的问题…事情是这样的,我用POTPLAYER打开摄像头,使用BUSHOUND进行抓包,选择的备用接口是0x0c CTL 01 0b 0c 00 01 00 00 00 SET_INTERFACE为了查看该端点的数据大......
USB的拓扑结构
USB的拓扑结构结可以从三个视图来解释,分别为物理拓扑,逻辑拓扑和软件编程拓扑USB的物理拓扑结构USB的物理拓扑指的是USB总线的实际物理设备连接关系。主机端提供USB根集线器,USB根集线器可外接USB外设,也可的外接USB的集线器HUB,用于拓展USB端点接口,拓展的USB集线器上的端口也可以......
UAC 拓扑结构
UAC规范描述了以下类型的标准单元和终端,这些单元和终端被认为足以代表当前和近期可用的大多数视频功能:输入终端 - Input Terminal (IT)输出终端 - Output Terminal (OT)混音器单元 - Mixer Unit (MU)选择器单元 - Selector Uni......
USB设备与集线器最大可以级联多少层
在USB2.0规范中,定义了USB设备与集线器最大可以级联7层(包括根集线器),即根集线器之设备之间最多有5个继集线器。注意:有一个USB复合(compound)设备,其本身是一个USB集线器并接连1个或多个USB功能设备,这里需要将这个USB集线器算在内。......
Windows下的USB设备描述符分析工具-UsbTreeView
UsbTreeView是Windows下的一款关于USB描述符分析的工具,该工具俱有以下特点:实时显示USB设备的连接状态以树状的形式显示连接到PC机中的所有USB设备,集线器和控制器可完美的分析连接到PC机中USB设备的各类USB描述符信息。支持USB1.0/USB2.0/USB3.x规范协议......
UsbTreeView中设备驱动信息获取方法
UsbTreeView是一个专门解析USB设备描述符的工具,可以显示USB设备的一系列属性值。其中包括驱动路径,和inf配置文件路径,查询了一下,没找到可以获取这些驱动信息的SetupApi。好奇这个软件是怎么实现的,于是对它调用的API抓了一下包,找到了它的实现方法。(1)驱动路径获取方法......
UAC复合设备(麦克风,扬声器,HID设备)的示例
UAC符合设备(麦克风,扬声器,HID设备)在设备管理器中如下图所示:在BUSHOUND下如下图所示:UAC音频设备UAC音频设备包括扬声器和麦克风。其中USB Pnp Audio Device使用了接口0,1,2,分别用于控制接口,扬声器和麦克风。HID音量控制设备USB输入设备用于音频的......
USBTreeView
USBTreeView是一针对 Windows 操作系统的 USB 设备分析工具,它可以用于查看 USB 设备的属性、配置、接口、中断管道等详细信息,并能够实时监测 USB 总线上的交互信息、访问权限等。使用 USBTreeView 可以帮助用户更好地理解和诊断 USB 设备的问题,特别是在开发和......
UVC摄像头实现的拓扑结构
UVC视备内部表示为多个可寻址实体或终端的互连。每个实体/终端代表一种功能,并具有由USB主机控制的属性。这些UVC设备内部互联的结构叫做UVC设备的内部拓扑结构。一个最简单的UVC拓扑结构如下图所示:数据由CAMERA Sensor采集,首先通过输入终端,再通过输出终端,最后通过USB的视频流端点......
UVC扩展单元描述符和设置不当会引起的设备启动失败(code:10)
UVC扩展单元用于UVC设备的自定义通讯,通过UVC扩展单元可以实现一些厂商自定义的通讯和设备特性。在一般的UVC摄像头的描述符布局中,其拓扑结构一般如下:可以看到,这上面的拓扑结构中支持2个扩展单元,所以在USB配置描述符的视频控制接口中就有两个独立的扩展单元描述符。这两件扩展单元的bSource......
UVC相机拓扑结构配置要点总结
做UVC相机开发的人经常是需要编写UVC相机配置描述符的,这个USB配置描述符包括两部分的内容,分别为视频控制接口部分和视频流接口部分。视频控制部分包括的内容主要描述了UVC相机的拓扑结构。一般情况下的相机拓扑结构是这样子的:不过有的时候,我们也需要扩展单元,所以加上扩展单元描述符就如下:这里......
USB2.0集线器高速描述符UsbTreeViewer解析示例
=========================== USB Port4 ===========================Connection Status : 0x01 (Device is connected)Port Chain ......
红外摄像头USBTreeViewer信息
=========================== USB Port1 ===========================Connection Status : 0x01 (Device is connected)Port Chain ......
USBTreeViewer获取字节串描述符
缘由在于自己虚拟了一个USB控制器集线器,故在使用USBTreeViewer查看其USB集线器下的设备信息时,字节串描述符的问题解决。USB的开发人员肯定对USBTreeViewer这个工具不陌生,我们使用它来查看电脑中USB设备的相关信息。例如设备的连接信息,USB设备描述符,USB配置描述......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!