commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/01: fcd: Update hidapi to latest HEAD.


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/01: fcd: Update hidapi to latest HEAD.
Date: Sat, 24 Sep 2016 17:48:09 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch maint
in repository gnuradio.

commit 67baea5e32de0daef510dfebfa67bf94c0b88f68
Author: Alexandru Csete <address@hidden>
Date:   Fri Sep 23 13:53:25 2016 +0200

    fcd: Update hidapi to latest HEAD.
    
    This contains necessary fixes for Mac OS X.
---
 gr-fcd/lib/hid/hid-libusb.c | 117 +++++++++++--
 gr-fcd/lib/hid/hidapi.h     |  32 ++--
 gr-fcd/lib/hid/hidmac.c     | 406 +++++++++++++++++++++-----------------------
 gr-fcd/lib/hid/hidwin.c     | 355 ++++++++++++++++++++++----------------
 4 files changed, 532 insertions(+), 378 deletions(-)

diff --git a/gr-fcd/lib/hid/hid-libusb.c b/gr-fcd/lib/hid/hid-libusb.c
index 097f872..3c6d877 100644
--- a/gr-fcd/lib/hid/hid-libusb.c
+++ b/gr-fcd/lib/hid/hid-libusb.c
@@ -14,7 +14,7 @@
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
- GNU Public License v3, a BSD-Style license, or the
+ GNU General Public License v3, a BSD-Style license, or the
  original HIDAPI license as outlined in the LICENSE.txt,
  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
  files located at the root of the source distribution.
@@ -44,11 +44,74 @@
 #include <wchar.h>
 
 /* GNU / LibUSB */
-#include "libusb.h"
-#include "iconv.h"
+#include <libusb.h>
+#ifndef __ANDROID__
+#include <iconv.h>
+#endif
 
 #include "hidapi.h"
 
+#ifdef __ANDROID__
+
+/* Barrier implementation because Android/Bionic don't have pthread_barrier.
+   This implementation came from Brent Priddy and was posted on
+   StackOverflow. It is used with his permission. */
+typedef int pthread_barrierattr_t;
+typedef struct pthread_barrier {
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    int count;
+    int trip_count;
+} pthread_barrier_t;
+
+static int pthread_barrier_init(pthread_barrier_t *barrier, const 
pthread_barrierattr_t *attr, unsigned int count)
+{
+       if(count == 0) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
+               return -1;
+       }
+       if(pthread_cond_init(&barrier->cond, 0) < 0) {
+               pthread_mutex_destroy(&barrier->mutex);
+               return -1;
+       }
+       barrier->trip_count = count;
+       barrier->count = 0;
+
+       return 0;
+}
+
+static int pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+       pthread_cond_destroy(&barrier->cond);
+       pthread_mutex_destroy(&barrier->mutex);
+       return 0;
+}
+
+static int pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+       pthread_mutex_lock(&barrier->mutex);
+       ++(barrier->count);
+       if(barrier->count >= barrier->trip_count)
+       {
+               barrier->count = 0;
+               pthread_cond_broadcast(&barrier->cond);
+               pthread_mutex_unlock(&barrier->mutex);
+               return 1;
+       }
+       else
+       {
+               pthread_cond_wait(&barrier->cond, &(barrier->mutex));
+               pthread_mutex_unlock(&barrier->mutex);
+               return 0;
+       }
+}
+
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -250,10 +313,10 @@ static int get_usage(uint8_t *report_descriptor, size_t 
size,
 }
 #endif /* INVASIVE_GET_USAGE */
 
-#ifdef __FreeBSD__
-/* The FreeBSD version of libusb doesn't have this funciton. In mainline
-   libusb, it's inlined in libusb.h. This function will bear a striking
-   resemblence to that one, because there's about one way to code it.
+#if defined(__FreeBSD__) && __FreeBSD__ < 10
+/* The libusb version included in FreeBSD < 10 doesn't have this function. In
+   mainline libusb, it's inlined in libusb.h. This function will bear a 
striking
+   resemblance to that one, because there's about one way to code it.
 
    Note that the data parameter is Unicode in UTF-16LE encoding.
    Return value is the number of bytes in data, or LIBUSB_ERROR_*.
@@ -326,8 +389,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, 
uint8_t idx)
        char buf[512];
        int len;
        wchar_t *str = NULL;
-       wchar_t wbuf[256];
 
+#ifndef __ANDROID__ /* we don't use iconv on Android */
+       wchar_t wbuf[256];
        /* iconv variables */
        iconv_t ic;
        size_t inbytes;
@@ -339,6 +403,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, 
uint8_t idx)
        char *inptr;
 #endif
        char *outptr;
+#endif
 
        /* Determine which language to use. */
        uint16_t lang;
@@ -355,6 +420,25 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, 
uint8_t idx)
        if (len < 0)
                return NULL;
 
+#ifdef __ANDROID__
+
+       /* Bionic does not have iconv support nor wcsdup() function, so it
+          has to be done manually.  The following code will only work for
+          code points that can be represented as a single UTF-16 character,
+          and will incorrectly convert any code points which require more
+          than one UTF-16 character.
+
+          Skip over the first character (2-bytes).  */
+       len -= 2;
+       str = malloc((len / 2 + 1) * sizeof(wchar_t));
+       int i;
+       for (i = 0; i < len / 2; i++) {
+               str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
+       }
+       str[len / 2] = 0x00000000;
+
+#else
+
        /* buf does not need to be explicitly NULL-terminated because
           it is only passed into iconv() which does not need it. */
 
@@ -388,6 +472,8 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, 
uint8_t idx)
 err:
        iconv_close(ic);
 
+#endif
+
        return str;
 }
 
@@ -607,7 +693,7 @@ void  HID_API_EXPORT hid_free_enumeration(struct 
hid_device_info *devs)
        }
 }
 
-hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, 
wchar_t *serial_number)
+hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, 
const wchar_t *serial_number)
 {
        struct hid_device_info *devs, *cur_dev;
        const char *path_to_open = NULL;
@@ -619,7 +705,8 @@ hid_device * hid_open(unsigned short vendor_id, unsigned 
short product_id, wchar
                if (cur_dev->vendor_id == vendor_id &&
                    cur_dev->product_id == product_id) {
                        if (serial_number) {
-                               if (wcscmp(serial_number, 
cur_dev->serial_number) == 0) {
+                               if (cur_dev->serial_number &&
+                                   wcscmp(serial_number, 
cur_dev->serial_number) == 0) {
                                        path_to_open = cur_dev->path;
                                        break;
                                }
@@ -762,7 +849,7 @@ static void *read_thread(void *param)
        /* Now that the read thread is stopping, Wake any threads which are
           waiting on data (in hid_read_timeout()). Do this under a mutex to
           make sure that a thread which is about to go to sleep waiting on
-          the condition acutally will go to sleep before the condition is
+          the condition actually will go to sleep before the condition is
           signaled. */
        pthread_mutex_lock(&dev->mutex);
        pthread_cond_broadcast(&dev->condition);
@@ -790,11 +877,11 @@ hid_device * HID_API_EXPORT hid_open_path(const char 
*path)
        int d = 0;
        int good_open = 0;
 
-       dev = new_hid_device();
-
        if(hid_init() < 0)
                return NULL;
 
+       dev = new_hid_device();
+
        libusb_get_device_list(usb_context, &devs);
        while ((usb_dev = devs[d++]) != NULL) {
                struct libusb_device_descriptor desc;
@@ -871,7 +958,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
                                                                
(ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
                                                              == 
LIBUSB_ENDPOINT_IN;
 
-                                                       /* Decide whether to 
use it for intput or output. */
+                                                       /* Decide whether to 
use it for input or output. */
                                                        if (dev->input_endpoint 
== 0 &&
                                                            is_interrupt && 
is_input) {
                                                                /* Use this 
endpoint for INPUT */
@@ -927,7 +1014,7 @@ int HID_API_EXPORT hid_write(hid_device *dev, const 
unsigned char *data, size_t
 
 
        if (dev->output_endpoint <= 0) {
-               /* No interrput out endpoint. Use the Control Endpoint */
+               /* No interrupt out endpoint. Use the Control Endpoint */
                res = libusb_control_transfer(dev->device_handle,
                        
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
                        0x09/*HID Set_Report*/,
diff --git a/gr-fcd/lib/hid/hidapi.h b/gr-fcd/lib/hid/hidapi.h
index 8e55c84..e5bc2dc 100644
--- a/gr-fcd/lib/hid/hidapi.h
+++ b/gr-fcd/lib/hid/hidapi.h
@@ -11,7 +11,7 @@
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
- GNU Public License v3, a BSD-Style license, or the
+ GNU General Public License v3, a BSD-Style license, or the
  original HIDAPI license as outlined in the LICENSE.txt,
  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
  files located at the root of the source distribution.
@@ -87,7 +87,7 @@ extern "C" {
                        needed.  This function should be called at the 
beginning of
                        execution however, if there is a chance of HIDAPI 
handles
                        being opened by different threads simultaneously.
-
+                       
                        @ingroup API
 
                        @returns
@@ -112,6 +112,8 @@ extern "C" {
 
                        This function returns a linked list of all the HID 
devices
                        attached to the system which match vendor_id and 
product_id.
+                       If @p vendor_id is set to 0 then any vendor matches.
+                       If @p product_id is set to 0 then any product matches.
                        If @p vendor_id and @p product_id are both set to 0, 
then
                        all HID devices will be returned.
 
@@ -155,7 +157,7 @@ extern "C" {
                                This function returns a pointer to a 
#hid_device object on
                                success or NULL on failure.
                */
-               HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned 
short vendor_id, unsigned short product_id, wchar_t *serial_number);
+               HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned 
short vendor_id, unsigned short product_id, const wchar_t *serial_number);
 
                /** @brief Open a HID device by its path name.
 
@@ -207,7 +209,7 @@ extern "C" {
                        contain the Report number if the device uses numbered 
reports.
 
                        @ingroup API
-                       @param dev A device handle returned from hid_open().
+                       @param device A device handle returned from hid_open().
                        @param data A buffer to put the read data into.
                        @param length The number of bytes to read. For devices 
with
                                multiple reports, make sure to read an extra 
byte for
@@ -216,7 +218,8 @@ extern "C" {
 
                        @returns
                                This function returns the actual number of 
bytes read and
-                               -1 on error.
+                               -1 on error. If no packet was available to be 
read within
+                               the timeout period, this function returns 0.
                */
                int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device 
*dev, unsigned char *data, size_t length, int milliseconds);
 
@@ -235,7 +238,8 @@ extern "C" {
 
                        @returns
                                This function returns the actual number of 
bytes read and
-                               -1 on error.
+                               -1 on error. If no packet was available to be 
read and
+                               the handle is in non-blocking mode, this 
function returns 0.
                */
                int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, 
unsigned char *data, size_t length);
 
@@ -289,22 +293,26 @@ extern "C" {
 
                /** @brief Get a feature report from a HID device.
 
-                       Make sure to set the first byte of @p data[] to the 
Report
-                       ID of the report to be read.  Make sure to allow space 
for
-                       this extra byte in @p data[].
+                       Set the first byte of @p data[] to the Report ID of the
+                       report to be read.  Make sure to allow space for this
+                       extra byte in @p data[]. Upon return, the first byte 
will
+                       still contain the Report ID, and the report data will
+                       start in data[1].
 
                        @ingroup API
                        @param device A device handle returned from hid_open().
                        @param data A buffer to put the read data into, 
including
                                the Report ID. Set the first byte of @p data[] 
to the
-                               Report ID of the report to be read.
+                               Report ID of the report to be read, or set it 
to zero
+                               if your device does not use numbered reports.
                        @param length The number of bytes to read, including an
                                extra byte for the report ID. The buffer can be 
longer
                                than the actual report.
 
                        @returns
-                               This function returns the number of bytes read 
and
-                               -1 on error.
+                               This function returns the number of bytes read 
plus
+                               one for the report ID (which is still in the 
first
+                               byte), or -1 on error.
                */
                int HID_API_EXPORT HID_API_CALL 
hid_get_feature_report(hid_device *device, unsigned char *data, size_t length);
 
diff --git a/gr-fcd/lib/hid/hidmac.c b/gr-fcd/lib/hid/hidmac.c
index d8c69a8..e0756a1 100644
--- a/gr-fcd/lib/hid/hidmac.c
+++ b/gr-fcd/lib/hid/hidmac.c
@@ -11,7 +11,7 @@
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
- GNU Public License v3, a BSD-Style license, or the
+ GNU General Public License v3, a BSD-Style license, or the
  original HIDAPI license as outlined in the LICENSE.txt,
  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
  files located at the root of the source distribution.
@@ -24,12 +24,14 @@
 
 #include <IOKit/hid/IOHIDManager.h>
 #include <IOKit/hid/IOHIDKeys.h>
+#include <IOKit/IOKitLib.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <wchar.h>
 #include <locale.h>
 #include <pthread.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <dlfcn.h>
 
 #include "hidapi.h"
 
@@ -118,16 +120,8 @@ struct hid_device_ {
        pthread_barrier_t barrier; /* Ensures correct startup sequence */
        pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown 
sequence */
        int shutdown_thread;
-
-       hid_device *next;
 };
 
-/* Static list of all the devices open. This way when a device gets
-   disconnected, its hid_device structure can be marked as disconnected
-   from hid_device_removal_callback(). */
-static hid_device *device_list = NULL;
-static pthread_mutex_t device_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-
 static hid_device *new_hid_device(void)
 {
        hid_device *dev = calloc(1, sizeof(hid_device));
@@ -141,7 +135,6 @@ static hid_device *new_hid_device(void)
        dev->input_report_buf = NULL;
        dev->input_reports = NULL;
        dev->shutdown_thread = 0;
-       dev->next = NULL;
 
        /* Thread objects */
        pthread_mutex_init(&dev->mutex, NULL);
@@ -149,22 +142,6 @@ static hid_device *new_hid_device(void)
        pthread_barrier_init(&dev->barrier, NULL, 2);
        pthread_barrier_init(&dev->shutdown_barrier, NULL, 2);
 
-       /* Add the new record to the device_list. */
-       pthread_mutex_lock(&device_list_mutex);
-       if (!device_list)
-               device_list = dev;
-       else {
-               hid_device *d = device_list;
-               while (d) {
-                       if (!d->next) {
-                               d->next = dev;
-                               break;
-                       }
-                       d = d->next;
-               }
-       }
-       pthread_mutex_unlock(&device_list_mutex);
-
        return dev;
 }
 
@@ -197,29 +174,11 @@ static void free_hid_device(hid_device *dev)
        pthread_cond_destroy(&dev->condition);
        pthread_mutex_destroy(&dev->mutex);
 
-       /* Remove it from the device list. */
-       pthread_mutex_lock(&device_list_mutex);
-       hid_device *d = device_list;
-       if (d == dev) {
-               device_list = d->next;
-       }
-       else {
-               while (d) {
-                       if (d->next == dev) {
-                               d->next = d->next->next;
-                               break;
-                       }
-
-                       d = d->next;
-               }
-       }
-       pthread_mutex_unlock(&device_list_mutex);
-
        /* Free the structure itself. */
        free(dev);
 }
 
-static         IOHIDManagerRef hid_mgr = 0x0;
+static IOHIDManagerRef hid_mgr = 0x0;
 
 
 #if 0
@@ -255,7 +214,6 @@ static unsigned short get_product_id(IOHIDDeviceRef device)
        return get_int_property(device, CFSTR(kIOHIDProductIDKey));
 }
 
-
 static int32_t get_max_report_length(IOHIDDeviceRef device)
 {
        return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey));
@@ -263,59 +221,46 @@ static int32_t get_max_report_length(IOHIDDeviceRef 
device)
 
 static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, 
wchar_t *buf, size_t len)
 {
-       CFStringRef str = IOHIDDeviceGetProperty(device, prop);
+       CFStringRef str;
 
-       buf[0] = 0x0000;
-
-       if (str) {
-               CFRange range;
-               range.location = 0;
-               range.length = len;
-               CFIndex used_buf_len;
-               CFStringGetBytes(str,
-                       range,
-                       kCFStringEncodingUTF32LE,
-                       (char)'?',
-                       FALSE,
-                       (UInt8*)buf,
-                       len,
-                       &used_buf_len);
-               buf[len-1] = 0x00000000;
-               return used_buf_len;
-       }
-       else
+       if (!len)
                return 0;
 
-}
-
-static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, 
char *buf, size_t len)
-{
-       CFStringRef str = IOHIDDeviceGetProperty(device, prop);
+       str = IOHIDDeviceGetProperty(device, prop);
 
-       buf[0] = 0x0000;
+       buf[0] = 0;
 
        if (str) {
+               CFIndex str_len = CFStringGetLength(str);
                CFRange range;
-               range.location = 0;
-               range.length = len;
                CFIndex used_buf_len;
-               CFStringGetBytes(str,
+               CFIndex chars_copied;
+
+               len --;
+
+               range.location = 0;
+               range.length = ((size_t)str_len > len)? len: (size_t)str_len;
+               chars_copied = CFStringGetBytes(str,
                        range,
-                       kCFStringEncodingUTF8,
+                       kCFStringEncodingUTF32LE,
                        (char)'?',
                        FALSE,
                        (UInt8*)buf,
-                       len,
+                       len * sizeof(wchar_t),
                        &used_buf_len);
-               buf[len-1] = 0x00000000;
-               return used_buf_len;
+
+               if (chars_copied == len)
+                       buf[len] = 0; /* len is decremented above */
+               else
+                       buf[chars_copied] = 0;
+
+               return 0;
        }
        else
-               return 0;
+               return -1;
 
 }
 
-
 static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
 {
        return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, 
len);
@@ -342,53 +287,87 @@ static wchar_t *dup_wcs(const wchar_t *s)
        return ret;
 }
 
-
-static int make_path(IOHIDDeviceRef device, char *buf, size_t len)
+/* hidapi_IOHIDDeviceGetService()
+ *
+ * Return the io_service_t corresponding to a given IOHIDDeviceRef, either by:
+ * - on OS X 10.6 and above, calling IOHIDDeviceGetService()
+ * - on OS X 10.5, extract it from the IOHIDDevice struct
+ */
+static io_service_t hidapi_IOHIDDeviceGetService(IOHIDDeviceRef device)
 {
-       int res;
-       unsigned short vid, pid;
-       char transport[32];
-
-       buf[0] = '\0';
-
-       res = get_string_property_utf8(
-               device, CFSTR(kIOHIDTransportKey),
-               transport, sizeof(transport));
-
-       if (!res)
-               return -1;
-
-       vid = get_vendor_id(device);
-       pid = get_product_id(device);
-
-       res = snprintf(buf, len, "%s_%04hx_%04hx_%p",
-                          transport, vid, pid, device);
+       static void *iokit_framework = NULL;
+       static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef 
device) = NULL;
+
+       /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if 
it exists.
+        * If any of these steps fail, dynamic_IOHIDDeviceGetService will be 
left NULL
+        * and the fallback method will be used.
+        */
+       if (iokit_framework == NULL) {
+               iokit_framework = 
dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY);
+
+               if (iokit_framework != NULL)
+                       dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, 
"IOHIDDeviceGetService");
+       }
 
+       if (dynamic_IOHIDDeviceGetService != NULL) {
+               /* Running on OS X 10.6 and above: IOHIDDeviceGetService() 
exists */
+               return dynamic_IOHIDDeviceGetService(device);
+       }
+       else
+       {
+               /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist.
+                *
+                * Be naughty and pull the service out of the IOHIDDevice.
+                * IOHIDDevice is an opaque struct not exposed to applications, 
but its
+                * layout is stable through all available versions of OS X.
+                * Tested and working on OS X 10.5.8 i386, x86_64, and ppc.
+                */
+               struct IOHIDDevice_internal {
+                       /* The first field of the IOHIDDevice struct is a
+                        * CFRuntimeBase (which is a private CF struct).
+                        *
+                        * a, b, and c are the 3 fields that make up a 
CFRuntimeBase.
+                        * See 
http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h
+                        *
+                        * The second field of the IOHIDDevice is the 
io_service_t we're looking for.
+                        */
+                       uintptr_t a;
+                       uint8_t b[4];
+#if __LP64__
+                       uint32_t c;
+#endif
+                       io_service_t service;
+               };
+               struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal 
*)device;
 
-       buf[len-1] = '\0';
-       return res+1;
+               return tmp->service;
+       }
 }
 
+/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */
 static int init_hid_manager(void)
 {
-       IOReturn res;
-
        /* Initialize all the HID Manager Objects */
        hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, 
kIOHIDOptionsTypeNone);
-       IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
-       IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), 
kCFRunLoopDefaultMode);
-       res = IOHIDManagerOpen(hid_mgr, kIOHIDOptionsTypeNone);
-       return (res == kIOReturnSuccess)? 0: -1;
+       if (hid_mgr) {
+               IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
+               IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), 
kCFRunLoopDefaultMode);
+               return 0;
+       }
+
+       return -1;
 }
 
