Windows 中的 USB ContainerID

此白皮书提供有关 Windows 操作系统的 USB ContainerID的信息。 它包括设备制造商对多功能 USB 设备进行编程的指南,以便 Windows 能够正确检测到它们。

从 Windows 7 开始,用户可以利用连接到其计算机的设备的所有功能。 这包括多功能设备,例如组合打印机、扫描仪和复印机设备。 Windows 7 支持将单个物理设备的所有功能合并到设备容器中。 设备容器是物理设备的虚拟表示形式。 可以通过为物理设备枚举的每个设备函数分配 ContainerID 属性来实现此合并。 通过为每个设备函数分配相同的 ContainerID 值,Windows 7 可识别所有设备功能都属于同一物理设备。

通过不同总线类型连接到计算机的所有类型的设备都可以支持设备容器。 但是,并非所有总线类型都使用相同的机制来生成 ContainerID。 对于 USB 设备,设备供应商可以使用 ContainerID 描述符来描述物理设备的 ContainerIDContainerID 描述符是可以存储在 USB 设备的固件中的 Microsoft OS 功能描述符。 USB 设备制造商必须在其设备中正确实现这些 ContainerID 描述符,以利用 Windows 7 中提供的新设备功能。 USB 设备制造商只需为每个物理设备实现一个 ContainerID ,而不考虑设备支持多少个设备功能。

有关将单个设备的所有功能合并到设备容器的详细信息,请参阅 如何生成容器 ID

有关适用于 USB 设备的 Microsoft OS 描述符的详细信息,请参阅 适用于 USB 设备的 Microsoft OS 描述符

如何生成 USB ContainerID

下面是为 USB 设备生成 ContainerID 的两种方法:

  • USB 设备的制造商使用 Microsoft OS ContainerID 描述符指定设备固件中的 ContainerID
  • Microsoft USB 集线器驱动程序会自动根据设备的产品 ID (PID) 、供应商 ID (VID) 、版本号和序列号的组合为设备创建 ContainerID 。 在这种情况下,Microsoft USB 集线器驱动程序会创建功能最少的 ContainerID 。 此方法仅适用于具有唯一序列号的设备。

USB ContainerID 内容

USB ContainerID 以通用唯一标识符 (UUID) 字符串的形式呈现给操作系统。 ContainerID UUID 包含在 ContainerID 描述符中。 ContainerID 描述符是设备级 Microsoft OS 功能描述符。 因此,当操作系统请求 USB ContainerID 时,描述符请求的 wValue 字段必须始终设置为零。 有关 Microsoft OS 功能描述符和描述符请求的详细信息,请参阅 Microsoft OS 1.0 描述符规范

ContainerID 描述符由标头部分组成。

Offset 字段 大小 类型 说明
0 dwLength 4 无符号 DWord 整个 ContainerID 描述符的长度(以字节为单位)。 此字段必须始终设置为 0x18 值。
4 bcdVersion 2 BCD ContainerID 描述符的版本号,以二进制编码的十进制 (BCD) ,其中每个小数对应于一个数字。 最大有效字节 (MSB) 包含小数点前的两位数字,最小有效字节 (LSB) 包含小数点后的两位。 例如,版本 1.00 表示为 0x0100。 此字段必须始终设置为 0x0100。
6 wIndex 2 对于 USB ContainerID 描述符,此字段始终设置为 6。

ContainerID 描述符由 ContainerID 节组成。

Offset 字段 大小 类型 说明
0 bContainerID 16 无符号 DWord ContainerID 数据。

设备制造商负责确保设备的每个实例的 ContainerID 具有通用唯一的 16 字节值。 此外,设备每次开机时都必须报告相同的 ContainerID 值。 有多种已建立的算法可用于生成 UUID,几乎零重复几率。 设备制造商可以选择最适合其需求的 UUID 生成算法。 只要结果是唯一的,使用哪种 UUID 生成算法并不重要。

USB ContainerID 语法

ContainerID 以 {xxxxxxxx-xxxx-xxx} 的标准 UUID 字符串格式报告。 下面是固件中 0C B4 A7 2C D1 7B 25 4F B5 73 A1 3A 97 5D DC 07 USB ContainerID 的示例表示形式,其格式设置为 {2CA7B40C-7BD1-4F25-B573-A13A975DDC07} UUID 字符串。

