Windows设备的惟一性标识及定位-DEVPKEY_Device_ContainerId
一个设备在接入电脑后,会由该设备所在的物理总线驱动进行枚举,并在系统中根据硬件ID(包括兼容ID)中查找最适合的驱动,并加载驱动实现对设备的驱动。以上是设备的枚举及驱动中载过程。
但在这里,我们考虑的是另一种情况,即设备的惟一性标识及系统对同一设备的物理识别。
在设备驱动层,我们一般都有一个笼统的概念。就是设备在加载后,会在注册表中记录着该设备的信息,这样当设备再次插入后,会根据注册表中已有的信息进行自动配对,这样就少了一次全局查找设备的驱动的信息,同时也会根据设备上次接入的信息并重新配置该设备。一个典型的用例就是U盘接入电脑后,当我们手动指定一个盘符后,当我们再次接入后,会同时再次会给该U盘指定相应的盘符。
如本人为了工作上的方便,在自己的工作机和家用机是都给自己的移动硬盘指定为K盘,这样无论在那台机器上,都会是K盘,这样创建的一些快捷方式也有效。
另外,我们可以通过在设备管理器中,通过查看菜单,选中“显示隐藏的设备”一项来查看设备中曾经接入过的设备。
接入过的设备以浅色显示。
如本人电脑中关于音频的设备信息:
从图中可以看到,本人电脑中曾经连接过很多音频设备。
以上是通过我们一些直观的设备信息来分析设备的信息。
另一种情况是根据设备的位置信息来标识。这个位置信息一般在设备管理器中,有相应的字段信息,如:
但有的时候,特别是对于末端设备,这个信息就是一个字符,不能很好的表示区分设备,如
所以这个信息,变显示的很业余了…
其实在Windows 7之后,微软增加了一个属性信息来标识惟一的物理设备,这个字段叫作DEVPKEY_Device_ContainerId
这个字段是一个GUID值,是由PnP Windows 即插即用 (管理器) 将此值分配给 devnode (设备节点)的 。当然这个GUID也可以通过驱动来提供,本工作过程是这样的:
当 PnP 管理器将容器 ID 分配给 devnode 时,它会首先检查 devnode 的总线驱动程序是否提供了ContainerId。 总线驱动程序通过查询请求提ContainerId,IRP_MN_QUERY_ID Parameters.QueryId.IdType 字段设置为 BusQueryContainerID。
通过COREAPI获取的节点信息如下:
如本人枚举电脑中接入的TYPE-C耳机,其容器ID是这样的:
Endpoint 0: "耳机 (HUAWEI USB-C HEADSET)" ({0.0.0.00000000}.{11c441bf-d55b-4cd5-a6da-c4af2ab989fd})
PKEY_Device_ContainerId: 39F77723-D0E6-5A93-99D2-4D2FA46E3984
PKEY_Device_FriendlyName: 耳机 (HUAWEI USB-C HEADSET)
PKEY_Device_DeviceDesc: 耳机
PKEY_Device_HardwareIds: (null)
PKEY_Device_CompatibleIds: (null)
PKEY_Device_Service: (null)
PKEY_Device_Class: (null)
PKEY_Device_ClassGuid: (null)
PKEY_Device_Driver: (null)
PKEY_Device_ConfigFlags: (null)
PKEY_Device_Manufacturer: (null)
PKEY_Device_FriendlyName: 耳机 (HUAWEI USB-C HEADSET)
PKEY_Device_LocationInfo: (null)
PKEY_Device_PDOName: (null)
PKEY_Device_Capabilities: (null)
PKEY_Device_UINumber: (null)
PKEY_Device_UpperFilters: (null)
PKEY_Device_LowerFilters: (null)
PKEY_Device_BusTypeGuid: (null)
PKEY_Device_LegacyBusType: (null)
PKEY_Device_BusNumber: (null)
PKEY_Device_EnumeratorName: USB
PKEY_Device_Security: (null)
PKEY_Device_SecuritySDS: (null)
PKEY_Device_DevType: (null)
PKEY_Device_Exclusive: (null)
PKEY_Device_Characteristics: (null)
PKEY_Device_Address: (null)
PKEY_Device_UINumberDescFormat: (null)
PKEY_Device_PowerData: (null)
PKEY_Device_RemovalPolicy: (null)
PKEY_Device_RemovalPolicyDefault: (null)
PKEY_Device_RemovalPolicyOverride: (null)
PKEY_Device_InstallState: (null)
PKEY_Device_LocationPaths: (null)
PKEY_Device_BaseContainerId: (null)
PKEY_Device_DevNodeStatus: (null)
PKEY_Device_ProblemCode: (null)
PKEY_Device_EjectionRelations: (null)
PKEY_Device_RemovalRelations: (null)
PKEY_Device_PowerRelations: (null)
PKEY_Device_BusRelations: (null)
PKEY_Device_Parent: (null)
PKEY_Device_Children: (null)
PKEY_Device_Siblings: (null)
PKEY_Device_TransportRelations: (null)
PKEY_Device_Reported: (null)
PKEY_Device_Legacy: (null)
PKEY_Device_InstanceId: (null)
PKEY_Device_ContainerId: 眣??媓??溤萹??┱耀zh-CN
PKEY_Device_ModelId: (null)
PKEY_Device_FriendlyNameAttributes: (null)
PKEY_Device_ManufacturerAttributes: (null)
PKEY_Device_PresenceNotForDevice: (null)
PKEY_Device_SignalStrength: (null)
PKEY_Device_IsAssociateableByUserAction: (null)
PKEY_Numa_Proximity_Domain: (null)
PKEY_Device_DHP_Rebalance_Policy: (null)
PKEY_Device_Numa_Node: (null)
PKEY_Device_BusReportedDeviceDesc: (null)
PKEY_Device_InstallInProgress: (null)
PKEY_Device_DriverDate: (null)
PKEY_Device_DriverVersion: (null)
PKEY_Device_DriverDesc: (null)
PKEY_Device_DriverInfPath: (null)
PKEY_Device_DriverInfSection: (null)
PKEY_Device_DriverInfSectionExt: (null)
PKEY_Device_MatchingDeviceId: (null)
PKEY_Device_DriverProvider: (null)
PKEY_Device_DriverPropPageProvider: (null)
PKEY_Device_DriverCoInstallers: (null)
PKEY_Device_ResourcePickerTags: (null)
PKEY_Device_ResourcePickerExceptions: (null)
PKEY_Device_DriverRank: (null)
PKEY_Device_DriverLogoLevel: (null)
PKEY_Device_NoConnectSound: (null)
PKEY_Device_GenericDriverInstalled: (null)
PKEY_Device_AdditionalSoftwareRequested: (null)
PKEY_DrvPkg_Model: (null)
PKEY_DrvPkg_VendorWebSite: (null)
PKEY_DrvPkg_DetailedDescription: (null)
PKEY_DrvPkg_DocumentationLink: (null)
PKEY_DrvPkg_Icon: (null)
PKEY_DrvPkg_BrandingIcon: (null)
PKEY_DeviceClass_UpperFilters: (null)
PKEY_DeviceClass_LowerFilters: (null)
PKEY_DeviceClass_Security: (null)
PKEY_DeviceClass_SecuritySDS: (null)
PKEY_DeviceClass_DevType: (null)
PKEY_DeviceClass_Exclusive: (null)
PKEY_DeviceClass_Characteristics: (null)
PKEY_DeviceClass_Name: (null)
PKEY_DeviceClass_ClassName: (null)
PKEY_DeviceClass_Icon: (null)
PKEY_DeviceClass_ClassInstaller: (null)
PKEY_DeviceClass_PropPageProvider: (null)
PKEY_DeviceClass_NoInstallClass: (null)
PKEY_DeviceClass_NoDisplayClass: (null)
PKEY_DeviceClass_SilentInstall: (null)
PKEY_DeviceClass_NoUseClass: (null)
PKEY_DeviceClass_DefaultService: (null)
PKEY_DeviceClass_IconPath: %windir%\system32\mmres.dll,-3031
PKEY_DeviceClass_ClassCoInstallers: (null)
PKEY_DeviceInterface_FriendlyName: HUAWEI USB-C HEADSET
PKEY_DeviceInterface_Enabled: (null)
PKEY_DeviceInterface_ClassGuid: (null)
PKEY_DeviceInterfaceClass_DefaultInterface: (null)
但有的时候系统中提供的容器ID是这样的,也不知道是为什么:
如系统自带的扬声器容器ID:
Endpoint 1: "扬声器 (Realtek(R) Audio)" ({0.0.0.00000000}.{a7d27728-c8ca-441b-b5a7-7b9a1ff250c4})
PKEY_Device_ContainerId: 00000000-0000-0000-FFFF-FFFFFFFFFFFF
以上的信息是本人通过COREAPI获取的,其实更加通用的是通过SetupApi函数来获取:函数为:SetupDiGetDeviceProperty 参数为 DEVPKEY_Device_ContainerId
本人编写的audioinfo.exe在USB中文网的技术交流群中,需要的可在本站底部扫二维码加群,然后在USB调试工具&测试软件目录中获取。
关于usQueryContainerID的信息可见文档:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/install/devpkey-device-basecontainerid