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