SDL  2.0
hid.c
Go to the documentation of this file.
1 /*******************************************************
2  HIDAPI - Multi-Platform library for
3  communication with HID devices.
4 
5  Alan Ott
6  Signal 11 Software
7 
8  8/22/2009
9 
10  Copyright 2009, All Rights Reserved.
11 
12  At the discretion of the user of this library,
13  this software may be licensed under the terms of the
14  GNU General Public License v3, a BSD-Style license, or the
15  original HIDAPI license as outlined in the LICENSE.txt,
16  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17  files located at the root of the source distribution.
18  These files may also be found in the public source
19  code repository located at:
20  http://github.com/signal11/hidapi .
21 ********************************************************/
22 #include "../../SDL_internal.h"
23 
24 #ifdef SDL_JOYSTICK_HIDAPI
25 
26 #include <windows.h>
27 
28 #if 0 /* can cause redefinition errors on some toolchains */
29 #ifdef __MINGW32__
30 #include <ntdef.h>
31 #include <winbase.h>
32 #endif
33 
34 #ifdef __CYGWIN__
35 #include <ntdef.h>
36 #define _wcsdup wcsdup
37 #endif
38 #endif /* */
39 
40 #ifndef _NTDEF_
41 typedef LONG NTSTATUS;
42 #endif
43 
44 /* SDL C runtime functions */
45 #include "SDL_stdinc.h"
46 
47 #define calloc SDL_calloc
48 #define free SDL_free
49 #define malloc SDL_malloc
50 #define memcpy SDL_memcpy
51 #define memset SDL_memset
52 #define strcmp SDL_strcmp
53 #define strlen SDL_strlen
54 #define strncpy SDL_strlcpy
55 #define strstr SDL_strstr
56 #define strtol SDL_strtol
57 #define wcscmp SDL_wcscmp
58 #define _wcsdup SDL_wcsdup
59 
60 /* The maximum number of characters that can be passed into the
61  HidD_Get*String() functions without it failing.*/
62 #define MAX_STRING_WCHARS 0xFFF
63 
64 /*#define HIDAPI_USE_DDK*/
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69  #include <setupapi.h>
70  #include <winioctl.h>
71  #ifdef HIDAPI_USE_DDK
72  #include <hidsdi.h>
73  #endif
74 
75  /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
76  #define HID_OUT_CTL_CODE(id) \
77  CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
78  #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
79 
80 #ifdef __cplusplus
81 } /* extern "C" */
82 #endif
83 
84 #include <stdio.h>
85 #include <stdlib.h>
86 
87 
88 #include "../hidapi/hidapi.h"
89 
90 #undef MIN
91 #define MIN(x,y) ((x) < (y)? (x): (y))
92 
93 #ifdef _MSC_VER
94  /* Thanks Microsoft, but I know how to use strncpy(). */
95  #pragma warning(disable:4996)
96 #endif
97 
98 #ifdef __cplusplus
99 extern "C" {
100 #endif
101 
102 #ifndef HIDAPI_USE_DDK
103  /* Since we're not building with the DDK, and the HID header
104  files aren't part of the SDK, we have to define all this
105  stuff here. In lookup_functions(), the function pointers
106  defined below are set. */
107  typedef struct _HIDD_ATTRIBUTES{
108  ULONG Size;
109  USHORT VendorID;
110  USHORT ProductID;
111  USHORT VersionNumber;
112  } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
113 
114  typedef USHORT USAGE;
115  typedef struct _HIDP_CAPS {
116  USAGE Usage;
117  USAGE UsagePage;
118  USHORT InputReportByteLength;
119  USHORT OutputReportByteLength;
120  USHORT FeatureReportByteLength;
121  USHORT Reserved[17];
122  USHORT fields_not_used_by_hidapi[10];
123  } HIDP_CAPS, *PHIDP_CAPS;
124  typedef void* PHIDP_PREPARSED_DATA;
125  #define HIDP_STATUS_SUCCESS 0x110000
126 
127  typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
128  typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
129  typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
130  typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
131  typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
132  typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
133  typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
134  typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
135  typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
136  typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps);
137  typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
138  typedef BOOLEAN(__stdcall *HidD_SetOutputReport_ )(HANDLE handle, PVOID buffer, ULONG buffer_len);
139  static HidD_GetAttributes_ HidD_GetAttributes;
140  static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
141  static HidD_GetManufacturerString_ HidD_GetManufacturerString;
142  static HidD_GetProductString_ HidD_GetProductString;
143  static HidD_SetFeature_ HidD_SetFeature;
144  static HidD_GetFeature_ HidD_GetFeature;
145  static HidD_GetIndexedString_ HidD_GetIndexedString;
146  static HidD_GetPreparsedData_ HidD_GetPreparsedData;
147  static HidD_FreePreparsedData_ HidD_FreePreparsedData;
148  static HidP_GetCaps_ HidP_GetCaps;
149  static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
150  static HidD_SetOutputReport_ HidD_SetOutputReport;
151 
152  static HMODULE lib_handle = NULL;
153  static BOOLEAN initialized = FALSE;
154 #endif /* HIDAPI_USE_DDK */
155 
156 struct hid_device_ {
157  HANDLE device_handle;
158  BOOL blocking;
159  USHORT output_report_length;
160  size_t input_report_length;
161  void *last_error_str;
162  DWORD last_error_num;
163  BOOL read_pending;
164  char *read_buf;
165  OVERLAPPED ol;
166 };
167 
168 static hid_device *new_hid_device()
169 {
170  hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
171  dev->device_handle = INVALID_HANDLE_VALUE;
172  dev->blocking = TRUE;
173  dev->output_report_length = 0;
174  dev->input_report_length = 0;
175  dev->last_error_str = NULL;
176  dev->last_error_num = 0;
177  dev->read_pending = FALSE;
178  dev->read_buf = NULL;
179  memset(&dev->ol, 0, sizeof(dev->ol));
180  dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
181 
182  return dev;
183 }
184 
185 static void free_hid_device(hid_device *dev)
186 {
187  CloseHandle(dev->ol.hEvent);
188  CloseHandle(dev->device_handle);
189  LocalFree(dev->last_error_str);
190  free(dev->read_buf);
191  free(dev);
192 }
193 
194 static void register_error(hid_device *device, const char *op)
195 {
196  WCHAR *ptr, *msg;
197 
198  DWORD count = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
199  FORMAT_MESSAGE_FROM_SYSTEM |
200  FORMAT_MESSAGE_IGNORE_INSERTS,
201  NULL,
202  GetLastError(),
203  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
204  (LPWSTR)&msg, 0/*sz*/,
205  NULL);
206  if (!count)
207  return;
208 
209  /* Get rid of the CR and LF that FormatMessage() sticks at the
210  end of the message. Thanks Microsoft! */
211  ptr = msg;
212  while (*ptr) {
213  if (*ptr == '\r') {
214  *ptr = 0x0000;
215  break;
216  }
217  ptr++;
218  }
219 
220  /* Store the message off in the Device entry so that
221  the hid_error() function can pick it up. */
222  LocalFree(device->last_error_str);
223  device->last_error_str = msg;
224 }
225 
226 #ifndef HIDAPI_USE_DDK
227 static int lookup_functions()
228 {
229  lib_handle = LoadLibraryA("hid.dll");
230  if (lib_handle) {
231 #define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
232  RESOLVE(HidD_GetAttributes);
233  RESOLVE(HidD_GetSerialNumberString);
234  RESOLVE(HidD_GetManufacturerString);
235  RESOLVE(HidD_GetProductString);
236  RESOLVE(HidD_SetFeature);
237  RESOLVE(HidD_GetFeature);
238  RESOLVE(HidD_GetIndexedString);
239  RESOLVE(HidD_GetPreparsedData);
240  RESOLVE(HidD_FreePreparsedData);
241  RESOLVE(HidP_GetCaps);
242  RESOLVE(HidD_SetNumInputBuffers);
243  RESOLVE(HidD_SetOutputReport);
244 #undef RESOLVE
245  }
246  else
247  return -1;
248 
249  return 0;
250 }
251 #endif
252 
253 static HANDLE open_device(const char *path, BOOL enumerate, BOOL bExclusive )
254 {
255  HANDLE handle;
256  // Opening with access 0 causes keyboards to stop responding in some system configurations
257  // http://steamcommunity.com/discussions/forum/1/1843493219428923893
258  // Thanks to co-wie (Ka-wei Low <kawei@mac.com>) for help narrowing down the problem on his system
259  //DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ);
260  DWORD desired_access = ( GENERIC_WRITE | GENERIC_READ );
261  DWORD share_mode = bExclusive ? 0 : ( FILE_SHARE_READ | FILE_SHARE_WRITE );
262 
263  handle = CreateFileA(path,
264  desired_access,
265  share_mode,
266  NULL,
267  OPEN_EXISTING,
268  FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
269  0);
270 
271  return handle;
272 }
273 
274 int HID_API_EXPORT hid_init(void)
275 {
276 #ifndef HIDAPI_USE_DDK
277  if (!initialized) {
278  if (lookup_functions() < 0) {
279  hid_exit();
280  return -1;
281  }
282  initialized = TRUE;
283  }
284 #endif
285  return 0;
286 }
287 
288 int HID_API_EXPORT hid_exit(void)
289 {
290 #ifndef HIDAPI_USE_DDK
291  if (lib_handle)
292  FreeLibrary(lib_handle);
293  lib_handle = NULL;
294  initialized = FALSE;
295 #endif
296  return 0;
297 }
298 
299 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
300 {
301  BOOL res;
302  struct hid_device_info *root = NULL; /* return object */
303  struct hid_device_info *cur_dev = NULL;
304 
305  /* Windows objects for interacting with the driver. */
306  GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
307  SP_DEVINFO_DATA devinfo_data;
308  SP_DEVICE_INTERFACE_DATA device_interface_data;
309  SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
310  HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
311  int device_index = 0;
312  int i;
313 
314  if (hid_init() < 0)
315  return NULL;
316 
317  /* Initialize the Windows objects. */
318  memset(&devinfo_data, 0x0, sizeof(devinfo_data));
319  devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
320  device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
321 
322  /* Get information for all the devices belonging to the HID class. */
323  device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
324 
325  /* Iterate over each device in the HID class, looking for the right one. */
326 
327  for (;;) {
328  HANDLE write_handle = INVALID_HANDLE_VALUE;
329  DWORD required_size = 0;
330  HIDD_ATTRIBUTES attrib;
331 
332  res = SetupDiEnumDeviceInterfaces(device_info_set,
333  NULL,
334  &InterfaceClassGuid,
335  device_index,
336  &device_interface_data);
337 
338  if (!res) {
339  /* A return of FALSE from this function means that
340  there are no more devices. */
341  break;
342  }
343 
344  /* Call with 0-sized detail size, and let the function
345  tell us how long the detail struct needs to be. The
346  size is put in &required_size. */
347  res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
348  &device_interface_data,
349  NULL,
350  0,
351  &required_size,
352  NULL);
353 
354  /* Allocate a long enough structure for device_interface_detail_data. */
355  device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
356  device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
357 
358  /* Get the detailed data for this device. The detail data gives us
359  the device path for this device, which is then passed into
360  CreateFile() to get a handle to the device. */
361  res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
362  &device_interface_data,
363  device_interface_detail_data,
364  required_size,
365  NULL,
366  NULL);
367 
368  if (!res) {
369  /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
370  Continue to the next device. */
371  goto cont;
372  }
373 
374  /* Make sure this device is of Setup Class "HIDClass" and has a
375  driver bound to it. */
376  for (i = 0; ; i++) {
377  char driver_name[256];
378 
379  /* Populate devinfo_data. This function will return failure
380  when there are no more interfaces left. */
381  res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
382  if (!res)
383  goto cont;
384 
385  res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
386  SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
387  if (!res)
388  goto cont;
389 
390  if (strcmp(driver_name, "HIDClass") == 0) {
391  /* See if there's a driver bound. */
392  res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
393  SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
394  if (res)
395  break;
396  }
397  }
398 
399  //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
400 
401  /* Open a handle to the device */
402  write_handle = open_device(device_interface_detail_data->DevicePath, TRUE, FALSE);
403 
404  /* Check validity of write_handle. */
405  if (write_handle == INVALID_HANDLE_VALUE) {
406  /* Unable to open the device. */
407  //register_error(dev, "CreateFile");
408  goto cont_close;
409  }
410 
411 
412  /* Get the Vendor ID and Product ID for this device. */
413  attrib.Size = sizeof(HIDD_ATTRIBUTES);
414  HidD_GetAttributes(write_handle, &attrib);
415  //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
416 
417  /* Check the VID/PID to see if we should add this
418  device to the enumeration list. */
419  if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
420  (product_id == 0x0 || attrib.ProductID == product_id)) {
421 
422  #define WSTR_LEN 512
423  const char *str;
424  struct hid_device_info *tmp;
425  PHIDP_PREPARSED_DATA pp_data = NULL;
426  HIDP_CAPS caps;
427  BOOLEAN hidp_res;
428  NTSTATUS nt_res;
429  wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
430  size_t len;
431 
432  /* VID/PID match. Create the record. */
433  tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
434  if (cur_dev) {
435  cur_dev->next = tmp;
436  }
437  else {
438  root = tmp;
439  }
440  cur_dev = tmp;
441 
442  /* Get the Usage Page and Usage for this device. */
443  hidp_res = HidD_GetPreparsedData(write_handle, &pp_data);
444  if (hidp_res) {
445  nt_res = HidP_GetCaps(pp_data, &caps);
446  if (nt_res == HIDP_STATUS_SUCCESS) {
447  cur_dev->usage_page = caps.UsagePage;
448  cur_dev->usage = caps.Usage;
449  }
450 
451  HidD_FreePreparsedData(pp_data);
452  }
453 
454  /* Fill out the record */
455  cur_dev->next = NULL;
456  str = device_interface_detail_data->DevicePath;
457  if (str) {
458  len = strlen(str);
459  cur_dev->path = (char*) calloc(len+1, sizeof(char));
460  strncpy(cur_dev->path, str, len+1);
461  cur_dev->path[len] = '\0';
462  }
463  else
464  cur_dev->path = NULL;
465 
466  /* Serial Number */
467  hidp_res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
468  wstr[WSTR_LEN-1] = 0x0000;
469  if (hidp_res) {
470  cur_dev->serial_number = _wcsdup(wstr);
471  }
472 
473  /* Manufacturer String */
474  hidp_res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
475  wstr[WSTR_LEN-1] = 0x0000;
476  if (hidp_res) {
477  cur_dev->manufacturer_string = _wcsdup(wstr);
478  }
479 
480  /* Product String */
481  hidp_res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
482  wstr[WSTR_LEN-1] = 0x0000;
483  if (hidp_res) {
484  cur_dev->product_string = _wcsdup(wstr);
485  }
486 
487  /* VID/PID */
488  cur_dev->vendor_id = attrib.VendorID;
489  cur_dev->product_id = attrib.ProductID;
490 
491  /* Release Number */
492  cur_dev->release_number = attrib.VersionNumber;
493 
494  /* Interface Number. It can sometimes be parsed out of the path
495  on Windows if a device has multiple interfaces. See
496  http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
497  search for "Hardware IDs for HID Devices" at MSDN. If it's not
498  in the path, it's set to -1. */
499  cur_dev->interface_number = -1;
500  if (cur_dev->path) {
501  char *interface_component = strstr(cur_dev->path, "&mi_");
502  if (interface_component) {
503  char *hex_str = interface_component + 4;
504  char *endptr = NULL;
505  cur_dev->interface_number = strtol(hex_str, &endptr, 16);
506  if (endptr == hex_str) {
507  /* The parsing failed. Set interface_number to -1. */
508  cur_dev->interface_number = -1;
509  }
510  }
511  }
512  }
513 
514 cont_close:
515  CloseHandle(write_handle);
516 cont:
517  /* We no longer need the detail data. It can be freed */
518  free(device_interface_detail_data);
519 
520  device_index++;
521 
522  }
523 
524  /* Close the device information handle. */
525  SetupDiDestroyDeviceInfoList(device_info_set);
526 
527  return root;
528 
529 }
530 
532 {
533  /* TODO: Merge this with the Linux version. This function is platform-independent. */
534  struct hid_device_info *d = devs;
535  while (d) {
536  struct hid_device_info *next = d->next;
537  free(d->path);
538  free(d->serial_number);
540  free(d->product_string);
541  free(d);
542  d = next;
543  }
544 }
545 
546 
547 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
548 {
549  /* TODO: Merge this functions with the Linux version. This function should be platform independent. */
550  struct hid_device_info *devs, *cur_dev;
551  const char *path_to_open = NULL;
552  hid_device *handle = NULL;
553 
554  devs = hid_enumerate(vendor_id, product_id);
555  cur_dev = devs;
556  while (cur_dev) {
557  if (cur_dev->vendor_id == vendor_id &&
558  cur_dev->product_id == product_id) {
559  if (serial_number) {
560  if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
561  path_to_open = cur_dev->path;
562  break;
563  }
564  }
565  else {
566  path_to_open = cur_dev->path;
567  break;
568  }
569  }
570  cur_dev = cur_dev->next;
571  }
572 
573  if (path_to_open) {
574  /* Open the device */
575  handle = hid_open_path(path_to_open, 0);
576  }
577 
578  hid_free_enumeration(devs);
579 
580  return handle;
581 }
582 
583 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive)
584 {
585  hid_device *dev;
586  HIDP_CAPS caps;
587  PHIDP_PREPARSED_DATA pp_data = NULL;
588  BOOLEAN res;
589  NTSTATUS nt_res;
590 
591  if (hid_init() < 0) {
592  return NULL;
593  }
594 
595  dev = new_hid_device();
596 
597  /* Open a handle to the device */
598  dev->device_handle = open_device(path, FALSE, bExclusive);
599 
600  /* Check validity of write_handle. */
601  if (dev->device_handle == INVALID_HANDLE_VALUE) {
602  /* Unable to open the device. */
603  register_error(dev, "CreateFile");
604  goto err;
605  }
606 
607  /* Set the Input Report buffer size to 64 reports. */
608  res = HidD_SetNumInputBuffers(dev->device_handle, 64);
609  if (!res) {
610  register_error(dev, "HidD_SetNumInputBuffers");
611  goto err;
612  }
613 
614  /* Get the Input Report length for the device. */
615  res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
616  if (!res) {
617  register_error(dev, "HidD_GetPreparsedData");
618  goto err;
619  }
620  nt_res = HidP_GetCaps(pp_data, &caps);
621  if (nt_res != HIDP_STATUS_SUCCESS) {
622  register_error(dev, "HidP_GetCaps");
623  goto err_pp_data;
624  }
625  dev->output_report_length = caps.OutputReportByteLength;
626  dev->input_report_length = caps.InputReportByteLength;
627  HidD_FreePreparsedData(pp_data);
628 
629  dev->read_buf = (char*) malloc(dev->input_report_length);
630 
631  return dev;
632 
633 err_pp_data:
634  HidD_FreePreparsedData(pp_data);
635 err:
636  free_hid_device(dev);
637  return NULL;
638 }
639 
640 int HID_API_EXPORT HID_API_CALL hid_write_output_report(hid_device *dev, const unsigned char *data, size_t length)
641 {
642  BOOL res;
643  res = HidD_SetOutputReport(dev->device_handle, (void *)data, (ULONG)length);
644  if (res)
645  return (int)length;
646  else
647  return -1;
648 }
649 
650 int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
651 {
652  DWORD bytes_written;
653  BOOL res;
654  size_t stashed_length = length;
655  OVERLAPPED ol;
656  unsigned char *buf;
657  memset(&ol, 0, sizeof(ol));
658 
659  /* Make sure the right number of bytes are passed to WriteFile. Windows
660  expects the number of bytes which are in the _longest_ report (plus
661  one for the report number) bytes even if the data is a report
662  which is shorter than that. Windows gives us this value in
663  caps.OutputReportByteLength. If a user passes in fewer bytes than this,
664  create a temporary buffer which is the proper size. */
665  if (length >= dev->output_report_length) {
666  /* The user passed the right number of bytes. Use the buffer as-is. */
667  buf = (unsigned char *) data;
668  } else {
669  /* Create a temporary buffer and copy the user's data
670  into it, padding the rest with zeros. */
671  buf = (unsigned char *) malloc(dev->output_report_length);
672  memcpy(buf, data, length);
673  memset(buf + length, 0, dev->output_report_length - length);
674  length = dev->output_report_length;
675  }
676  if (length > 512)
677  {
678  return hid_write_output_report( dev, data, stashed_length );
679  }
680  else
681  {
682  res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &ol );
683  if (!res) {
684  if (GetLastError() != ERROR_IO_PENDING) {
685  /* WriteFile() failed. Return error. */
686  register_error(dev, "WriteFile");
687  bytes_written = (DWORD) -1;
688  goto end_of_function;
689  }
690  }
691 
692  /* Wait here until the write is done. This makes
693  hid_write() synchronous. */
694  res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
695  if (!res) {
696  /* The Write operation failed. */
697  register_error(dev, "WriteFile");
698  bytes_written = (DWORD) -1;
699  goto end_of_function;
700  }
701  }
702 end_of_function:
703  if (buf != data)
704  free(buf);
705 
706  return bytes_written;
707 }
708 
709 
710 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
711 {
712  DWORD bytes_read = 0;
713  size_t copy_len = 0;
714  BOOL res;
715 
716  /* Copy the handle for convenience. */
717  HANDLE ev = dev->ol.hEvent;
718 
719  if (!dev->read_pending) {
720  /* Start an Overlapped I/O read. */
721  dev->read_pending = TRUE;
722  memset(dev->read_buf, 0, dev->input_report_length);
723  ResetEvent(ev);
724  res = ReadFile(dev->device_handle, dev->read_buf, (DWORD)dev->input_report_length, &bytes_read, &dev->ol);
725 
726  if (!res) {
727  if (GetLastError() != ERROR_IO_PENDING) {
728  /* ReadFile() has failed.
729  Clean up and return error. */
730  CancelIo(dev->device_handle);
731  dev->read_pending = FALSE;
732  goto end_of_function;
733  }
734  }
735  }
736 
737  if (milliseconds >= 0) {
738  /* See if there is any data yet. */
739  res = WaitForSingleObject(ev, milliseconds);
740  if (res != WAIT_OBJECT_0) {
741  /* There was no data this time. Return zero bytes available,
742  but leave the Overlapped I/O running. */
743  return 0;
744  }
745  }
746 
747  /* Either WaitForSingleObject() told us that ReadFile has completed, or
748  we are in non-blocking mode. Get the number of bytes read. The actual
749  data has been copied to the data[] array which was passed to ReadFile(). */
750  res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
751 
752  /* Set pending back to false, even if GetOverlappedResult() returned error. */
753  dev->read_pending = FALSE;
754 
755  if (res && bytes_read > 0) {
756  if (dev->read_buf[0] == 0x0) {
757  /* If report numbers aren't being used, but Windows sticks a report
758  number (0x0) on the beginning of the report anyway. To make this
759  work like the other platforms, and to make it work more like the
760  HID spec, we'll skip over this byte. */
761  bytes_read--;
762  copy_len = length > bytes_read ? bytes_read : length;
763  memcpy(data, dev->read_buf+1, copy_len);
764  }
765  else {
766  /* Copy the whole buffer, report number and all. */
767  copy_len = length > bytes_read ? bytes_read : length;
768  memcpy(data, dev->read_buf, copy_len);
769  }
770  }
771 
772 end_of_function:
773  if (!res) {
774  register_error(dev, "GetOverlappedResult");
775  return -1;
776  }
777 
778  return (int)copy_len;
779 }
780 
781 int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
782 {
783  return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
784 }
785 
786 int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
787 {
788  dev->blocking = !nonblock;
789  return 0; /* Success */
790 }
791 
792 int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
793 {
794  BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, (ULONG)length);
795  if (!res) {
796  register_error(dev, "HidD_SetFeature");
797  return -1;
798  }
799 
800  return (int)length;
801 }
802 
803 
804 int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
805 {
806  BOOL res;
807 #if 0
808  res = HidD_GetFeature(dev->device_handle, (PVOID)data, (ULONG)length);
809  if (!res) {
810  register_error(dev, "HidD_GetFeature");
811  return -1;
812  }
813  return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */
814 #else
815  DWORD bytes_returned;
816 
817  OVERLAPPED ol;
818  memset(&ol, 0, sizeof(ol));
819 
820  res = DeviceIoControl(dev->device_handle,
821  IOCTL_HID_GET_FEATURE,
822  data, (DWORD)length,
823  data, (DWORD)length,
824  &bytes_returned, &ol);
825 
826  if (!res) {
827  if (GetLastError() != ERROR_IO_PENDING) {
828  /* DeviceIoControl() failed. Return error. */
829  register_error(dev, "Send Feature Report DeviceIoControl");
830  return -1;
831  }
832  }
833 
834  /* Wait here until the write is done. This makes
835  hid_get_feature_report() synchronous. */
836  res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
837  if (!res) {
838  /* The operation failed. */
839  register_error(dev, "Send Feature Report GetOverLappedResult");
840  return -1;
841  }
842 
843  /* bytes_returned does not include the first byte which contains the
844  report ID. The data buffer actually contains one more byte than
845  bytes_returned. */
846  bytes_returned++;
847 
848 
849  return bytes_returned;
850 #endif
851 }
852 
853 void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
854 {
855  if (!dev)
856  return;
857  CancelIo(dev->device_handle);
858  free_hid_device(dev);
859 }
860 
861 int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
862 {
863  BOOL res;
864 
865  res = HidD_GetManufacturerString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
866  if (!res) {
867  register_error(dev, "HidD_GetManufacturerString");
868  return -1;
869  }
870 
871  return 0;
872 }
873 
874 int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
875 {
876  BOOL res;
877 
878  res = HidD_GetProductString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
879  if (!res) {
880  register_error(dev, "HidD_GetProductString");
881  return -1;
882  }
883 
884  return 0;
885 }
886 
887 int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
888 {
889  BOOL res;
890 
891  res = HidD_GetSerialNumberString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
892  if (!res) {
893  register_error(dev, "HidD_GetSerialNumberString");
894  return -1;
895  }
896 
897  return 0;
898 }
899 
900 int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
901 {
902  BOOL res;
903 
904  res = HidD_GetIndexedString(dev->device_handle, string_index, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
905  if (!res) {
906  register_error(dev, "HidD_GetIndexedString");
907  return -1;
908  }
909 
910  return 0;
911 }
912 
913 HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
914 {
915  return (wchar_t*)dev->last_error_str;
916 }
917 
918 
919 #if 0
920 
921 /*#define PICPGM*/
922 /*#define S11*/
923 #define P32
924 #ifdef S11
925  unsigned short VendorID = 0xa0a0;
926  unsigned short ProductID = 0x0001;
927 #endif
928 
929 #ifdef P32
930  unsigned short VendorID = 0x04d8;
931  unsigned short ProductID = 0x3f;
932 #endif
933 
934 #ifdef PICPGM
935  unsigned short VendorID = 0x04d8;
936  unsigned short ProductID = 0x0033;
937 #endif
938 
939 int __cdecl main(int argc, char* argv[])
940 {
941  int res;
942  unsigned char buf[65];
943 
944  UNREFERENCED_PARAMETER(argc);
945  UNREFERENCED_PARAMETER(argv);
946 
947  /* Set up the command buffer. */
948  memset(buf,0x00,sizeof(buf));
949  buf[0] = 0;
950  buf[1] = 0x81;
951 
952 
953  /* Open the device. */
954  int handle = open(VendorID, ProductID, L"12345");
955  if (handle < 0)
956  printf("unable to open device\n");
957 
958 
959  /* Toggle LED (cmd 0x80) */
960  buf[1] = 0x80;
961  res = write(handle, buf, 65);
962  if (res < 0)
963  printf("Unable to write()\n");
964 
965  /* Request state (cmd 0x81) */
966  buf[1] = 0x81;
967  write(handle, buf, 65);
968  if (res < 0)
969  printf("Unable to write() (2)\n");
970 
971  /* Read requested state */
972  read(handle, buf, 65);
973  if (res < 0)
974  printf("Unable to read()\n");
975 
976  /* Print out the returned buffer. */
977  for (int i = 0; i < 4; i++)
978  printf("buf[%d]: %d\n", i, buf[i]);
979 
980  return 0;
981 }
982 #endif
983 
984 #ifdef __cplusplus
985 } /* extern "C" */
986 #endif
987 
988 #endif /* SDL_JOYSTICK_HIDAPI */
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error(hid_device *device)
Get a string describing the last error which occurred.
Definition: hid.cpp:1149
int interface_number
Definition: hidapi.h:79
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
#define HID_API_EXPORT
Definition: hidapi.h:36
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
Free an enumeration Linked List.
Definition: hid.cpp:979
SDL_EventEntry * free
Definition: SDL_events.c:84
#define memset
Definition: SDL_malloc.c:619
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
wchar_t * manufacturer_string
Definition: hidapi.h:66
char * path
Definition: hidapi.h:55
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
Write an Output report to a HID device.
Definition: hid.cpp:1028
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
Get a string from a HID device, based on its string index.
Definition: hid.cpp:1144
GLenum GLsizei len
GLuint res
static SDL_AudioDeviceID device
Definition: loopwave.c:37
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
Definition: hid.cpp:1040
struct hid_device_info * next
Definition: hidapi.h:82
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
Set the device handle to be non-blocking.
Definition: hid.cpp:1060
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
Close a HID device.
Definition: hid.cpp:1090
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
Get The Product String from a HID device.
Definition: hid.cpp:1122
unsigned short product_id
Definition: hidapi.h:59
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
#define TRUE
Definition: edid-parse.c:33
wchar_t * serial_number
Definition: hidapi.h:61
int hid_exit(void)
Finalize the HIDAPI library.
Definition: hid.cpp:1154
unsigned short vendor_id
Definition: hidapi.h:57
HID_API_EXPORT hid_device *HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally a serial number...
Definition: hid.cpp:989
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
Get a feature report from a HID device.
Definition: hid.cpp:1078
wchar_t * product_string
Definition: hidapi.h:68
unsigned short usage
Definition: hidapi.h:74
GLenum GLuint GLenum GLsizei const GLchar * buf
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
Get The Serial Number String from a HID device.
Definition: hid.cpp:1133
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define HID_API_EXPORT_CALL
Definition: hidapi.h:40
#define NULL
Definition: begin_code.h:164
GLuint buffer
int hid_init(void)
Initialize the HIDAPI library.
Definition: hid.cpp:956
unsigned short usage_page
Definition: hidapi.h:71
#define memcpy
Definition: SDL_malloc.c:622
GLuint GLfloat x0
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path, int bExclusive)
Open a HID device by its path name.
Definition: hid.cpp:995
GLsizei const GLchar *const * path
#define main
Definition: SDL_main.h:111
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
Send a Feature report to the device.
Definition: hid.cpp:1065
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
Get The Manufacturer String from a HID device.
Definition: hid.cpp:1111
GLuint GLsizei GLsizei * length
#define FALSE
Definition: edid-parse.c:34
struct hid_device_info HID_API_EXPORT *HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
Enumerate the HID Devices.
Definition: hid.cpp:961
#define HID_API_CALL
Definition: hidapi.h:37
#define malloc
Definition: SDL_qsort.c:47
unsigned short release_number
Definition: hidapi.h:64
#define MIN(a, b)
Definition: SDL_rotate.h:26
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
Read an Input report from a HID device.
Definition: hid.cpp:1053