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:
- Find all devices having device interface
GUID_DEVINTERFACE_USB_HUB
with SetupDiGetClassDevs(... DIGCF_DEVICEINTERFACE)
.
- Enumerate over the returned device information set (
SetupDiEnumDeviceInfo
).
- For each device, get the
DevInst
member:
- 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).
- For each child node, call
CM_Request_Device_Eject
.