MacOS: empty path for devices in long USB chain #236
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi#236
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem: Plug two 8-port USB hubs in a chain, add a HID device to second hub: hidapi returns empty string for path.
This was an old signal11 issue https://github.com/signal11/hidapi/issues/301 and I think we still have it. Over in
node-hidland (https://github.com/node-hid/node-hid/issues/417), someone was experiencing this problem and had a good test showing bothhidapitesterandnode-hidbeing able to get a path when the device is plugged in at one leaf of the USB tree but not at the other.I think the issue happens at Line 464 of hidapi/mac/hid.c and I think it's because
io_string_tis 512 characters and MacOS USB paths are already > 200 chars if you have just a single external USB hub.I'm looking into finding definitions of
io_string_tandIORegistryEntryGetPath()to see what our options are.(The reason why I specify 8-port hubs above is those are implemented as two 4-port hubs, meaning the external USB tree look can look like: hub->hub->hub->hub->device, depending on where you plug what into what)
It looks like perhaps a solution is to use
IORegistryEntryGetRegistryEntryID()instead ofIORegistryEntryGetPath(): https://github.com/Yubico/python-fido2/pull/94/commits/61c2a5d852118b60fbd19c0be91043a8a2172e78Related to https://github.com/libusb/hidapi/issues/127 and
github.com/flirc/hidapi@8d251c3854(the fix)?I think so. I'll be attempting it this weekend.
@Youw Maybe this can be merged as well.
github.com/flirc/hidapi@8d251c3854I'd suggest a few changes to flirc/hidapi@8d251c3 before accepting it.
https://github.com/libusb/hidapi/issues/249#issuecomment-894585228
I was hit by this issue as well, since I have two external powered USB hubs (one 7-port and one 11-port) which are actually complicate hubs (nested hub). So even the first hub (D-Link USB 3 powered 7-port hub) already cause issues.
@Youw @todbot It seems to me that hidapi has changed a lot that commit
github.com/todbot/hidapi@8839e544a6no longer applies. Please help if you got time. Thanks.I'll work on it this week.
Maybe we could use
IORegistryEntryGetPath()and simply pass it a char buffer that‘s greater than 512 bytes.(Since
io_string_tis just achar[512])Notice that the Swift version of this function just uses a char buffer of any size and the docs mention nothing about a 512 character limit.
I'm confident that won't work. The implementation of
IORegistryEntryGetPathexpectschar[512]as an input, which practically means that that parameter is passed by pointer/reference, but even if we pass a pointer/reference to a larger buffer - the implementation will only use what it originally expects.I think it might be worth a shot.
The documentation reads like it just expect a char buffer of any length not just 512. E.g. „IORegistryEntryGetPath() will fail […] if the buffer is not large enough to contain the path.“
And the documentation is missleading. The buffer size is not passed into
IORegistryEntryGetPath. It is hard-coded in its declaration.This probably isn't relevant anymore since the ID-based method is already implemented, but just out of interest, I dug through the Apple open source files and took a look at the implementation of
IORegistryEntryGetPath(), and you're right - the limit of 512 characters is hardcoded into it.However I found a newer pair of functions called
IORegistryEntryCopyPath()andIORegistryEntryCopyFromPath()which seem to do the same thing asIORegistryEntryGetPath()andIORegistryEntryFromPath()but relying on CFStringRef instead of io_string_t. I'm quite certain that these functions don't have the 512 character limit.However they are only available starting with macOS 10.11.
This should be fixed by #322. Tested with my Mac Mini M1.