USB通用父驱动usbccgp.sys的过滤UVC摄像头、UAC麦克风和HID设备硬件ID
激动的心情,无溢言表。。
虽然只是一个很简单的东西。。
但相于折腾了这么久,还是很开心的了。
最近有个需求,功能是这样的:
有一个USB复合设备,连接到windows系统中它在windows下的设备树如下:
- USB Composite Device(usbccgp.sys)
现的的需求是这样的,由于设备一直插在系统中,需要动态创建和卸载子设备,同时这些子设备的PDI,VID和REV需要按需求变化指定。所以安上面的要求,本人的设计方案是在根设备驱动层加一层“总线过滤层”,由该层动态创建和卸载子设备,并且由应用层可以通过IOCTL指定子设备的硬件信息。所以设备树如下:
- USBZH BUS Device
对设备的驱动将原来的USB通用父驱动usbccgp.sys改为自己写的USBZH BUS Device ,再由该驱动层创建PDO,该PDO装载系统的USB通用父驱动usbccgp.sys。
框架设计完成,开始编码,经过自己的辛苦努力,终于完成基本功能,可无奈出现了一个比较小的问题:
就是在创建了子设备后,再卸载子设备后,再次卸载驱动时会出现重启现象。在别的情况下不会出现,无论是是否创建子设备或子设备创建后不销毁都是不需要重启的。只有在销毁设备后才会出现。
这个小问题,我也是查了一段时间:
首先怀疑的是自己的子PDO没的销毁干净,怀疑是有系统残留引起的。但是自己也确实看到在IoDeleteDevice也调用了,该PDO的引用计数也降为0了。
其次怀疑的是子设备的IRP_MJ_PNP处理的问题,查了好久,也没发现什么问题。
再次怀疑的是总线驱动IRP_MN_QUERY_DEVICE_RELATIONS的问题,将各个设备的过程打印:http://www.usbzh.com/article/detail-463.html 也查看了REACTOS源代d码pnpmanger的部分源代码。。。
说多了都是泪。。。
最后一个很奇怪的感觉,就是可能是IRP的问题。随手翻了一下unPlugin的代码:
NTSTATUS UsbzhUnPluginDevice(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
.....
IoInvalidateDeviceRelations(deviceExtension->PhysicalDeviceObject, BusRelations);
return STATUS_SUCCESS;
}
呃,,竟然没有完成IRP….