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

Winapi 如何使用Windows API重置USB设备?,winapi,usb,Winapi,Usb,您知道使用Windows XP API重置USB总线的方法吗?换言之,我希望操作系统将当前连接的所有USB设备踢出,然后重新自动检测所有设备 我知道,而且我想我可以对它进行系统调用,但我希望直接调用API。好的,可以使用Setup API(SetupDiXXX函数)枚举系统中的USB设备,然后对每个设备调用WinUsb_ResetPipe,但我不确定这是否是您要寻找的。我已经有一段时间没有使用USB设备了,但我记得,没有标准的方法来重置设备(即模拟断电/通电循环)。如果可能的话,对于特定的设备,

您知道使用Windows XP API重置USB总线的方法吗?换言之,我希望操作系统将当前连接的所有USB设备踢出,然后重新自动检测所有设备


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

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

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


此外,仅仅因为从硬件角度看,您发出了总线重置,并不意味着Windows将删除表示集线器子级的PDO并重新检测它们;USB总线驱动程序可以(并且确实)执行我所描述的操作(即,在不干扰设备树的情况下执行硬件总线重置),并且只有在设备没有响应后,才会执行意外删除并将其从树中拉出。

从内核模式:您可以强制重新连接特定的USB设备,通过向其PDO发送一个
IOCTL_INTERNAL_USB_CYCLE_端口
,就好像它被拔下并重新插上一样。(这只能在内核模式下完成,例如通过帮助程序驱动程序。)此“循环”操作将导致USB复位,然后重新枚举设备。例如,如果设备返回时带有不同的USB设备描述符,则可能会为其匹配不同的驱动程序

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

  • 查找所有具有设备接口的设备
    GUID\u DEVICEINTERFACE\u USB\u HUB
    SetupDiGetClassDevs(…DIGCF\u DEVICEINTERFACE)
  • 枚举返回的设备信息集(
    SetupDiEnumDeviceInfo
  • 对于每个设备,获取
    DevInst
    成员:
  • 反复调用
    CM\u Get\u Child(DevInst)
    ,然后调用
    CM\u Get\u Sibling
    ,查看集线器的所有子节点(即USB设备)
  • 对于每个子节点,调用
    CM\u Request\u Device\u Eject

  • 也可以循环连接设备的USB集线器上的父端口。除其他外,这将导致明显的拔掉/重新拔掉动作,因为发生这种情况时,您将看到一个气球弹出

    其中很多都是缺乏文档记录的,老实说,我得到的印象是,在微软只有少数人真正了解它。我为我设计的未来设备所做的设计决定是,我打算在两侧都包括看门狗功能,以及设备端完全重置功能。这样,如果设备发现自己被搞糊涂了,它可以切断自己的电源一秒钟,然后完全重置。如果主机无法与其通信,它也可以做同样的事情。如果设备认为一切正常,但主机知道得更好,主机可以命令它重置

    对于这个问题,至少有三个API值得研究:安装API、配置管理器API和各种WMI扩展。但是,如果您打算使用嵌入式XP目标,请谨慎使用WMI,因为您必须在操作系统映像中包含许多其他您可能不需要的内容