+/* Initialize the IOHIDManager if necessary. This is the public function, and
+   it is safe to call this function repeatedly. Return 0 for success and -1
+   for failure. */
 int HID_API_EXPORT hid_init(void)
 {
        if (!hid_mgr) {
-               if (init_hid_manager() < 0) {
-                       hid_exit();
-                       return -1;
-               }
+               return init_hid_manager();
        }
+
+       /* Already initialized. */
        return 0;
 }
 
@@ -404,19 +383,29 @@ int HID_API_EXPORT hid_exit(void)
        return 0;
 }
 
+static void process_pending_events(void) {
+       SInt32 res;
+       do {
+               res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE);
+       } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut);
+}
+
 struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short 
vendor_id, unsigned short product_id)
 {
-       struct hid_device_info *root = NULL; // return object
+       struct hid_device_info *root = NULL; /* return object */
        struct hid_device_info *cur_dev = NULL;
        CFIndex num_devices;
        int i;
 
-       setlocale(LC_ALL,"");
-
        /* Set up the HID Manager if it hasn't been done */
-       hid_init();
+       if (hid_init() < 0)
+               return NULL;
+
+       /* give the IOHIDManager a chance to update itself */
+       process_pending_events();
 
        /* Get a list of the Devices */
+       IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
        CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
 
        /* Convert the list into a C array so we can iterate easily. */
@@ -430,7 +419,6 @@ struct hid_device_info  HID_API_EXPORT 
*hid_enumerate(unsigned short vendor_id,
                unsigned short dev_pid;
                #define BUF_LEN 256
                wchar_t buf[BUF_LEN];
-               char cbuf[BUF_LEN];
 
                IOHIDDeviceRef dev = device_array[i];
 
@@ -441,12 +429,14 @@ struct hid_device_info  HID_API_EXPORT 
*hid_enumerate(unsigned short vendor_id,
                dev_pid = get_product_id(dev);
 
                /* Check the VID/PID against the arguments */
-               if ((vendor_id == 0x0 && product_id == 0x0) ||
-                   (vendor_id == dev_vid && product_id == dev_pid)) {
+               if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
+                   (product_id == 0x0 || product_id == dev_pid)) {
                        struct hid_device_info *tmp;
-                       size_t len;
+                       io_object_t iokit_dev;
+                       kern_return_t res;
+                       io_string_t path;
 
-                       /* VID/PID match. Create the record. */
+                       /* VID/PID match. Create the record. */
                        tmp = malloc(sizeof(struct hid_device_info));
                        if (cur_dev) {
                                cur_dev->next = tmp;
@@ -456,14 +446,20 @@ struct hid_device_info  HID_API_EXPORT 
*hid_enumerate(unsigned short vendor_id,
                        }
                        cur_dev = tmp;
 
-                       // Get the Usage Page and Usage for this device.
+                       /* Get the Usage Page and Usage for this device. */
                        cur_dev->usage_page = get_int_property(dev, 
CFSTR(kIOHIDPrimaryUsagePageKey));
                        cur_dev->usage = get_int_property(dev, 
CFSTR(kIOHIDPrimaryUsageKey));
 
                        /* Fill out the record */
                        cur_dev->next = NULL;
-                       len = make_path(dev, cbuf, sizeof(cbuf));
-                       cur_dev->path = strdup(cbuf);
+
+                       /* Fill in the path (IOService plane) */
+                       iokit_dev = hidapi_IOHIDDeviceGetService(dev);
+                       res = IORegistryEntryGetPath(iokit_dev, 
kIOServicePlane, path);
+                       if (res == KERN_SUCCESS)
+                               cur_dev->path = strdup(path);
+                       else
+                               cur_dev->path = strdup("");
 
                        /* Serial Number */
                        get_serial_number(dev, buf, BUF_LEN);
@@ -508,7 +504,7 @@ void  HID_API_EXPORT hid_free_enumeration(struct 
hid_device_info *devs)
        }
 }
 
-hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short 
product_id, wchar_t *serial_number)
+hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short 
product_id, const wchar_t *serial_number)
 {
        /* This function is identical to the Linux version. Platform 
independent. */
        struct hid_device_info *devs, *cur_dev;
@@ -545,20 +541,13 @@ hid_device * HID_API_EXPORT hid_open(unsigned short 
vendor_id, unsigned short pr
 }
 
 static void hid_device_removal_callback(void *context, IOReturn result,
-                                        void *sender, IOHIDDeviceRef dev_ref)
+                                        void *sender)
 {
        /* Stop the Run Loop for this device. */
-       pthread_mutex_lock(&device_list_mutex);
-       hid_device *d = device_list;
-       while (d) {
-               if (d->device_handle == dev_ref) {
-                       d->disconnected = 1;
-                       CFRunLoopStop(d->run_loop);
-               }
+       hid_device *d = context;
 
-               d = d->next;
-       }
-       pthread_mutex_unlock(&device_list_mutex);
+       d->disconnected = 1;
+       CFRunLoopStop(d->run_loop);
 }
 
 /* The Run Loop calls this function for each input report received.
@@ -612,17 +601,18 @@ static void hid_report_callback(void *context, IOReturn 
result, void *sender,
 
 }
 
-/* This gets called when the read_thred's run loop gets signaled by
+/* This gets called when the read_thread's run loop gets signaled by
    hid_close(), and serves to stop the read_thread's run loop. */
 static void perform_signal_callback(void *context)
 {
        hid_device *dev = context;
-       CFRunLoopStop(dev->run_loop); //TODO: CFRunLoopGetCurrent()
+       CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/
 }
 
 static void *read_thread(void *param)
 {
        hid_device *dev = param;
+       SInt32 code;
 
        /* Move the device's run loop to this thread. */
        IOHIDDeviceScheduleWithRunLoop(dev->device_handle, 
CFRunLoopGetCurrent(), dev->run_loop_mode);
@@ -646,7 +636,6 @@ static void *read_thread(void *param)
 
        /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
           reports into the hid_report_callback(). */
-       SInt32 code;
        while (!dev->shutdown_thread && !dev->disconnected) {
                code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, 
FALSE);
                /* Return if the device has been disconnected */
@@ -670,19 +659,12 @@ static void *read_thread(void *param)
        /* Now that the read thread is stopping, Wake any threads which are
           waiting on data (in hid_read_timeout()). Do this under a mutex to
           make sure that a thread which is about to go to sleep waiting on
-          the condition acutally will go to sleep before the condition is
+          the condition actually will go to sleep before the condition is
           signaled. */
        pthread_mutex_lock(&dev->mutex);
        pthread_cond_broadcast(&dev->condition);
        pthread_mutex_unlock(&dev->mutex);
 
-       /* Close the OS handle to the device, but only if it's not
-          been unplugged. If it's been unplugged, then calling
-          IOHIDDeviceClose() will crash. */
-       if (!dev->disconnected) {
-               IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
-       }
-
        /* Wait here until hid_close() is called and makes it past
           the call to CFRunLoopWakeUp(). This thread still needs to
           be valid when that function is called on the other thread. */
@@ -691,71 +673,77 @@ static void *read_thread(void *param)
        return NULL;
 }
 
+/* hid_open_path()
+ *
+ * path must be a valid path to an IOHIDDevice in the IOService plane
+ * Example: 
"IOService:/AppleACPIPlatformExpert/address@hidden/AppleACPIPCI/address@hidden,7/AppleUSBEHCI/PLAYSTATION(R)3
 address@hidden/address@hidden/IOUSBHIDDriver"
+ */
 hid_device * HID_API_EXPORT hid_open_path(const char *path)
 {
-       int i;
        hid_device *dev = NULL;
-       CFIndex num_devices;
+       io_registry_entry_t entry = MACH_PORT_NULL;
 
        dev = new_hid_device();
 
        /* Set up the HID Manager if it hasn't been done */
-       hid_init();
+       if (hid_init() < 0)
+               return NULL;
+
+       /* Get the IORegistry entry for the given path */
+       entry = IORegistryEntryFromPath(kIOMasterPortDefault, path);
+       if (entry == MACH_PORT_NULL) {
+               /* Path wasn't valid (maybe device was removed?) */
+               goto return_error;
+       }
 
-       CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
+       /* Create an IOHIDDevice for the entry */
+       dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry);
+       if (dev->device_handle == NULL) {
+               /* Error creating the HID device */
+               goto return_error;
+       }
 
-       num_devices = CFSetGetCount(device_set);
-       IOHIDDeviceRef *device_array = calloc(num_devices, 
sizeof(IOHIDDeviceRef));
-       CFSetGetValues(device_set, (const void **) device_array);
-       for (i = 0; i < num_devices; i++) {
-               char cbuf[BUF_LEN];
-               size_t len;
-               IOHIDDeviceRef os_dev = device_array[i];
-
-               len = make_path(os_dev, cbuf, sizeof(cbuf));
-               if (!strcmp(cbuf, path)) {
-                       // Matched Paths. Open this Device.
-                       IOReturn ret = IOHIDDeviceOpen(os_dev, 
kIOHIDOptionsTypeNone);
-                       if (ret == kIOReturnSuccess) {
-                               char str[32];
-
-                               free(device_array);
-                               CFRelease(device_set);
-                               dev->device_handle = os_dev;
-
-                               /* Create the buffers for receiving data */
-                               dev->max_input_report_len = (CFIndex) 
get_max_report_length(os_dev);
-                               dev->input_report_buf = 
calloc(dev->max_input_report_len, sizeof(uint8_t));
-
-                               /* Create the Run Loop Mode for this device.
-                                  printing the reference seems to work. */
-                               sprintf(str, "HIDAPI_%p", os_dev);
-                               dev->run_loop_mode =
-                                       CFStringCreateWithCString(NULL, str, 
kCFStringEncodingASCII);
-
-                               /* Attach the device to a Run Loop */
-                               IOHIDDeviceRegisterInputReportCallback(
-                                       os_dev, dev->input_report_buf, 
dev->max_input_report_len,
-                                       &hid_report_callback, dev);
-                               
IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, 
NULL);
-
-                               /* Start the read thread */
-                               pthread_create(&dev->thread, NULL, read_thread, 
dev);
-
-                               /* Wait here for the read thread to be 
initialized. */
-                               pthread_barrier_wait(&dev->barrier);
-
-                               return dev;
-                       }
-                       else {
-                               goto return_error;
-                       }
-               }
+       /* Open the IOHIDDevice */
+       IOReturn ret = IOHIDDeviceOpen(dev->device_handle, 
kIOHIDOptionsTypeSeizeDevice);
+       if (ret == kIOReturnSuccess) {
+               char str[32];
+
+               /* Create the buffers for receiving data */
+               dev->max_input_report_len = (CFIndex) 
get_max_report_length(dev->device_handle);
+               dev->input_report_buf = calloc(dev->max_input_report_len, 
sizeof(uint8_t));
+
+               /* Create the Run Loop Mode for this device.
+                  printing the reference seems to work. */
+               sprintf(str, "HIDAPI_%p", dev->device_handle);
+               dev->run_loop_mode =
+                       CFStringCreateWithCString(NULL, str, 
kCFStringEncodingASCII);
+
+               /* Attach the device to a Run Loop */
+               IOHIDDeviceRegisterInputReportCallback(
+                       dev->device_handle, dev->input_report_buf, 
dev->max_input_report_len,
+                       &hid_report_callback, dev);
+               IOHIDDeviceRegisterRemovalCallback(dev->device_handle, 
hid_device_removal_callback, dev);
+
+               /* Start the read thread */
+               pthread_create(&dev->thread, NULL, read_thread, dev);
+
+               /* Wait here for the read thread to be initialized. */
+               pthread_barrier_wait(&dev->barrier);
+
+               IOObjectRelease(entry);
+               return dev;
+       }
+       else {
+               goto return_error;
        }
 
 return_error:
-       free(device_array);
-       CFRelease(device_set);
+       if (dev->device_handle != NULL)
+               CFRelease(dev->device_handle);
+
+       if (entry != MACH_PORT_NULL)
+               IOObjectRelease(entry);
+
        free_hid_device(dev);
        return NULL;
 }
