Alan Ott 4a229e26c0 Fix hid_enumerate() crash on Mac OS X
Fix the problem where hid_enumerate() will crash if any of the HID devices
attached to the system are opened in exclusive mode (using
kIOHIDOptionsTypeSeizeDevice from IOHIDManagerOpen()). According to reports,
some Logitech devices have software which opens devices in exclusive mode,
causing HIDAPI-based programs to crash on systems where these Logitech
devices (and their accompanying software) are installed.

The fix is simple enough. IOHIDManagerOpen() does not need to be called from
HIDAPI, contrary to the examples in Apple's Technical Note TN2187.  From
examining the IOHIDManager source[1], it appears that "opening" the
IOHIDManager (not the IOHIDDevice) causes IOHIDManager to try to open all
matching devices connected to the system, failing if even one device cannot
be opened.  (Calling IOHIDManagerOpen() does indeed call IOHIDDeviceOpen()
for every matching connected device and for every future matching connected
device as well).  HIDAPI of course tries to match all devices (by passing
NULL to IOHIDManagerSetDeviceMatching()), hence the issue.

Empirical evidence first suggested that IOHIDManagerOpen() did not actually
need to be called, and examination of the source[1] seems to confirm that it
only gets in the way.

Many thanks to Brendan Shanks, Bill Good, Github user darthrake, and Vitali
Lovich for pointing this out and participating in the information gathering,
debugging, and discussion.

[1] http://opensource.apple.com/source/IOKitUser/IOKitUser-502/hid.subproj/IOHIDManager.c

Signed-off-by: Alan Ott <alan@signal11.us>
2012-01-11 16:22:54 -05:00
2010-10-09 12:40:38 -04:00
2012-01-11 16:22:54 -05:00
2011-10-25 20:58:17 -04:00
2011-10-26 17:39:00 -04:00
2010-10-13 10:29:45 -04:00
2010-04-11 17:34:12 -04:00
2011-09-13 11:33:05 +08:00

HID API for Windows, Linux, and Mac OS X

About
------

HIDAPI is a multi-platform library which allows an application to interface
with USB and Bluetooth HID-Class devices on Windows, Linux, and Mac OS X. 
On Windows, a DLL is built.  On other platforms (and optionally on Windows),
the single source file can simply be dropped into a target application.

HIDAPI has four back-ends:
	* Windows (using hid.dll)
	* Linux/hidraw (using the Kernel's hidraw driver)
	* Linux/libusb (using libusb-1.0)
	* Mac (using IOHidManager)

On Linux, either the hidraw or the libusb back-end can be used. There are
tradeoffs, and the functionality supported is slightly different.

Linux/hidraw (linux/hid.c):
This back-end uses the hidraw interface in the Linux kernel.  While this
back-end will support both USB and Bluetooth, it has some limitations on
kernels prior to 2.6.39, including the inability to send or receive feature
reports.  In addition, it will only communicate with devices which have
hidraw nodes associated with them.  Keyboards, mice, and some other devices
which are blacklisted from having hidraw nodes will not work. Fortunately,
for nearly all the uses of hidraw, this is not a problem.

Linux/libusb (linux/hid-libusb.c):
This back-end uses libusb-1.0 to communicate directly to a USB device. This
back-end will of course not work with Bluetooth devices.

What Does the API Look Like?
-----------------------------
The API provides the the most commonly used HID functions including sending
and receiving of input, output, and feature reports.  The sample program,
which communicates with the USB Generic HID sample which is part of the
Microchip Application Library (in folder "Microchip Solutions\USB Device
- HID - Custom Demos\Generic HID - Firmware" when the Microchip Application
Framework is installed), looks like this (with error checking removed for
simplicity):

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "hidapi.h"

#define MAX_STR 255

int main(int argc, char* argv[])
{
	int res;
	unsigned char buf[65];
	wchar_t wstr[MAX_STR];
	hid_device *handle;
	int i;

	// Open the device using the VID, PID,
	// and optionally the Serial number.
	handle = hid_open(0x4d8, 0x3f, NULL);

	// Read the Manufacturer String
	res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
	wprintf(L"Manufacturer String: %s\n", wstr);

	// Read the Product String
	res = hid_get_product_string(handle, wstr, MAX_STR);
	wprintf(L"Product String: %s\n", wstr);

	// Read the Serial Number String
	res = hid_get_serial_number_string(handle, wstr, MAX_STR);
	wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr);

	// Read Indexed String 1
	res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
	wprintf(L"Indexed String 1: %s\n", wstr);

	// Toggle LED (cmd 0x80). The first byte is the report number (0x0).
	buf[0] = 0x0;
	buf[1] = 0x80;
	res = hid_write(handle, buf, 65);

	// Request state (cmd 0x81). The first byte is the report number (0x0).
	buf[0] = 0x0;
	buf[1] = 0x81;
	res = hid_write(handle, buf, 65);

	// Read requested state
	hid_read(handle, buf, 65);

	// Print out the returned buffer.
	for (i = 0; i < 4; i++)
		printf("buf[%d]: %d\n", i, buf[i]);

	return 0;
}

License
--------
HIDAPI may be used by one of three licenses as outlined in LICENSE.txt.

Download
---------
It can be downloaded from github
	git clone git://github.com/signal11/hidapi.git

Build Instructions
-------------------
To build the console test program:
  Windows:
    Build the .sln file in the windows/ directory.
  Linux:
    cd to the linux/ directory and run make.
  Mac OS X:
    cd to the mac/ directory and run make.

To build the Test GUI:
  The test GUI uses Fox toolkit, available from www.fox-toolkit.org.
  On Debian-based systems such as Ubuntu, install Fox using the following:
	sudo apt-get install libfox-1.6-dev
  On Mac OSX, install Fox from ports:
	sudo port install fox
  On Windows, download the hidapi-externals.zip file from the main download
  site and extract it just outside of hidapi, so that hidapi-externals and
  hidapi are on the same level, as shown:

     Parent_Folder
       |
       +hidapi
       +hidapi-externals

  Then to build:
    On Windows, build the .sln file in the testgui/ directory.
    On Linux and Mac, run make from the testgui/ directory.

To build using the DDK (old method):

   1. Install the Windows Driver Kit (WDK) from Microsoft.
   2. From the Start menu, in the Windows Driver Kits folder, select Build
      Environments, then your operating system, then the x86 Free Build
      Environment (or one that is appropriate for your system).
   3. From the console, change directory to the windows/ddk_build/ directory,
      which is part of the HIDAPI distribution.
   4. Type build.
   5. You can find the output files (DLL and LIB) in a subdirectory created
      by the build system which is appropriate for your environment. On
      Windows XP, this directory is objfre_wxp_x86/i386.

--------------------------------

Signal 11 Software - 2010-04-11
                     2010-07-28
                     2011-09-10
S
Description
A Simple library for communicating with USB and Bluetooth HID devices on Linux, Mac, and Windows.
Readme 3.8 MiB
Languages
C 82.4%
CMake 6.1%
M4 5.7%
C++ 3.4%
Makefile 1.1%
Other 1.3%