Windows 上的 USB 实例 ID 对于设备是唯一的吗?

is the USB Instance ID on Windows unique for a device?

我正在尝试在 Windows 系统上唯一地识别 USB 设备。由于序列号是可选的(在大多数设备上都是空的),我正在查看实例 ID。类似于 USB\VID_03F0&PID_094A&24b73976&0&2.

的字段

我已经知道,如果我将同一设备插入不同的端口,此 ID 会发生变化,但这对我来说没问题。问题是:如果我使用相同的设备(在我的示例中为鼠标)并将其插入,它会获得相同还是不同的实例 ID?

我做了一些研究,似乎没有人完全知道 VID 和 PID 背后的部分是什么。他们似乎确实识别了端口 and/or 集线器,但如果我将不同的设备插入同一个插槽,我不仅会看到不同的 VID 和 PID,还会看到不同的垃圾。例如,这是插入同一端口的键盘:USB\VID_046D&PID_C328&MI_00&3f9ff46&0&0000

Microsoft 文档和此处的相关问题均未回答此问题。

如果我有两个相似的鼠标(或键盘,或其他),即相同的制造商和型号,如果我将它们插入相同的端口,它们会获得相同或不同的实例 ID 吗?

我是否有机会唯一标识特定设备(而不仅仅是型号)?

If I take an identical device (mouse in my example) and plug it in, will it get the same or a different Instance ID?

它将获得相同的 ID,除非原始设备仍处于连接状态。如果没有唯一的序列号字符串,OS 就无法区分。

如果您使用 USB 协议分析器查看插入 USB 设备时 Windows 执行的操作,您会发现它是通过读取 USB 描述符开始的。这些是二进制数据,例如设备描述符(包含供应商 ID、产品 ID 和版本)、配置描述符(说明设备支持哪些接口以及使用哪些端点)、字符串描述符(如制造商名称、产品名称, 和序列号),以及在 USB 协议的各种扩展中添加的其他 USB 描述符。

我不知道 Windows 如何选择设备实例 ID,但 ID 很可能是这些描述符中字节的函数,您将设备插入的端口,什么都没有别的。 Windows 不太可能使用任何高级指纹识别技术来尝试嗅探不同 USB 设备之间的微小差异,因为这似乎是浪费精力。我推测设备实例 ID 的要点是 Windows 可以找到一个注册表项(在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB 内),该注册表项指示上次插入设备时决定使用哪些驱动程序,并且它为这些驱动程序使用了哪些设置。

设备型号与其 USB 描述符之间没有普遍关联。你可能有两个外观相似的键盘,它们具有完全不同的固件和 USB 描述符,只是因为制造商选择升级固件。你可以有两个不同颜色的键盘,它们使用相同的固件,因此看起来与计算机相同,因为它们会对所有可能的 USB 消息做出相同的响应(这不仅仅是《星际迷航》中的幻想)。

关于你的第一个问题(在标题中):

is the USB Instance ID on Windows unique for a device?

摘自Microsoft Device Instance ID page

A device instance ID is a system-supplied device identification string that uniquely identifies a device in the system.

A device instance ID is persistent across system restarts.

所以,回答你的问题:

系统设备 ID 唯一标识特定 Windows 系统中的设备

请注意:它的任务是识别本机中的设备。从机器上取下设备后,该设备不再是这台机器的一部分

因此,现在,如果您从系统中删除设备并重新插入,您无法确定设备实例 ID 是否相同,但是
您可以确定如果您重新启动系统,设备实例 ID 将是相同的。

让我们继续,检查您的下一个问题。


关于你的第二个问题:

If I take an identical device (mouse in my example) and plug it in, will it get the same or a different Instance ID ?

我们再看看Microsoft Device Instance ID page

The format of this string consists of an instance ID concatenated to a device ID, as follows:

<device-ID>\<instance-specific-ID>

The following is an example of an instance ID ("1&08") concatenated to a device ID for a PCI device:

PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02&08

所以,在 USB\VID_xxx&PID_xxx\ 部分之后,您看到的是 Instance ID(名称与 System Device ID 的区别很小)

我们来看看Microsoft Instance ID page:

An instance ID is a device identification string that distinguishes a device from other devices of the same type on a computer. An instance ID contains serial number information, if supported by the underlying bus, or some kind of location information

The UniqueID member of the DEVICE_CAPABILITIES structure for a device indicates if a bus-supplied instance ID is unique across the system, as follows:

  • If UniqueID is FALSE, the bus-supplied instance ID for a device is unique only to the device's bus. The Plug and Play (PnP) manager modifies the bus-supplied instance ID, and combines it with the corresponding device ID, to create a device instance ID that is unique in the system.
  • If UniqueID is TRUE, the device instance ID, formed from the bus-supplied device ID and instance ID, uniquely identifies a device in the system.

所以,回答你的问题:

  • 如果 UniqueIDTRUE,设备实例 ID 将是相同的,即使您将设备移动到不同的 USB 端口(我补充说:这是当 USB设备提供序列号)
  • 如果 UniqueIDFALSE,您无法确定 bus-supplied 实例 ID 是否相同,因此您无法确定整个设备实例 ID 是否相同相同。 (但是,实例 ID 在系统重新启动时应该相同,因此如果您有相同的设备 1 和设备 2,并在系统重新启动期间交换它们,我假设实例 ID 将相同,因此设备实例ID也会一样!扩展这个,如果device1和device2是同一个设备,你可以简单地删除device1并在系统重启时重新插入它,并且设备实例ID应该是相同的!)

这是因为系统设备 ID 的任务是识别系统中的设备,而不是整个世界中的设备(因此,设备与系统分离)。

这也回答了你的第三个问题:

If I had two similar mice (or keyboards, or whatever), i.e. same manufacturer and model, would they get the same or different Instance IDs if I plug them into the same port?


关于你的最后一个问题:

Do I have any chance to uniquely identify a specific device (not just a model) ?

是的,并且(再次谈到 USB)您甚至可以在全世界唯一地识别特定设备,如果制造商在 USB 总线上提供序列号,AND 它向您保证序列号对于该特定 (VID,PID) 对是唯一的。这是一个非常严格的约束,但例如考虑一个 USB WiFi 卡(我这里有一个 Netgear):

  • 提供USB序列号
  • USB 序列号正好它的MAC地址

由于 MAC 地址根据定义是唯一的,因此您可以确定您可以唯一地识别 那个 设备,即使它插在不同的机器上。

但是,您无法唯一地识别所有 台设备,或您选择的特定设备。它必须满足这些要求。


附加测试

我测试了前面提到的 Netgear USB WiFi 卡,它具有相同的设备实例 ID,即使插入不同的端口,甚至插入不同的 机器
我测试了一个提供 USB 序列号的通用 USB 密钥,其行为与 USB WiFi 卡相同。
在这些情况下,设备实例 ID 类似于:

USB\VID_1221&PID_3234[=10=]004700356

我测试了两个相同的通用 USB 键盘,并将它们(一次一个)插入同一个 USB 集线器端口。设备实例 ID 保持不变(另外,当我插入第二个键盘时,Windows 没有显示 "Installing hardware" 弹出窗口)。设备实例 ID 为:

USB\VID_1C4F&PID_0002&15cdfaa&0&3

然后,我将其中一个键盘插入不同的 USB 端口,设备实例 ID 更改为:

USB\VID_1C4F&PID_0002&2eab04ab&0&1

更多参考资料

Microsoft page about USB Identifiers