如何从ETW提取USB设备类型与驱动器号并区分设备类别?
嘿,我来帮你搞定这个ETW日志器的问题——之前做USB设备监控的时候,我也在设备类型区分和驱动器号提取上卡过壳,分享些实用的经验给你:
1. 区分USB大容量存储设备与其他USB设备
你现在只用Summary == "New USB Device Information"过滤确实不够,得深挖USBHUB3事件里的设备描述符和接口描述符字段:
- 标准的USB大容量存储设备,其
DeviceDescriptor.bDeviceClass值为0x08(对应USB类定义里的Mass Storage类)。 - 但要注意复合设备(比如带存储功能的相机),这类设备的主设备类可能是
0xEF(Miscellaneous),但它的接口描述符里InterfaceDescriptor.bInterfaceClass会是0x08。
在Microsoft Messages Analyzer里,你可以展开事件的详细结构,找到这些字段:
- 选中捕获到的新设备事件,在右侧面板展开
Fields>DeviceDescriptor - 查看
bDeviceClass的值;如果是复合设备,再展开InterfaceDescriptors数组,检查每个接口的bInterfaceClass
如果要在ETW过滤里直接筛选,你可以用类似这样的条件:
Microsoft_Windows_USB_USBHUB3.DeviceDescriptor.bDeviceClass == 8 OR (Microsoft_Windows_USB_USBHUB3.DeviceDescriptor.bDeviceClass == 239 AND Microsoft_Windows_USB_USBHUB3.InterfaceDescriptors[*].bInterfaceClass == 8)
2. 提取USB设备类型与驱动器号
设备类型
除了上面提到的类字段,你还可以从DeviceDescriptor.bDeviceSubClass和bDeviceProtocol进一步细分(比如SCSI透明命令集是0x06)。另外,DeviceInstanceId字段(格式类似USB\VID_XXXX&PID_XXXX\...)里的VID/PID也能帮你识别特定厂商的设备。
驱动器号
划重点:USBHUB3的事件本身不会直接返回驱动器号,因为驱动器号是Windows存储栈分配的,得结合另一个ETW提供者的事件:
- 推荐订阅
Microsoft_Windows_VolumeManager提供者,监听VolumeMount事件——这个事件里会包含DriveLetter字段,以及关联的DeviceId。 - 你需要把USBHUB3事件里的
DeviceInstanceId和VolumeMount事件里的DeviceId做关联:通常DeviceId会包含DeviceInstanceId里的VID/PID部分(比如\\?\usb#vid_xxxx&pid_xxxx#...),可以通过字符串匹配来关联两者。
操作步骤参考:
- 先从USBHUB3的新设备事件中提取
DeviceInstanceId,确认是大容量存储设备 - 等待
VolumeMount事件,检查事件中的DeviceId是否包含该DeviceInstanceId的关键部分 - 匹配成功后,提取
DriveLetter字段(格式比如D:)
如果需要更底层的存储事件,也可以订阅Microsoft_Windows_StorageClass提供者,它的DiskClassDeviceEvent也会包含设备和卷的关联信息。
3. 整合到状态机触发逻辑
你可以这样设计状态机的流程:
- 状态1:等待新USB设备事件:捕获USBHUB3的新设备事件,过滤出大容量存储设备,记录其
DeviceInstanceId - 状态2:等待驱动器号分配:监听VolumeMount事件,匹配之前记录的
DeviceInstanceId,拿到驱动器号后触发程序唤醒 - 额外处理:如果一段时间内没拿到驱动器号,可以超时重置状态,避免卡住
最后提醒下,捕获ETW事件需要管理员权限,编程的时候记得提权或者让用户以管理员身份运行程序。
内容的提问来源于stack exchange,提问作者igal k
相关产品推荐
相关产品推荐

