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