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 */