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