Windows系统实现USB设备的拨出与重新插入
最近在搞USBHOUND,原理比较简单,但是涉及的东西还是比较多,这不,为了搞清楚URB之间的传递脉路,又开始进入了USBCCGP淅代码中。
USBCCGP是Windows系统中关于USB比较重要的一个驱动,其实原了USB物理复合设备到逻辑设备的基本功能,其中有大量的关于USB相关处理请求,是值得我们在开发USB驱动时借鉴。
这里我们注意到两个IOCTL,分别为:
IOCTL_INTERNAL_USB_RESET_PORT:用于USB设备端口的复位
A driver can use this request to reset the upstream port of the device it manages. After a successful reset, the bus driver reselects the configuration and any alternative interface settings that the device had before the reset occurred. All pipe handles, configuration handles and interface handles remain valid.
IOCTL_INTERNAL_USB_CYCLE_PORT:模拟USB设备的拨出与再插入。
This I/O request simulates a device unplug and replug on the port associated with the PDO.
以上的两个IOCTL功能类似,并且不能实现重入,并且是发给真实的物理设备的,故在USBCCPG的FDO中对其下层PDO操作。。
case IOCTL_INTERNAL_USB_RESET_PORT:
case IOCTL_INTERNAL_USB_CYCLE_PORT:
if (parentFdoExt->state == STATE_STARTED){
status = ParentResetOrCyclePort(parentFdoExt, irp, ioControlCode);
}
else {
DBGERR(("ParentInternalDeviceControl (IOCTL_INTERNAL_USB_RESET_PORT): BAD PNP state! - parent has state %xh.", parentFdoExt->state));
status = STATUS_DEVICE_NOT_READY;
}
break;
并且,这里对该设备执行这两个操作,也只能是正常工作并已经启动了的设备。其处理函数是通过ParentResetOrCyclePort实现的。
其大致原理是对该请求IRP进行判断是否是有相同的IRP已经在执行,如果已经有,则将该IRP pending,并持入待完成队列。如果没有,则同步执行给下层设备PDO.当执行完成时,则完成已经挂起的所有IRP,实现多个相同的IRP请求OVERLAP功能。
/*
- Some redundant RESET or CYCLE irps may have been sent while we
- were processing this one, and gotten queued.
- We’ll complete these now that the parent has been reset.
*/
不过在应用层其功能实现,应该和USBTREEVIEW这个操作有关,详细的可以参见USBVIEW代码。
这里标记一下。