如何为 USB 设备分配容器 ID
对于通过通用串行总线 (USB) 连接到计算机的设备,以下流程图显示了用于将容器 ID 分配给 USB 设备节点 (devnode) 的启发式。
此启发式使用来自多个源的信息来确定 USB 开发节点的以下其中一项是否属实:
开发节点是否表示 USB 总线上的新设备? 如果为 true,则开发节点将收到新的容器 ID。
开发节点是否是现有设备的子开发节点? 如果为 true,则开发节点将继承父开发节点的容器 ID。
USB 设备的容器 ID 通过多种方式生成。 此决策基于设备中包含的信息。 此信息是从 ACPI 设置、USB 总线驱动程序和 USB 集线器检索的。
此启发式针对 即插即用 (PnP) 管理器在 USB 总线上枚举的每个开发节点遵循这些步骤。
USB 总线驱动程序查询时,USB 设备可以通过 Microsoft 操作系统 (OS) ContainerID 描述符报告 容器 ID 。
从 Windows 7 开始,操作系统支持 Microsoft OS ContainerID 描述符。 通过此描述符,独立硬件供应商 (IHV) 可以精确指定设备的容器 ID。 因此,设备的容器 ID 是唯一的,不会在安装设备的每台计算机上更改。 此外,如果报告 Microsoft OS ContainerID 描述符,则设备会向操作系统指示所有枚举的开发节点都是同一物理设备的一部分。
Microsoft OS ContainerID 描述符用于支持通过多个系统总线同时连接设备的设备。 例如,打印机可以使用 即插即用 扩展 (PnP-X) 支持同时进行 USB 和 IP 网络连接。 通过使用单个 Microsoft OS ContainerID 描述符,两个传输将报告相同的容器 ID。 因此,PnP 管理器确定每个总线枚举的开发节点是同一物理设备的一部分。
有关 Microsoft OS ContainerID 描述符的详细信息,请参阅 Microsoft OS 描述符。
如果 USB 设备未报告 Microsoft OS ContainerID 描述符,USB 集线器驱动程序会查询 ACPI 以确定设备是否连接到面向外部的端口。
操作系统尝试 (_ADR) 对象 查找 ACPI 地址,该对象与设备连接到的 USB 端口的地址匹配。 如果找到匹配的地址对象,操作系统将执行以下步骤:
查询 (_UPC) 对象的 USB 端口功能,并检查 PortIsConnectable 值。 如果 PortIsConnectable 的非零值0xFF,则端口可用于连接外部设备。 因此,连接到此端口的任何设备都必须在计算机外部。
如果计算机实现 ACPI 3.0 并且 PortIsConnectable 字节为非零,则操作系统会 (_PLD) 对象 查询物理位置说明。 操作系统检查是否在 _PLD 对象上设置了 UserVisible 位 (位 64 位) 。 它作为额外的检查执行此操作,以确保端口既可连接,又在外部对用户可见。
如果从 ACPI 收集的信息指示设备是外部设备,则 PnP 管理器会为设备生成容器 ID。 ContainedID 值是设备的 USB 序列号的哈希值或随机生成的值。 为开发节点分配此容器 ID。
注意 如果操作系统确定设备位于计算机内部,则开发节点将继承父开发节点的容器 ID,在本例中 () 是计算机本身的容器 ID。
如果 ACPI 未返回与设备连接的 USB 端口地址匹配的 _ADR 对象,则 PnP 管理器会基于开发节点的可移动状态生成容器 ID。
USB 集线器驱动程序从中心查询 USB RemoveAndPowerMask 描述符,并检查是否为设备连接到的端口设置了 DeviceRemovable 位。 如果设置了 DeviceRemovable 位,则连接到端口的设备可从中心进行删除。 如果未设置 DeviceRemovable 位,则连接到端口的设备无法从中心进行移动。
USB 总线驱动程序向 PnP 管理器报告端口可移动/不可移动状态,后者通过以下步骤为开发节点生成 ContainerId :
如果中心指示连接到给定端口的设备可从中心删除,则 PnP 管理器将确定附加到此端口的设备位于计算机外部。 它为开发节点生成的容器 ID 要么是设备的 USB 序列号的哈希,要么是随机生成的值。
如果中心指示附加到给定端口的设备无法从中心移动,则 PnP 管理器确定附加到此端口的设备是多功能设备的子功能。 在这种情况下,开发节点继承父开发节点的容器 ID。
有关 ACPI 3.0 接口的详细信息,请参阅 高级配置和电源接口规范修订版 3.0b。