@@ -767,8 +755,8 @@ static int set_report(hid_device *dev, IOHIDReportType 
type, const unsigned char
        IOReturn res;
 
        /* Return if the device has been disconnected. */
-       if (dev->disconnected)
-               return -1;
+       if (dev->disconnected)
+               return -1;
 
        if (data[0] == 0x0) {
                /* Not using numbered Reports.
@@ -981,7 +969,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
                IOHIDDeviceRegisterInputReportCallback(
                        dev->device_handle, dev->input_report_buf, 
dev->max_input_report_len,
                        NULL, dev);
-               IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, NULL, dev);
+               IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, 
dev);
                IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, 
dev->run_loop, dev->run_loop_mode);
                IOHIDDeviceScheduleWithRunLoop(dev->device_handle, 
CFRunLoopGetMain(), kCFRunLoopDefaultMode);
        }
@@ -1003,7 +991,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
           been unplugged. If it's been unplugged, then calling
           IOHIDDeviceClose() will crash. */
        if (!dev->disconnected) {
-               IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
+               IOHIDDeviceClose(dev->device_handle, 
kIOHIDOptionsTypeSeizeDevice);
        }
 
        /* Clear out the queue of received reports. */
@@ -1012,6 +1000,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
                return_data(dev, NULL, 0);
        }
        pthread_mutex_unlock(&dev->mutex);
+       CFRelease(dev->device_handle);
 
        free_hid_device(dev);
 }
