Windows设备的ID及DeviceCapability
设备ID
Windows设备的ID常见的有以下四种:
- BusQueryDeviceID
- BusQueryInstanceID
- BusQueryHardwareIDs
- BusQueryCompatibleIDs
BusQueryDeviceID
BusQueryDeviceID是由总线驱动程序上报给系统的。一般是第一BusQueryHardwareIDs,其作为设备的类标识。其主要作用是和BusQueryInstanceID生成InstancePath.
BusQueryInstanceID
BusQueryInstanceID也是由总线驱动程序上报。其作为同类设备BusQueryDeviceID
下的实例区分。
BusQueryHardwareIDs
BusQueryHardwareIDs是一个集合,一个设备所有名字集合,其以REG_MULTI_SZ的形式返回。
硬件ID用于设备定制驱动的标识校验。
- HID代表总线类型。
- VID PID是USB设备的厂商ID和产口ID
- REV是USB设备的BCDDevie
- MI:是接口描述符ID
- Col:只出现在HID设备,是HID报告描述符应用集合的位次索引。
BusQueryCompatibleIDs
兼容ID是按设备类集合。
其主要用于兼容或者说是类驱动的标识校验。
https://www.usb.org/defined-class-codes
在Windows系统中,一般专门定制驱动的优先级高于兼容驱动。但有时这不是绝对的,因为驱动的加权也会计算驱动的签名。
更多的可以见:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/how-setup-ranks-drivers--windows-vista-and-later-
2 设备实例路径InstancePath
影响设备实例路径由以下几个要素决定:BusQueryDeviceID、BusQueryInstanceID、DeviceCapabilty中的Unique和父节点的InstancePath相关。
If(DeviceCapability.Unique)
{
InstancePath = BusQueryDeviceID. BusQueryInstanceID
}
Else
{
InstancePath = BusQueryDeviceID.Hash(父节点InstancePath).InstanceID
}
其中父节点InstancePath 哈希的学名为ParentIdPrefix,其实现机制为PDO设备的层级深度和父节点的Hash值。
ParentIdPrefix可以在注册表下可以看到:
计算机计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_351E&PID_00CC\7&314ba276&0&1
ULONG GetInstancePathHas(WCHAR* pInstancePath)
{
ULONG Hash = 0;
ULONG nLen = (ULONG)wcslen(pInstancePath);
PWCHAR _ep = pInstancePath + nLen;
ULONG _chHolder = 0;
while (pInstancePath < _ep)
{
_chHolder = 37 * _chHolder + (unsigned int)(*pInstancePath++);
}
Hash = abs((INT64)(314159269 * _chHolder)) % 1000000007;
return Hash;
}
3 DeviceCapability
在注册表键值为:Capabilities,通过Windbg查看的数据结构为:
kd> dt _DEVICE_CAPABILITIES
nt!_DEVICE_CAPABILITIES
+0x000 Size : Uint2B
+0x002 Version : Uint2B
+0x004 DeviceD1 : Pos 0, 1 Bit
+0x004 DeviceD2 : Pos 1, 1 Bit
+0x004 LockSupported : Pos 2, 1 Bit
+0x004 EjectSupported : Pos 3, 1 Bit
+0x004 Removable : Pos 4, 1 Bit
+0x004 DockDevice : Pos 5, 1 Bit
+0x004 UniqueID : Pos 6, 1 Bit
+0x004 SilentInstall : Pos 7, 1 Bit
+0x004 RawDeviceOK : Pos 8, 1 Bit
+0x004 SurpriseRemovalOK : Pos 9, 1 Bit
+0x004 WakeFromD0 : Pos 10, 1 Bit
+0x004 WakeFromD1 : Pos 11, 1 Bit
+0x004 WakeFromD2 : Pos 12, 1 Bit
+0x004 WakeFromD3 : Pos 13, 1 Bit
+0x004 HardwareDisabled : Pos 14, 1 Bit
+0x004 NonDynamic : Pos 15, 1 Bit
+0x004 WarmEjectSupported : Pos 16, 1 Bit
+0x004 NoDisplayInUI : Pos 17, 1 Bit
+0x004 Reserved1 : Pos 18, 1 Bit
+0x004 WakeFromInterrupt : Pos 19, 1 Bit
+0x004 Reserved : Pos 20, 12 Bits
+0x008 Address : Uint4B
+0x00c UINumber : Uint4B
+0x010 DeviceState : [7] _DEVICE_POWER_STATE
+0x02c SystemWake : _SYSTEM_POWER_STATE
+0x030 DeviceWake : _DEVICE_POWER_STATE
+0x034 D1Latency : Uint4B
+0x038 D2Latency : Uint4B
+0x03c D3Latency : Uint4B
其中注册表中它的值内容为:
Capabilities = (Capabilities->LockSupported) |
(Capabilities->EjectSupported << 1) |
(Capabilities->WarmEjectSupported<< 1) |
(Capabilities->Removable << 2) |
(Capabilities->DockDevice << 3) |
(Capabilities->UniqueID << 4) |
(Capabilities->SilentInstall << 5) |
(Capabilities->RawDeviceOK << 6) |
(Capabilities->SurpriseRemovalOK << 7) |
(Capabilities->HardwareDisabled << 8) |
(Capabilities->NonDynamic << 9);