如何使用Windows API重置USB设备?

时间:2009-06-12 17:30:14

标签: winapi usb

您是否知道使用Windows XP API重置USB总线的方法?换句话说,我希望操作系统能够启动当前连接的任何USB设备,然后重新自动检测所有设备。

我知道devcon,我想我可以对它进行系统调用,但我希望能直接调用API。

4 个答案:

答案 0 :(得分:12)

从内核模式:您可以通过向其PDO发送IOCTL_INTERNAL_USB_CYCLE_PORT来强制重新连接特定的USB设备,就像它已拔下并重新插入一样。 (这只能通过内核模式完成,例如通过辅助驱动程序。)此“循环”操作将导致USB重置,之后将重新枚举设备。例如,如果设备带有不同的USB设备描述符,则可以匹配不同的驱动程序。

从用户模式:您可以通过CfgMgr API弹出设备来执行此操作。例如,要遍历所有USB集线器并弹出所有设备:

  1. 使用GUID_DEVINTERFACE_USB_HUB查找具有设备接口SetupDiGetClassDevs(... DIGCF_DEVICEINTERFACE)的所有设备。
  2. 枚举返回的设备信息集(SetupDiEnumDeviceInfo)。
  3. 对于每个设备,请获取DevInst成员:
    1. 重复调用CM_Get_Child(DevInst)然后CM_Get_Sibling以遍历集线器的所有子节点(即USB设备)。
    2. 对于每个子节点,请致电CM_Request_Device_Eject

答案 1 :(得分:2)

好吧,使用可以使用Setup API(SetupDiXXX函数)来枚举系统中的USB设备,然后在每个设备上调用WinUsb_ResetPipe,但我不确定这是否是您正在寻找的。自从我使用USB设备以来已经有一段时间了,但我记得,没有标准的方法来重置设备(即模拟断电/上电周期)。如果特定设备可能,则必须向驱动程序发送适当的IOCTL(使用DeviceIOControl)。 IOCTL会因制造商而异。

答案 2 :(得分:2)

也可以在设备连接的USB集线器上循环父端口。除其他外,这将导致显而易见的拔出/重新插入操作,因为当发生这种情况时,您将看到气球弹出窗口。

其中大部分内容都没有记录,老实说,我得到的印象是,微软中只有少数人真正理解它。我设计的未来设备的设计决定是我打算在两侧都包括看门狗功能,以及设备端完全复位功能。这样,如果该设备的数字出来它是混乱的,它可以只是削减自己的权力一秒钟,完全复位,如果主机不能与它通信,它可以做同样的事情,如果设备认为一切很好,但主人知道的更好,主持人可以命令它重置。

至少有三个API值得研究此问题:Setup API,Config Manager API和各种WMI扩展。但是,如果您打算使用嵌入式XP目标,请谨慎使用WMI,因为您必须在操作系统映像中包含许多其他内容,否则您可能不需要这些内容。

答案 3 :(得分:0)

据我所知,没有办法做到这一点 - 您可以发出命令让PnP 重新扫描新设备的总线,但这与发布总线不同重启。

此外,仅仅因为从硬件角度来看,您发布了总线重置并不意味着Windows将删除代表集线器子集的PDO并重新检测它们; USB总线驱动程序可以(并且确实)完成我所描述的内容(即,在不干扰设备树的情况下发出硬件总线重置),并且只有在设备之后设备没有响应它是否会发出意外删除和把它从树上拉出来。