@@ -1033,7 +1022,7 @@ int HID_API_EXPORT_CALL 
hid_get_serial_number_string(hid_device *dev, wchar_t *s
 
 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int 
string_index, wchar_t *string, size_t maxlen)
 {
-       // TODO:
+       /* TODO: */
 
        return 0;
 }
@@ -1041,7 +1030,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device 
*dev, int string_index
 
 HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
 {
-       // TODO:
+       /* TODO: */
 
        return NULL;
 }
@@ -1051,6 +1040,7 @@ HID_API_EXPORT const wchar_t * HID_API_CALL  
hid_error(hid_device *dev)
 
 
 
+
 #if 0
 static int32_t get_location_id(IOHIDDeviceRef device)
 {
@@ -1096,8 +1086,6 @@ int main(void)
        IOHIDDeviceRef *device_array = calloc(num_devices, 
sizeof(IOHIDDeviceRef));
        CFSetGetValues(device_set, (const void **) device_array);
 
-       setlocale(LC_ALL, "");
-
        for (i = 0; i < num_devices; i++) {
                IOHIDDeviceRef dev = device_array[i];
                printf("Device: %p\n", dev);
diff --git a/gr-fcd/lib/hid/hidwin.c b/gr-fcd/lib/hid/hidwin.c
index 5d34aad..86810d7 100644
--- a/gr-fcd/lib/hid/hidwin.c
+++ b/gr-fcd/lib/hid/hidwin.c
@@ -8,10 +8,10 @@
  8/22/2009
 
  Copyright 2009, All Rights Reserved.
-
+ 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
- GNU Public License v3, a BSD-Style license, or the
+ GNU General Public License v3, a BSD-Style license, or the
  original HIDAPI license as outlined in the LICENSE.txt,
  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
  files located at the root of the source distribution.
@@ -36,7 +36,11 @@ typedef LONG NTSTATUS;
 #define _wcsdup wcsdup
 #endif
 
-//#define HIDAPI_USE_DDK
+/* The maximum number of characters that can be passed into the
+   HidD_Get*String() functions without it failing.*/
+#define MAX_STRING_WCHARS 0xFFF
+
+/*#define HIDAPI_USE_DDK*/
 
 #ifdef __cplusplus
 extern "C" {
@@ -47,13 +51,13 @@ extern "C" {
                #include <hidsdi.h>
        #endif
 
-       // Copied from inc/ddk/hidclass.h, part of the Windows DDK.
+       /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
        #define HID_OUT_CTL_CODE(id)  \
                CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, 
FILE_ANY_ACCESS)
        #define IOCTL_HID_GET_FEATURE                   HID_OUT_CTL_CODE(100)
 
 #ifdef __cplusplus
-} // extern "C"
+} /* extern "C" */
 #endif
 
 #include <stdio.h>
@@ -62,8 +66,11 @@ extern "C" {
 
 #include "hidapi.h"
 
+#undef MIN
+#define MIN(x,y) ((x) < (y)? (x): (y))
+
 #ifdef _MSC_VER
-       // Thanks Microsoft, but I know how to use strncpy().
+       /* Thanks Microsoft, but I know how to use strncpy(). */
        #pragma warning(disable:4996)
 #endif
 
@@ -72,10 +79,10 @@ extern "C" {
 #endif
 
 #ifndef HIDAPI_USE_DDK
-       // Since we're not building with the DDK, and the HID header
-       // files aren't part of the SDK, we have to define all this
-       // stuff here. In lookup_functions(), the function pointers
-       // defined below are set.
+       /* Since we're not building with the DDK, and the HID header
+          files aren't part of the SDK, we have to define all this
+          stuff here. In lookup_functions(), the function pointers
+          defined below are set. */
        typedef struct _HIDD_ATTRIBUTES{
                ULONG Size;
                USHORT VendorID;
@@ -93,8 +100,8 @@ extern "C" {
                USHORT Reserved[17];
                USHORT fields_not_used_by_hidapi[10];
        } HIDP_CAPS, *PHIDP_CAPS;
-       typedef char* HIDP_PREPARSED_DATA;
-       #define HIDP_STATUS_SUCCESS 0x0
+       typedef void* PHIDP_PREPARSED_DATA;
+       #define HIDP_STATUS_SUCCESS 0x110000
 
        typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, 
PHIDD_ATTRIBUTES attrib);
        typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, 
PVOID buffer, ULONG buffer_len);
@@ -103,9 +110,10 @@ extern "C" {
        typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID 
data, ULONG length);
        typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID 
data, ULONG length);
        typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, 
ULONG string_index, PVOID buffer, ULONG buffer_len);
-       typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, 
HIDP_PREPARSED_DATA **preparsed_data);
-       typedef BOOLEAN (__stdcall 
*HidD_FreePreparsedData_)(HIDP_PREPARSED_DATA *preparsed_data);
-       typedef BOOLEAN (__stdcall *HidP_GetCaps_)(HIDP_PREPARSED_DATA 
*preparsed_data, HIDP_CAPS *caps);
+       typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, 
PHIDP_PREPARSED_DATA *preparsed_data);
+       typedef BOOLEAN (__stdcall 
*HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
+       typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA 
preparsed_data, HIDP_CAPS *caps);
+       typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, 
ULONG number_buffers);
 
        static HidD_GetAttributes_ HidD_GetAttributes;
        static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