UCHAR ExampleContainerIDDescriptor[24] =
{
    0x18, 0x00, 0x00, 0x00,     // dwLength - 24 bytes
    0x00, 0x01,                 // bcdVersion - 1.00
    0x06, 0x00,                 // wIndex – 6 for a ContainerID
    0x0C, 0xB4, 0xA7, 0x2C,     // bContainerID -
    0xD1, 0x7B, 0x25, 0x4F,     // {2CA7B40C-7BD1-4F25-B573-A13A975DDC07}
    0xB5, 0x73, 0xA1, 0x3A,     // 0C B4 A7 2C D1 7B 25 4F B5 73 A1 3A 97 5D DC 07
    0x97, 0x5D, 0xDC, 0x07      //
}

请注意,当前 8 个字节的格式设置为 UUID 字符串时,字节顺序的变化。

Microsoft OS 描述符更改

为了保留旧 版 ContainerID 功能,已向 Microsoft OS 字符串描述符添加了一个新的标志字段,可用于指示对 ContainerID 描述符的支持。

Microsoft OS 字符串描述符的当前定义在描述符的末尾包含一个 1 字节板字段 bPad,该字段通常设置为零。 对于支持新 ContainerID 的 USB 设备, bPad 字段重新定义为标志字段 bFlags。 此字段的第 1 位用于指示对 ContainerID 描述符的支持。 表 3 描述了 USB 设备的 Microsoft OS 字符串描述符的字段。

字段 ) (字节长度 说明
bLength 1 0x12 描述符的长度。
bDescriptorType 1 0x03 描述符类型。 值 0x03 表示 Microsoft OS 字符串描述符。
qwSignature 14 “MSFT100” 签名字段。
bMS_VendorCode 1 供应商代码 供应商代码。
bFlags 1 0x02 位 0:保留
位 1: ContainerID 支持
 0:不支持 ContainerID
 1:支持 ContainerID
位 2–7:保留

目前,支持 Microsoft OS 描述符但不支持 ContainerID 描述符的 USB 设备将 bPad 字段设置为 0x00。 USB 中心驱动程序不会查询此类设备以查找 USB ContainerID 描述符。

USB 多功能设备的容器视图

ContainerID 提供的信息用于合并多功能 USB 设备的设备。 图 1 显示了当产品中的所有设备都使用相同的 ContainerID 时,多功能打印机中的所有设备如何合并到单个设备容器的示例。

合并多功能打印机中的所有设备。

通过合并多功能 USB 设备的所有设备,物理产品可以在 Windows 7 的设备和打印机中显示为单个设备。 图 2 显示了在设备和打印机中显示为单个设备的 USB 多功能键盘和鼠标设备的示例。

设备和打印机中的多功能设备。

USB ContainerID HCK 要求

设备制造商必须确保其生成的设备的每个实例都具有全局唯一的 ContainerID 值,以便 Windows 能够成功合并每个 USB 多功能设备的功能。 Windows 硬件认证Windows 硬件认证工具包包含 USB ContainerID (如果已在设备中实现)的要求 DEVFUND-0034。 如果设备实现了 USB ContainerID,Windows 硬件认证会在 Microsoft OS 描述符测试中测试 ContainerID ,并检查 ContainerID 值是否全局唯一。 有关这些 Windows 硬件认证要求的详细信息,请参阅 Windows 硬件认证网站。

有关实现 USB ContainerID 的建议:下面是针对设计、制造和交付 USB 设备的设备供应商的建议:

  • 了解 Windows 7 如何通过使用 ContainerID 改进对多功能和多个传输 USB 设备的支持。 建议首先阅读“Windows 7 中的多功能设备支持和设备容器分组”。
  • 请确保每个 USB 设备上的序列号是唯一的。 Windows 硬件认证要求规定,如果设备包含序列号,则设备的每个实例的序列号必须是唯一的。
  • 不要为系统中嵌入的 USB 设备提供 ContainerID 。 集成 USB 设备应依赖于 ACPI BIOS 设置或端口的 USB 集线器描述符 DeviceRemovable 位。
  • 确保连接到系统的所有 USB 设备都具有唯一的 ContainerID 值。 不要跨产品系列共享 ContainerID 值或 USB 序列号。
  • 请确保为设备正确设置可移动设备功能。 注意 向以前交付的 USB 设备添加 USB ContainerID 描述符的设备供应商必须在设备描述符中递增设备版本号 (bcdDevice) 。 这是必需的,因为 USB 中心驱动程序会根据设备的供应商 ID、产品 ID 和设备版本号缓存 Microsoft OS 字符串描述符 (或缺少一个) 。 如果不递增设备版本号,中心驱动程序不会查询新设备的 USB ContainerID (如果中心驱动程序以前枚举具有相同的供应商 ID、产品 ID 和设备版本号不支持 USB ContainerID 描述符)的设备实例。

为 Windows 构建 USB 设备
USB 设备的容器 ID