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