@@ -117,14 +125,16 @@ extern "C" {
        static HidD_GetPreparsedData_ HidD_GetPreparsedData;
        static HidD_FreePreparsedData_ HidD_FreePreparsedData;
        static HidP_GetCaps_ HidP_GetCaps;
+       static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
 
        static HMODULE lib_handle = NULL;
        static BOOLEAN initialized = FALSE;
-#endif // HIDAPI_USE_DDK
+#endif /* HIDAPI_USE_DDK */
 
 struct hid_device_ {
                HANDLE device_handle;
                BOOL blocking;
+               USHORT output_report_length;
                size_t input_report_length;
                void *last_error_str;
                DWORD last_error_num;
@@ -138,17 +148,26 @@ static hid_device *new_hid_device()
        hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
        dev->device_handle = INVALID_HANDLE_VALUE;
        dev->blocking = TRUE;
+       dev->output_report_length = 0;
        dev->input_report_length = 0;
        dev->last_error_str = NULL;
        dev->last_error_num = 0;
        dev->read_pending = FALSE;
        dev->read_buf = NULL;
        memset(&dev->ol, 0, sizeof(dev->ol));
-       dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state 
f=nonsignaled*/, NULL);
+       dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state 
f=nonsignaled*/, NULL);
 
        return dev;
 }
 
+static void free_hid_device(hid_device *dev)
+{
+       CloseHandle(dev->ol.hEvent);
+       CloseHandle(dev->device_handle);
+       LocalFree(dev->last_error_str);
+       free(dev->read_buf);
+       free(dev);
+}
 
 static void register_error(hid_device *device, const char *op)
 {
@@ -160,11 +179,11 @@ static void register_error(hid_device *device, const char 
*op)
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-               (LPWSTR)&msg, 0/*sz*/,
+               (LPVOID)&msg, 0/*sz*/,
                NULL);
-
-       // Get rid of the CR and LF that FormatMessage() sticks at the
-       // end of the message. Thanks Microsoft!
+       
+       /* Get rid of the CR and LF that FormatMessage() sticks at the
+          end of the message. Thanks Microsoft! */
        ptr = msg;
        while (*ptr) {
                if (*ptr == '\r') {
@@ -174,8 +193,8 @@ static void register_error(hid_device *device, const char 
*op)
                ptr++;
        }
 
-       // Store the message off in the Device entry so that
-       // the hid_error() function can pick it up.
+       /* Store the message off in the Device entry so that
+          the hid_error() function can pick it up. */
        LocalFree(device->last_error_str);
        device->last_error_str = msg;
 }
@@ -196,6 +215,7 @@ static int lookup_functions()
                RESOLVE(HidD_GetPreparsedData);
                RESOLVE(HidD_FreePreparsedData);
                RESOLVE(HidP_GetCaps);
+               RESOLVE(HidD_SetNumInputBuffers);
 #undef RESOLVE
        }
        else
@@ -205,34 +225,20 @@ static int lookup_functions()
 }
 #endif
 
-static HANDLE open_device(const char *path)
+static HANDLE open_device(const char *path, BOOL enumerate)
 {
        HANDLE handle;
+       DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ);
+       DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
 
-       /* First, try to open with sharing mode turned off. This will make it so
-          that a HID device can only be opened once. This is to be consistent
-          with the behavior on the other platforms. */
        handle = CreateFileA(path,
-               GENERIC_WRITE |GENERIC_READ,
-               0, /*share mode*/
+               desired_access,
+               share_mode,
                NULL,
                OPEN_EXISTING,
-               FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
+               FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
                0);
 
-       if (handle == INVALID_HANDLE_VALUE) {
-               /* Couldn't open the device. Some devices must be opened
-                  with sharing enabled (even though they are only opened once),
-                  so try it here. */
-               handle = CreateFileA(path,
-                       GENERIC_WRITE |GENERIC_READ,
-                       FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/
-                       NULL,
-                       OPEN_EXISTING,
-                       FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
-                       0);
-       }
-
        return handle;
 }
 
@@ -264,29 +270,31 @@ int HID_API_EXPORT hid_exit(void)
 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned 
short vendor_id, unsigned short product_id)
 {
        BOOL res;
-       struct hid_device_info *root = NULL; // return object
+       struct hid_device_info *root = NULL; /* return object */
        struct hid_device_info *cur_dev = NULL;
 
-       // Windows objects for interacting with the driver.
+       /* Windows objects for interacting with the driver. */
        GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 
0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
        SP_DEVINFO_DATA devinfo_data;
        SP_DEVICE_INTERFACE_DATA device_interface_data;
        SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
        HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
        int device_index = 0;
+       int i;
 
        if (hid_init() < 0)
                return NULL;
 
-       // Initialize the Windows objects.
+       /* Initialize the Windows objects. */
+       memset(&devinfo_data, 0x0, sizeof(devinfo_data));
        devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
        device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 
-       // Get information for all the devices belonging to the HID class.
+       /* Get information for all the devices belonging to the HID class. */
        device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, 
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
-
-       // Iterate over each device in the HID class, looking for the right one.
-
+       
+       /* Iterate over each device in the HID class, looking for the right 
one. */
+       
        for (;;) {
                HANDLE write_handle = INVALID_HANDLE_VALUE;
                DWORD required_size = 0;
@@ -297,16 +305,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
                        &InterfaceClassGuid,
                        device_index,
                        &device_interface_data);
-
+               
                if (!res) {
-                       // A return of FALSE from this function means that
-                       // there are no more devices.
+                       /* A return of FALSE from this function means that
+                          there are no more devices. */
                        break;
                }
 
-               // Call with 0-sized detail size, and let the function
-               // tell us how long the detail struct needs to be. The
-               // size is put in &required_size.
+               /* Call with 0-sized detail size, and let the function
+                  tell us how long the detail struct needs to be. The
+                  size is put in &required_size. */
                res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
                        &device_interface_data,
                        NULL,
@@ -314,13 +322,13 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
                        &required_size,
                        NULL);
 
-               // Allocate a long enough structure for 
device_interface_detail_data.
+               /* Allocate a long enough structure for 
device_interface_detail_data. */
                device_interface_detail_data = 
(SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
                device_interface_detail_data->cbSize = 
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
 
-               // Get the detailed data for this device. The detail data gives 
us
-               // the device path for this device, which is then passed into
-               // CreateFile() to get a handle to the device.
+               /* Get the detailed data for this device. The detail data gives 
us
+                  the device path for this device, which is then passed into
+                  CreateFile() to get a handle to the device. */
                res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
                        &device_interface_data,
                        device_interface_detail_data,
@@ -329,42 +337,67 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
                        NULL);
 
                if (!res) {
-                       //register_error(dev, "Unable to call 
SetupDiGetDeviceInterfaceDetail");
-                       // Continue to the next device.
+                       /* register_error(dev, "Unable to call 
SetupDiGetDeviceInterfaceDetail");
+                          Continue to the next device. */
                        goto cont;
                }
 
+               /* Make sure this device is of Setup Class "HIDClass" and has a
+                  driver bound to it. */
+               for (i = 0; ; i++) {
+                       char driver_name[256];
+
+                       /* Populate devinfo_data. This function will return 
failure
+                          when there are no more interfaces left. */
+                       res = SetupDiEnumDeviceInfo(device_info_set, i, 
&devinfo_data);
+                       if (!res)
+                               goto cont;
+
+                       res = 
SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
+                                      SPDRP_CLASS, NULL, (PBYTE)driver_name, 
sizeof(driver_name), NULL);
+                       if (!res)
+                               goto cont;
+
+                       if (strcmp(driver_name, "HIDClass") == 0) {
+                               /* See if there's a driver bound. */
+                               res = 
SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
+                                          SPDRP_DRIVER, NULL, 
(PBYTE)driver_name, sizeof(driver_name), NULL);
+                               if (res)
+                                       break;
+                       }
+               }
+
                //wprintf(L"HandleName: %s\n", 
device_interface_detail_data->DevicePath);
 
-               // Open a handle to the device
-               write_handle = 
open_device(device_interface_detail_data->DevicePath);
+               /* Open a handle to the device */
+               write_handle = 
open_device(device_interface_detail_data->DevicePath, TRUE);
 
-               // Check validity of write_handle.
+               /* Check validity of write_handle. */
                if (write_handle == INVALID_HANDLE_VALUE) {
-                       // Unable to open the device.
+                       /* Unable to open the device. */
                        //register_error(dev, "CreateFile");
                        goto cont_close;
-               }
+               }               
 
 
-               // Get the Vendor ID and Product ID for this device.
+               /* Get the Vendor ID and Product ID for this device. */
                attrib.Size = sizeof(HIDD_ATTRIBUTES);
                HidD_GetAttributes(write_handle, &attrib);
                //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, 
