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