macOS: implement kernel driver detach #911
macOS: implement kernel driver detach #911
Conversation 52 Commits 5 Checks 0
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 The original implementation relied on a new option but that has been superseded by a new implementation which uses the First, the Second, Third,
I've only tested this with hidtest (modified to use libusb on OSX) and with libusbredir (in spice-gtk). More testing is needed specifically with calling libusb_detach_kernel_driver on multiple interfaces. On calling libusb_detach_kernel_driver before libusb_open or libusb_attach_kernel_driver after libusb_close (I'm not sure if this should be a supported use case but the APIs don't prescribe the usage order...). I'm also not sure why |
|
if (dpriv->capture_count > 0) { |
/* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */ |
kresult = (*(dpriv->device))->ResetDevice (dpriv->device); |
Yup I tried that the main problem is if you need authorization (it’s not running as root and it shows the user a pop-up to approve the device), it will need it again after calling re-enumerate (with or without the release flag). This means the user needs to click “approve” after every re-enum.
Perhaps someone with a usb sniffer can check the behaviour of the reset call again?
I use libusb with a computer emulator called QEMU. I was able to test out the changes in the above patches. They do work. I was able to listen to MP3 files in several of my VM's using a real attached USB sound card. Good job everyone. |
osy commented on May 17 •
@hjelmn was USB reset tested? I’m still having some issues that I think might be related to reset but I don’t have any sniffer to test. I’ve been locally experimenting with a patch that implements the reenumeration but the kernel drivers always reattach as soon as you re-enumerate and then you can re-capture but there is a period of time when the kernel drivers take control and can possibly modify the device state. I’m still not sure how to do a “clean” reset while keeping capture state. |
I would like to get these changes up in a 1.0.25 RC so a wider audience can start testing. I don't have the equipment to test that reset works as expected. If there is a known issue we can add a known issues list while a fix is developed. Given how capture works I don't think we can easily fix it if it is broken. |
I tested this with various devices (gamepads, mouse, kbd, camera, USB Disk, ...) and it works like a charm! Thanks a lot. |
mcuee commented on Aug 8 •
mcuee commented on Aug 8 •
Ref: Device Capture
Discussion |
Ref: Property List Key: com.apple.vm.device-access Discussion |
https://developer.apple.com/documentation/bundleresources/entitlements Discussion You configure entitlements for your app by declaring capabilities for a target in Xcode. Xcode records capabilities that you add in a property list file with the .entitlements extension. You can also edit the entitlements file directly. When code signing your app, Xcode combines the entitlements file, information from your developer account, and other project information to apply a final set of entitlements to your app. |
mcuee commented on Aug 8 •
After changing that line, it still does not work, strange.
Full debug log. click to expand |
It's because IOServiceAuthorize launches a GUI popup. I don't think it works with sudo. |
@osy Still I am not 100% sure if this is true. It seems to me claiming interface can work with your pull request.
|
Running with sudo.
Full debug log. click to expand |
So sudo does work with commit 6a902c3 Late commits somehow make running sudo not working anymore. Here is with a USB Flash disk.
|
I can see macOS complained about ejecting the disk (so the kernel driver detach is working). And the disk disappeared from my desktop. Later the disk reappears (so the kernel driver re-attach seems to work as well). BTW, ignore the error message after releasing interface, that was fixed later. |
hjelmn commented on Aug 8 •
Ok. Should work again...
|
Yes latest git head is good.
|
And hidtest works as well.
|
And it is also okay with USB Composite Devices.
|
@hjelmn @osy We may need to improve the documentation here. The other thing is to document how to get the entitlement (I am not using Xcode so I have not tried it myself). |
There actually isn’t a documented way. I had to manually contact Apple to get them. They are included with the VM entitlements and there’s no signup form or anything. You just have to purchase an Apple Developer membership and contact their technical support. |
I see. Thanks. Maybe I will just mention this in the wiki. |
@osy I think the Developer provisioning profile process should be similar to the following. Is that correct? |
A bit of mentioning in Apple websites. But I agree it is not well documented. https://developer.apple.com/documentation/bundleresources/entitlements |
Improved the error message a bit:
|
It's took me a while for reading history above, and a little bit confused. Is there any solution? macOS12 has released its official version, the libuvc still can't access camera anyhow. I did use the com.apple.vm.device-access in the entitlements. |
mcuee commented 28 days ago •
@llinshenzhen |
This is probably not a good place to continue the discussion as it has already been closed. |
This is ok for now but if possible it would be better if we can be consistent and always re-enumerate the device. This ensures that the device is actually reset. I am surprised we can't just specify capture again on reset but I have to assume you have already tried this. We may want to call this out somewhere in the docs so that users are aware that reset may not actually reset when capturing a device.