attrib.VendorID);
 
-               // Check the VID/PID to see if we should add this
-               // device to the enumeration list.
-               if ((vendor_id == 0x0 && product_id == 0x0) ||
-                       (attrib.VendorID == vendor_id && attrib.ProductID == 
product_id)) {
+               /* Check the VID/PID to see if we should add this
+                  device to the enumeration list. */
+               if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
+                   (product_id == 0x0 || attrib.ProductID == product_id)) {
 
                        #define WSTR_LEN 512
                        const char *str;
                        struct hid_device_info *tmp;
-                       HIDP_PREPARSED_DATA *pp_data = NULL;
+                       PHIDP_PREPARSED_DATA pp_data = NULL;
                        HIDP_CAPS caps;
                        BOOLEAN res;
                        NTSTATUS nt_res;
-                       wchar_t wstr[WSTR_LEN]; // TODO: Determine Size
+                       wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
                        size_t len;
 
                        /* VID/PID match. Create the record. */
@@ -377,7 +410,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
                        }
                        cur_dev = tmp;
 
-                       // Get the Usage Page and Usage for this device.
+                       /* Get the Usage Page and Usage for this device. */
                        res = HidD_GetPreparsedData(write_handle, &pp_data);
                        if (res) {
                                nt_res = HidP_GetCaps(pp_data, &caps);
@@ -388,7 +421,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
 
                                HidD_FreePreparsedData(pp_data);
                        }
-
+                       
                        /* Fill out the record */
                        cur_dev->next = NULL;
                        str = device_interface_detail_data->DevicePath;
@@ -452,14 +485,14 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL 
hid_enumerate(unsigned shor
 cont_close:
                CloseHandle(write_handle);
 cont:
-               // We no longer need the detail data. It can be freed
+               /* We no longer need the detail data. It can be freed */
                free(device_interface_detail_data);
 
                device_index++;
 
        }
 
-       // Close the device information handle.
+       /* Close the device information handle. */
        SetupDiDestroyDeviceInfoList(device_info_set);
 
        return root;
@@ -468,7 +501,7 @@ cont:
 
 void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info 
*devs)
 {
-       // TODO: Merge this with the Linux version. This function is 
platform-independent.
+       /* TODO: Merge this with the Linux version. This function is 
platform-independent. */
        struct hid_device_info *d = devs;
        while (d) {
                struct hid_device_info *next = d->next;
@@ -482,13 +515,13 @@ void  HID_API_EXPORT HID_API_CALL 
hid_free_enumeration(struct hid_device_info *d
 }
 
 
-HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, 
unsigned short product_id, wchar_t *serial_number)
+HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, 
unsigned short product_id, const wchar_t *serial_number)
 {
-       // TODO: Merge this functions with the Linux version. This function 
should be platform independent.
+       /* TODO: Merge this functions with the Linux version. This function 
should be platform independent. */
        struct hid_device_info *devs, *cur_dev;
        const char *path_to_open = NULL;
        hid_device *handle = NULL;
-
+       
        devs = hid_enumerate(vendor_id, product_id);
        cur_dev = devs;
        while (cur_dev) {
@@ -514,7 +547,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned 
short vendor_id, unsi
        }
 
        hid_free_enumeration(devs);
-
+       
        return handle;
 }
 
@@ -522,7 +555,7 @@ HID_API_EXPORT hid_device * HID_API_CALL 
hid_open_path(const char *path)
 {
        hid_device *dev;
        HIDP_CAPS caps;
-       HIDP_PREPARSED_DATA *pp_data = NULL;
+       PHIDP_PREPARSED_DATA pp_data = NULL;
        BOOLEAN res;
        NTSTATUS nt_res;
 
@@ -532,17 +565,24 @@ HID_API_EXPORT hid_device * HID_API_CALL 
hid_open_path(const char *path)
 
        dev = new_hid_device();
 
-       // Open a handle to the device
-       dev->device_handle = open_device(path);
+       /* Open a handle to the device */
+       dev->device_handle = open_device(path, FALSE);
 
-       // Check validity of write_handle.
+       /* Check validity of write_handle. */
        if (dev->device_handle == INVALID_HANDLE_VALUE) {
-               // Unable to open the device.
+               /* Unable to open the device. */
                register_error(dev, "CreateFile");
                goto err;
        }
 
-       // Get the Input Report length for the device.
+       /* Set the Input Report buffer size to 64 reports. */
+       res = HidD_SetNumInputBuffers(dev->device_handle, 64);
+       if (!res) {
+               register_error(dev, "HidD_SetNumInputBuffers");
+               goto err;
+       }
+
+       /* Get the Input Report length for the device. */
        res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
        if (!res) {
                register_error(dev, "HidD_GetPreparsedData");
@@ -550,9 +590,10 @@ HID_API_EXPORT hid_device * HID_API_CALL 
hid_open_path(const char *path)
        }
        nt_res = HidP_GetCaps(pp_data, &caps);
        if (nt_res != HIDP_STATUS_SUCCESS) {
-               register_error(dev, "HidP_GetCaps");
+               register_error(dev, "HidP_GetCaps");    
                goto err_pp_data;
        }
+       dev->output_report_length = caps.OutputReportByteLength;
        dev->input_report_length = caps.InputReportByteLength;
        HidD_FreePreparsedData(pp_data);
 
@@ -562,9 +603,8 @@ HID_API_EXPORT hid_device * HID_API_CALL 
hid_open_path(const char *path)
 
 err_pp_data:
                HidD_FreePreparsedData(pp_data);
-err:
-               CloseHandle(dev->device_handle);
-               free(dev);
+err:   
+               free_hid_device(dev);
                return NULL;
 }
 
@@ -574,27 +614,52 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device 
*dev, const unsigned char *
        BOOL res;
 
        OVERLAPPED ol;
+       unsigned char *buf;
        memset(&ol, 0, sizeof(ol));
 
-       res = WriteFile(dev->device_handle, data, length, NULL, &ol);
+       /* Make sure the right number of bytes are passed to WriteFile. Windows
+          expects the number of bytes which are in the _longest_ report (plus
+          one for the report number) bytes even if the data is a report
+          which is shorter than that. Windows gives us this value in
+          caps.OutputReportByteLength. If a user passes in fewer bytes than 
this,
+          create a temporary buffer which is the proper size. */
+       if (length >= dev->output_report_length) {
+               /* The user passed the right number of bytes. Use the buffer 
as-is. */
+               buf = (unsigned char *) data;
+       } else {
+               /* Create a temporary buffer and copy the user's data
+                  into it, padding the rest with zeros. */
+               buf = (unsigned char *) malloc(dev->output_report_length);
+               memcpy(buf, data, length);
+               memset(buf + length, 0, dev->output_report_length - length);
+               length = dev->output_report_length;
+       }
 
+       res = WriteFile(dev->device_handle, buf, length, NULL, &ol);
+       
        if (!res) {
                if (GetLastError() != ERROR_IO_PENDING) {
-                       // WriteFile() failed. Return error.
+                       /* WriteFile() failed. Return error. */
                        register_error(dev, "WriteFile");
-                       return -1;
+                       bytes_written = -1;
+                       goto end_of_function;
                }
        }
 
-       // Wait here until the write is done. This makes
-       // hid_write() synchronous.
+       /* Wait here until the write is done. This makes
+          hid_write() synchronous. */
        res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, 
TRUE/*wait*/);
        if (!res) {
-               // The Write operation failed.
+               /* The Write operation failed. */
                register_error(dev, "WriteFile");
-               return -1;
+               bytes_written = -1;
+               goto end_of_function;
        }
 
+end_of_function:
+       if (buf != data)
+               free(buf);
+
        return bytes_written;
 }
 
@@ -602,21 +667,23 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device 
*dev, const unsigned char *
 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned 
char *data, size_t length, int milliseconds)
 {
        DWORD bytes_read = 0;
+       size_t copy_len = 0;
        BOOL res;
 
-       // Copy the handle for convenience.
+       /* Copy the handle for convenience. */
        HANDLE ev = dev->ol.hEvent;
 
        if (!dev->read_pending) {
-               // Start an Overlapped I/O read.
+               /* Start an Overlapped I/O read. */
                dev->read_pending = TRUE;
+               memset(dev->read_buf, 0, dev->input_report_length);
                ResetEvent(ev);
                res = ReadFile(dev->device_handle, dev->read_buf, 
dev->input_report_length, &bytes_read, &dev->ol);
-
+               
                if (!res) {
                        if (GetLastError() != ERROR_IO_PENDING) {
-                               // ReadFile() has failed.
-                               // Clean up and return error.
+                               /* ReadFile() has failed.
+                                  Clean up and return error. */
                                CancelIo(dev->device_handle);
                                dev->read_pending = FALSE;
                                goto end_of_function;
@@ -625,21 +692,21 @@ int HID_API_EXPORT HID_API_CALL 
hid_read_timeout(hid_device *dev, unsigned char
        }
 
        if (milliseconds >= 0) {
-               // See if there is any data yet.
+               /* See if there is any data yet. */
                res = WaitForSingleObject(ev, milliseconds);
                if (res != WAIT_OBJECT_0) {
-                       // There was no data this time. Return zero bytes 
available,
-                       // but leave the Overlapped I/O running.
+                       /* There was no data this time. Return zero bytes 
available,
+                          but leave the Overlapped I/O running. */
                        return 0;
                }
        }
 
-       // Either WaitForSingleObject() told us that ReadFile has completed, or
-       // we are in non-blocking mode. Get the number of bytes read. The actual
-       // data has been copied to the data[] array which was passed to 
ReadFile().
+       /* Either WaitForSingleObject() told us that ReadFile has completed, or
+          we are in non-blocking mode. Get the number of bytes read. The actual
+          data has been copied to the data[] array which was passed to 
ReadFile(). */
        res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, 
TRUE/*wait*/);
-
-       // Set pending back to false, even if GetOverlappedResult() returned 
error.
+       
+       /* Set pending back to false, even if GetOverlappedResult() returned 
error. */
        dev->read_pending = FALSE;
 
        if (res && bytes_read > 0) {
@@ -649,21 +716,23 @@ int HID_API_EXPORT HID_API_CALL 
hid_read_timeout(hid_device *dev, unsigned char
                           work like the other platforms, and to make it work 
more like the
                           HID spec, we'll skip over this byte. */
                        bytes_read--;
-                       memcpy(data, dev->read_buf+1, length);
+                       copy_len = length > bytes_read ? bytes_read : length;
+                       memcpy(data, dev->read_buf+1, copy_len);
                }
                else {
                        /* Copy the whole buffer, report number and all. */
-                       memcpy(data, dev->read_buf, length);
+                       copy_len = length > bytes_read ? bytes_read : length;
+                       memcpy(data, dev->read_buf, copy_len);
                }
        }
-
+       
 end_of_function:
        if (!res) {
                register_error(dev, "GetOverlappedResult");
                return -1;
        }
-
-       return bytes_read;
+       
+       return copy_len;
 }
 
 int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, 
size_t length)
@@ -713,20 +782,26 @@ int HID_API_EXPORT HID_API_CALL 
hid_get_feature_report(hid_device *dev, unsigned
 
        if (!res) {
                if (GetLastError() != ERROR_IO_PENDING) {
-                       // DeviceIoControl() failed. Return error.
+                       /* DeviceIoControl() failed. Return error. */
                        register_error(dev, "Send Feature Report 
DeviceIoControl");
                        return -1;
                }
        }
 
-       // Wait here until the write is done. This makes
-       // hid_get_feature_report() synchronous.
+       /* Wait here until the write is done. This makes
+          hid_get_feature_report() synchronous. */
        res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, 
TRUE/*wait*/);
        if (!res) {
-               // The operation failed.
+               /* The operation failed. */
                register_error(dev, "Send Feature Report GetOverLappedResult");
                return -1;
        }
+
+       /* bytes_returned does not include the first byte which contains the
+          report ID. The data buffer actually contains one more byte than
+          bytes_returned. */
+       bytes_returned++;
+
        return bytes_returned;
 #endif
 }
@@ -736,18 +811,14 @@ void HID_API_EXPORT HID_API_CALL hid_close(hid_device 
*dev)
        if (!dev)
                return;
        CancelIo(dev->device_handle);
-       CloseHandle(dev->ol.hEvent);
-       CloseHandle(dev->device_handle);
-       LocalFree(dev->last_error_str);
-       free(dev->read_buf);
-       free(dev);
+       free_hid_device(dev);
 }
 
 int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device 
*dev, wchar_t *string, size_t maxlen)
 {
        BOOL res;
 
-       res = HidD_GetManufacturerString(dev->device_handle, string, 2 * 
maxlen);
+       res = HidD_GetManufacturerString(dev->device_handle, string, 
sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
        if (!res) {
                register_error(dev, "HidD_GetManufacturerString");
                return -1;
@@ -760,7 +831,7 @@ int HID_API_EXPORT_CALL HID_API_CALL 
hid_get_product_string(hid_device *dev, wch
 {
        BOOL res;
 
-       res = HidD_GetProductString(dev->device_handle, string, 2 * maxlen);
+       res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) 
* MIN(maxlen, MAX_STRING_WCHARS));
        if (!res) {
                register_error(dev, "HidD_GetProductString");
                return -1;
@@ -773,7 +844,7 @@ int HID_API_EXPORT_CALL HID_API_CALL 
hid_get_serial_number_string(hid_device *de
 {
        BOOL res;
 
-       res = HidD_GetSerialNumberString(dev->device_handle, string, 2 * 
maxlen);
+       res = HidD_GetSerialNumberString(dev->device_handle, string, 
sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
        if (!res) {
                register_error(dev, "HidD_GetSerialNumberString");
                return -1;
@@ -786,7 +857,7 @@ int HID_API_EXPORT_CALL HID_API_CALL 
hid_get_indexed_string(hid_device *dev, int
 {
        BOOL res;
 
-       res = HidD_GetIndexedString(dev->device_handle, string_index, string, 2 
* maxlen);
+       res = HidD_GetIndexedString(dev->device_handle, string_index, string, 
sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
        if (!res) {
                register_error(dev, "HidD_GetIndexedString");
                return -1;
@@ -802,10 +873,10 @@ HID_API_EXPORT const wchar_t * HID_API_CALL  
hid_error(hid_device *dev)
 }
 
 
-//#define PICPGM
-//#define S11
+/*#define PICPGM*/
+/*#define S11*/
 #define P32
-#ifdef S11
+#ifdef S11 
   unsigned short VendorID = 0xa0a0;
        unsigned short ProductID = 0x0001;
 #endif
@@ -831,36 +902,36 @@ int __cdecl main(int argc, char* argv[])
        UNREFERENCED_PARAMETER(argc);
        UNREFERENCED_PARAMETER(argv);
 
-       // Set up the command buffer.
+       /* Set up the command buffer. */
        memset(buf,0x00,sizeof(buf));
        buf[0] = 0;
        buf[1] = 0x81;
+       
 
-
-       // Open the device.
+       /* Open the device. */
        int handle = open(VendorID, ProductID, L"12345");
        if (handle < 0)
                printf("unable to open device\n");
 
 
-       // Toggle LED (cmd 0x80)
+       /* Toggle LED (cmd 0x80) */
        buf[1] = 0x80;
        res = write(handle, buf, 65);
        if (res < 0)
                printf("Unable to write()\n");
 
-       // Request state (cmd 0x81)
+       /* Request state (cmd 0x81) */
        buf[1] = 0x81;
        write(handle, buf, 65);
        if (res < 0)
                printf("Unable to write() (2)\n");
 
-       // Read requested state
+       /* Read requested state */
        read(handle, buf, 65);
        if (res < 0)
                printf("Unable to read()\n");
 
-       // Print out the returned buffer.
+       /* Print out the returned buffer. */
        for (int i = 0; i < 4; i++)
                printf("buf[%d]: %d\n", i, buf[i]);
 
@@ -869,5 +940,5 @@ int __cdecl main(int argc, char* argv[])
 #endif
 
 #ifdef __cplusplus
-} // extern "C"
+} /* extern "C" */
 #endif



reply via email to

[Prev in Thread] Current Thread [Next in Thread]