Removes a possible cause for a segmentation fault observed in `CFSetGetCount`.
Related: #208 ("Segmentation fault on Mac OS Catalina").
Signed-off-by: Jonas Malaco <jonas@protocubo.io>
In one of the early versions of macOS, when you try to close the device
with IOHIDDeviceClose() that is being physically disconnected.
Starting with some version of macOS, this crash bug was fixed,
and starting with macSO 10.15 the opposite effect took place:
in some environments crash happens if IOHIDDeviceClose() is _not_ called.
This patch is to keep a workaround for old versions of macOS,
and don't have a leak in new/tested environments.
Fixes: #144.
The compiler provided the following warning message:
```
hid.c:830:29: warning: format specifies type 'void *' but the argument has type 'IOHIDDeviceRef' (aka 'struct __IOHIDDevice *') [-Wformat-pedantic]
sprintf(str, "HIDAPI_%p", dev->device_handle);
~~ ^~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
```
Previously the interface would never be set on Mac.
This presents a big pain because retrieving interface numbers can be the
only way to distinguish between the interfaces returned by HIDAPI.
This change makes it possible to retrieve interface number from an
hid_device_info on Mac for USB HID devices only.
It is unclear if the macOS IOKit library returns valid interface numbers
for non-HID USB devices. Because of this, I have opted to simply skip
that case - leave it initialised to `-1`.
In the future, we can easily relax this restriction if it turns out
IOKit correctly returns interface number with non-HID USB devices. For
now, this commit brings 90% of the value at 5% of the risk.
Change hid_enumerate() and hid_open_path() to use IOKit IOService:/
paths to uniquely identify devices, instead of creating a path
(done by the make_path() function).
The path passed to hid_open_path() now must be a valid path to an
IOHIDDevice in the IOService plane, like:
"IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/
AppleUSBEHCI/PLAYSTATION(R)3
Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver"
On Mac OS X 10.8.x (Mountain Lion), if a device is connected, opened, then
closed, then unplugged, subsequent calls to hid_enumerate() will still
list the device (even though it's been unplugged). If the device is
plugged in again, a second instance will show up in the list and often it
will be impossible to open either. Github user TamToucan figured out that
in hid_enumerate() if a call is made to IOHIDManagerSetDeviceMatching()
before the call to IOHIDManagerCopyDevices() that this will clear the
problem.
Thanks to TamToucan for figuring this out.
Passing product_id=0 will match any product of a given vendor. This patch
makes it also possible to use vendor_id=0 to match any vendor for a given
product id.
Windows code added to Ludovic's patch by Alan Ott.
Using locations makes the path the same for each run of a HIDAPI based
program. This is useful for opening devices which don't have a serial
number, and where multiple devices of the same type are attached to the
system at once.
This references pull request #78.
There were errors regarding the length of strings in conversion from CFString
to wchar_t.
Thanks to github user nikolajsheller for pointing this out in pull request #80.
Use kIOHIDOptionsTypeSeizeDevice instead of kIOHIDOptionsTypeNone to
avoid interferences with other applications trying to use the HID device
at the same time.
Remove device_list, which was used to match up IOHIDDeviceRef's and
hid_device's in the device removal callback. This was needed because the
removal callback was attached to the whole IOHIDManager, instead of
individual IOHIDDevices.
Instead attach the removal callback to each IOHIDDevice individually,
and have a pointer to the device's hid_device passed to the callback.
This adds the familiar autotools build system and associated documentation
for Linux, FreeBSD, Mac, MinGW, and Cygwin. The old Makefiles have been
kept, and where appropriate have been renamed Makefile-manual.
Thanks to Peter Stuge, Ludovic Rousseau, Xiaofan Chen, Alex Dupre, and
Segher Boessenkool for providing testing, review, and suggestions, and to
Ludovic Rousseau for providing patches which contributed to this commit.
get_serial_number()
get_manufacturer_string()
get_product_string()
This is to match the documentation in the header file, returning 0 on
success and -1 on error.