You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
From the author osy:
It's a well known issue on macOS that you cannot use libusb to attach to an interface already claimed by an KEXT for exclusive access. The common workaround is to do sudo kextunload or inject a codeless KEXT. Both require admin permissions, and does not work for all devices on latest macOS. Additionally, SIP has to be disabled to inject a codeless KEXT, making it a pain to work with USB devices.
This patch uses the kUSBReEnumerateCaptureDeviceBit introduced back in macOS 10.10 which will tell the kernel to unload all other drivers for you without needing any dirty hacks.
Unfortunately, a side effect is that it will reset (simulate unplug-replug) the device to do this and so I didn't want to make it the default behaviour of libusb_open as that may, for example, cause all USB devices to be reset if the application decides to read the product string of every device attached. I can't find a good way to change this without touching the API specs, so I introduced a new option LIBUSB_OPTION_FORCE_CAPTURE_OPEN that lets you toggle the "capture" behaviour.
Also, the way libusb_close works makes it a bit awkward to implement the "release" of the captured device because just closing the handle does not tell the KEXTs to start matching again and calling USBDeviceReEnumerate with kUSBReEnumerateReleaseDeviceBit will also cause the device to be reset which then makes the next call of libusb_open fetch a stale cached object and fail. However, calling darwin_reset_device to address the stale cache issue will cause the device to be opened again, which causes another "capture" and then the OS will never get the device back. So the workaround of this is as follows:
When darwin_close is called, if the device is captured, then darwin_reset_device will first be called.
darwin_reset_device_capture will call USBDeviceReEnumerate and release the capture.
darwin_restore_state calls darwin_open indicating that capture should NOT be used.
darwin_open succeeds and the device is re-opened without the capture bit.
Call returns to darwin_close who calls USBDeviceClose on the non-captured device handle.
The text was updated successfully, but these errors were encountered:
mcuee
changed the title
macOS: implement device capture to force unload of KEXT drivers #893
macOS: implement device capture to force unload of KEXT drivers
Apr 6, 2021
Pull request https://github.com/libusb/libusb/pull/893 has been closed but the idea seems to be pretty interesting.
From the author osy:
It's a well known issue on macOS that you cannot use libusb to attach to an interface already claimed by an KEXT for exclusive access. The common workaround is to do
sudo kextunloador inject a codeless KEXT. Both require admin permissions, and does not work for all devices on latest macOS. Additionally, SIP has to be disabled to inject a codeless KEXT, making it a pain to work with USB devices.This patch uses the
kUSBReEnumerateCaptureDeviceBitintroduced back in macOS 10.10 which will tell the kernel to unload all other drivers for you without needing any dirty hacks.Unfortunately, a side effect is that it will reset (simulate unplug-replug) the device to do this and so I didn't want to make it the default behaviour of
libusb_openas that may, for example, cause all USB devices to be reset if the application decides to read the product string of every device attached. I can't find a good way to change this without touching the API specs, so I introduced a new optionLIBUSB_OPTION_FORCE_CAPTURE_OPENthat lets you toggle the "capture" behaviour.Also, the way
libusb_closeworks makes it a bit awkward to implement the "release" of the captured device because just closing the handle does not tell the KEXTs to start matching again and callingUSBDeviceReEnumeratewithkUSBReEnumerateReleaseDeviceBitwill also cause the device to be reset which then makes the next call oflibusb_openfetch a stale cached object and fail. However, callingdarwin_reset_deviceto address the stale cache issue will cause the device to be opened again, which causes another "capture" and then the OS will never get the device back. So the workaround of this is as follows:darwin_closeis called, if the device is captured, thendarwin_reset_devicewill first be called.darwin_reset_device_capturewill callUSBDeviceReEnumerateand release the capture.darwin_restore_statecallsdarwin_openindicating that capture should NOT be used.darwin_opensucceeds and the device is re-opened without the capture bit.darwin_closewho callsUSBDeviceCloseon the non-captured device handle.The text was updated successfully, but these errors were encountered: