Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reset USB devices using the Windows API?

Tags:

winapi

usb

Do you know a way to use the Windows XP API to reset the USB bus? In other words, I'd like the OS to kick out any USB devices that are currently connected, and then auto-detect everything anew.

I'm aware of devcon, and I suppose I could do system calls out to it, but I'm hoping for a direct call into the API.

like image 497
Isaac Moses Avatar asked Jun 12 '09 17:06

Isaac Moses


1 Answers

From kernel mode: You can force a specific USB device to be re-connected, as if it was unplugged and replugged again, by sending an IOCTL_INTERNAL_USB_CYCLE_PORT to its PDO. (This can only be done from a kernel mode, e.g. through a helper driver.) This 'cycle' operation will cause a USB reset to occur, after which the device would be re-enumerated. For example, if the device comes back with a different USB device descriptor, a different driver may be matched for it.

From user mode: You can do this by ejecting the device through the CfgMgr API. For example, to go over all USB hubs and eject all devices:

  1. Find all devices having device interface GUID_DEVINTERFACE_USB_HUB with SetupDiGetClassDevs(... DIGCF_DEVICEINTERFACE).
  2. Enumerate over the returned device information set (SetupDiEnumDeviceInfo).
  3. For each device, get the DevInst member:
    1. Invoke CM_Get_Child(DevInst) and then CM_Get_Sibling repeatedly to go over all child nodes of the hub (i.e. the USB devices).
    2. For each child node, call CM_Request_Device_Eject.
like image 122
Ilya Avatar answered Sep 28 '22 17:09

Ilya