Modern Windows implementations don't allow opening HID devices in
READ/WRITE mode if they are claimed by the system. Examples of such
devices include keyboards and mice.
However, these devices can be opened without READ/WRITE permissions, in
order to allow sending and receiving feature reports.
If open_device() fails, retry without requesting READ/WRITE permissions.
This inverts the logic of the parameter to open_device().
It is a refactor of #44 by @pqu.
Signed-off-by: Sean Cross <sean@xobs.io>
Limit the size of the buffer passed to hid_get_manufacturer_string(),
hid_get_product_string(), and hid_get_serial_number_string() because
calling the underlying win32 functions with larger buffers causes them
to fail.
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"
Problem reported by the Coverity tool
CID 1042532 (#1 of 1): Unchecked return value from library
(CHECKED_RETURN)2. check_return: Calling function
"fstat(dev->device_handle, &s)" without checking return value. This
library function may fail and return an error code.
In the past, there was desire to make hid_open() open devices
exclusively, preventing devices from being opened more than once.
Unfortunately, recent versions of Windows have made this largely
impossible for many devices, as it appears that Windows itself is
holding certain HID devices open or preventing them from being
opened in exclusive mode.
This patch will always open devices in SHARED mode on Windows.
Make sure hid_device_info.serial_number is not null before passing it to
wcscmp().
When libusb can't open a device for any reason (e.g. file system
permissions), hid_device_info.serial_number is NULL. Make sure
hid_device_info.serial_number is not null before passing it to wcscmp(3).
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
hid_read() and hid_read_timeout() now return the number of bytes copied,
instead of the number of bytes returned by GetOverlappekdResult() (which is
the maximum report size for the device). This limits the return value to
the requested length (buffer size), matching the behavior on other
platforms.
m4/ax_pthread.m4 says that PTHREAD_CFLAGS needs to be provided to the
linker line as well as the compile line. This enables static library
builds of hidapi.
Refactor version detection into a function.
Handle versions of form X.Y.Z as well as X.Y.
Don't do workarounds for old kernels if version cannot be detected.
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.
While triaging libusb bugs, I took an indepth look at:
https://github.com/libusbx/libusbx/issues/25
This has lead me to the conclusion that there are 2 issues with hidapi's
libusb code wrt waiting for the transfer cancellation on read_thread()
exit:
1) There is a race where hid_close() can successfully cancel the transfer
after a read_callback() has submitted it but before read_thread() checks
shutdown_thread. If this race is hit, then the libusb_cancel_transfer()
in read_thread() will fail, causing read_thread() to not call
libusb_handle_events() to complete the cancelled transfer. hid_close()
will then free the transfer, and if later on libusb_handle_events() gets
called on the same context, it will try to complete the now freed
transfer. This is what I believe leads to the segfault described in
https://github.com/libusbx/libusbx/issues/25
2) hidapi uses one read_thread() per hid_device, so if there are multiple
hid_devices then there are multiple threads calling
libusb_handle_events(), in this case there is no guarantee that a single
libusb_handle_events() call will successfully lead to the cancelled
transfer being completed. If the transfer completion is already handled
by another read_thread() and there are no other events, then the
libusb_handle_events() call will hang, and thus the pthread_join() and
thus hidapi_close() will hang.
As number 2 is a generic problem found in more libusb apps, libusb has
gotten a new API called libusb_handle_events_completed(), which takes an
extra pointer to an int, whose contents must be set to nonzero on
completion by the callback, which allows waiting for the completion of a
specific transfer in a race-free manner.
This patch switches the waiting for the transfer's final completion to
using libusb_handle_events_completed(), thereby fixing both issues. Note
the while is necessary since libusb_handle_events_completed(), like
libusb_handle_events(), will return as soon as it has handled *any* event.
The difference with libusb_handle_events_completed() is that once it has
all the necessary internal libusb locks, it checks the contents of the
completed parameter, and will bail if that has become nonzero without
waiting for further events.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Create a new free_hid_device() function which takes care of all the
resources in hid_device which may need to be freed/released.
Reported-by: Johan Lindh <johan@linkdata.se>
It appears that calls to read() when in non-blocking mode will not set errno
to other than EAGAIN when the a device has been disconnected. Note that
this is the same errno code set when there is simply no data to return.
Make it so that poll() is used, in non-blocking mode, to check the
status of the device. In blocking mode though, poll() is not needed.
Some composite devices do not have bDeviceClass set to
LIBUSB_CLASS_PER_INTERFACE and were ignored when enumerating HID devices.
Ignore checking the bDeviceClass as we will be checking interface
bInterfaceClass later anyway.
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
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.
Improve logic of report length field handling for empty fields.
Add column headers for data and length fields.
Add documentation statement about length fields.
Increase window size.
Add message boxes when invalid values are entered.
memset() buffers to zero.
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.