sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

hid.c (30202B)


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