1 /*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
10 Copyright 2009, All Rights Reserved.
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 http://github.com/signal11/hidapi .
21 ********************************************************/
26 typedef LONG NTSTATUS;
36 #define _wcsdup wcsdup
39 /* The maximum number of characters that can be passed into the
40 HidD_Get*String() functions without it failing.*/
41 #define MAX_STRING_WCHARS 0xFFF
43 /*#define HIDAPI_USE_DDK*/
54 /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
55 #define HID_OUT_CTL_CODE(id) \
56 CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
57 #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
70 #define MIN(x,y) ((x) < (y)? (x): (y))
73 /* Thanks Microsoft, but I know how to use strncpy(). */
74 #pragma warning(disable:4996)
81 #ifndef HIDAPI_USE_DDK
82 /* Since we're not building with the DDK, and the HID header
83 files aren't part of the SDK, we have to define all this
84 stuff here. In lookup_functions(), the function pointers
85 defined below are set. */
86 typedef struct _HIDD_ATTRIBUTES{
91 } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
94 typedef struct _HIDP_CAPS {
97 USHORT InputReportByteLength;
98 USHORT OutputReportByteLength;
99 USHORT FeatureReportByteLength;
101 USHORT fields_not_used_by_hidapi[10];
102 } HIDP_CAPS, *PHIDP_CAPS;
103 typedef void* PHIDP_PREPARSED_DATA;
104 #define HIDP_STATUS_SUCCESS 0x110000
106 typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
107 typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
108 typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
109 typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
110 typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
111 typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
112 typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
113 typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
114 typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
115 typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps);
116 typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
118 static HidD_GetAttributes_ HidD_GetAttributes;
119 static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
120 static HidD_GetManufacturerString_ HidD_GetManufacturerString;
121 static HidD_GetProductString_ HidD_GetProductString;
122 static HidD_SetFeature_ HidD_SetFeature;
123 static HidD_GetFeature_ HidD_GetFeature;
124 static HidD_GetIndexedString_ HidD_GetIndexedString;
125 static HidD_GetPreparsedData_ HidD_GetPreparsedData;
126 static HidD_FreePreparsedData_ HidD_FreePreparsedData;
127 static HidP_GetCaps_ HidP_GetCaps;
128 static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
130 static HMODULE lib_handle = NULL;
131 static BOOLEAN initialized = FALSE;
132 #endif /* HIDAPI_USE_DDK */
135 HANDLE device_handle;
137 USHORT output_report_length;
138 size_t input_report_length;
139 void *last_error_str;
140 DWORD last_error_num;
146 static hid_device *new_hid_device()
148 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
149 dev->device_handle = INVALID_HANDLE_VALUE;
150 dev->blocking = TRUE;
151 dev->output_report_length = 0;
152 dev->input_report_length = 0;
153 dev->last_error_str = NULL;
154 dev->last_error_num = 0;
155 dev->read_pending = FALSE;
156 dev->read_buf = NULL;
157 memset(&dev->ol, 0, sizeof(dev->ol));
158 dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
163 static void free_hid_device(hid_device *dev)
165 CloseHandle(dev->ol.hEvent);
166 CloseHandle(dev->device_handle);
167 LocalFree(dev->last_error_str);
172 static void register_error(hid_device *device, const char *op)
176 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
177 FORMAT_MESSAGE_FROM_SYSTEM |
178 FORMAT_MESSAGE_IGNORE_INSERTS,
181 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
182 (LPVOID)&msg, 0/*sz*/,
185 /* Get rid of the CR and LF that FormatMessage() sticks at the
186 end of the message. Thanks Microsoft! */
196 /* Store the message off in the Device entry so that
197 the hid_error() function can pick it up. */
198 LocalFree(device->last_error_str);
199 device->last_error_str = msg;
202 #ifndef HIDAPI_USE_DDK
203 static int lookup_functions()
205 lib_handle = LoadLibraryA("hid.dll");
207 #define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
208 RESOLVE(HidD_GetAttributes);
209 RESOLVE(HidD_GetSerialNumberString);
210 RESOLVE(HidD_GetManufacturerString);
211 RESOLVE(HidD_GetProductString);
212 RESOLVE(HidD_SetFeature);
213 RESOLVE(HidD_GetFeature);
214 RESOLVE(HidD_GetIndexedString);
215 RESOLVE(HidD_GetPreparsedData);
216 RESOLVE(HidD_FreePreparsedData);
217 RESOLVE(HidP_GetCaps);
218 RESOLVE(HidD_SetNumInputBuffers);
228 static HANDLE open_device(const char *path, BOOL enumerate)
231 DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ);
232 DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
234 handle = CreateFileA(path,
239 FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
245 int HID_API_EXPORT hid_init(void)
247 #ifndef HIDAPI_USE_DDK
249 if (lookup_functions() < 0) {
259 int HID_API_EXPORT hid_exit(void)
261 #ifndef HIDAPI_USE_DDK
263 FreeLibrary(lib_handle);
270 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
273 struct hid_device_info *root = NULL; /* return object */
274 struct hid_device_info *cur_dev = NULL;
276 /* Windows objects for interacting with the driver. */
277 GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
278 SP_DEVINFO_DATA devinfo_data;
279 SP_DEVICE_INTERFACE_DATA device_interface_data;
280 SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
281 HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
282 int device_index = 0;
288 /* Initialize the Windows objects. */
289 memset(&devinfo_data, 0x0, sizeof(devinfo_data));
290 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
291 device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
293 /* Get information for all the devices belonging to the HID class. */
294 device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
296 /* Iterate over each device in the HID class, looking for the right one. */
299 HANDLE write_handle = INVALID_HANDLE_VALUE;
300 DWORD required_size = 0;
301 HIDD_ATTRIBUTES attrib;
303 res = SetupDiEnumDeviceInterfaces(device_info_set,
307 &device_interface_data);
310 /* A return of FALSE from this function means that
311 there are no more devices. */
315 /* Call with 0-sized detail size, and let the function
316 tell us how long the detail struct needs to be. The
317 size is put in &required_size. */
318 res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
319 &device_interface_data,
325 /* Allocate a long enough structure for device_interface_detail_data. */
326 device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
327 device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
329 /* Get the detailed data for this device. The detail data gives us
330 the device path for this device, which is then passed into
331 CreateFile() to get a handle to the device. */
332 res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
333 &device_interface_data,
334 device_interface_detail_data,
340 /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
341 Continue to the next device. */
345 /* Make sure this device is of Setup Class "HIDClass" and has a
346 driver bound to it. */
348 char driver_name[256];
350 /* Populate devinfo_data. This function will return failure
351 when there are no more interfaces left. */
352 res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
356 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
357 SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
361 if (strcmp(driver_name, "HIDClass") == 0) {
362 /* See if there's a driver bound. */
363 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
364 SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
370 //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
372 /* Open a handle to the device */
373 write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);
375 /* Check validity of write_handle. */
376 if (write_handle == INVALID_HANDLE_VALUE) {
377 /* Unable to open the device. */
378 //register_error(dev, "CreateFile");
383 /* Get the Vendor ID and Product ID for this device. */
384 attrib.Size = sizeof(HIDD_ATTRIBUTES);
385 HidD_GetAttributes(write_handle, &attrib);
386 //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
388 /* Check the VID/PID to see if we should add this
389 device to the enumeration list. */
390 if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
391 (product_id == 0x0 || attrib.ProductID == product_id)) {
395 struct hid_device_info *tmp;
396 PHIDP_PREPARSED_DATA pp_data = NULL;
400 wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
403 /* VID/PID match. Create the record. */
404 tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
413 /* Get the Usage Page and Usage for this device. */
414 res = HidD_GetPreparsedData(write_handle, &pp_data);
416 nt_res = HidP_GetCaps(pp_data, &caps);
417 if (nt_res == HIDP_STATUS_SUCCESS) {
418 cur_dev->usage_page = caps.UsagePage;
419 cur_dev->usage = caps.Usage;
422 HidD_FreePreparsedData(pp_data);
425 /* Fill out the record */
426 cur_dev->next = NULL;
427 str = device_interface_detail_data->DevicePath;
430 cur_dev->path = (char*) calloc(len+1, sizeof(char));
431 strncpy(cur_dev->path, str, len+1);
432 cur_dev->path[len] = '\0';
435 cur_dev->path = NULL;
438 res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
439 wstr[WSTR_LEN-1] = 0x0000;
441 cur_dev->serial_number = _wcsdup(wstr);
444 /* Manufacturer String */
445 res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
446 wstr[WSTR_LEN-1] = 0x0000;
448 cur_dev->manufacturer_string = _wcsdup(wstr);
452 res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
453 wstr[WSTR_LEN-1] = 0x0000;
455 cur_dev->product_string = _wcsdup(wstr);
459 cur_dev->vendor_id = attrib.VendorID;
460 cur_dev->product_id = attrib.ProductID;
463 cur_dev->release_number = attrib.VersionNumber;
465 /* Interface Number. It can sometimes be parsed out of the path
466 on Windows if a device has multiple interfaces. See
467 http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
468 search for "Hardware IDs for HID Devices" at MSDN. If it's not
469 in the path, it's set to -1. */
470 cur_dev->interface_number = -1;
472 char *interface_component = strstr(cur_dev->path, "&mi_");
473 if (interface_component) {
474 char *hex_str = interface_component + 4;
476 cur_dev->interface_number = strtol(hex_str, &endptr, 16);
477 if (endptr == hex_str) {
478 /* The parsing failed. Set interface_number to -1. */
479 cur_dev->interface_number = -1;
486 CloseHandle(write_handle);
488 /* We no longer need the detail data. It can be freed */
489 free(device_interface_detail_data);
495 /* Close the device information handle. */
496 SetupDiDestroyDeviceInfoList(device_info_set);
502 void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
504 /* TODO: Merge this with the Linux version. This function is platform-independent. */
505 struct hid_device_info *d = devs;
507 struct hid_device_info *next = d->next;
509 free(d->serial_number);
510 free(d->manufacturer_string);
511 free(d->product_string);
518 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
520 /* TODO: Merge this functions with the Linux version. This function should be platform independent. */
521 struct hid_device_info *devs, *cur_dev;
522 const char *path_to_open = NULL;
523 hid_device *handle = NULL;
525 devs = hid_enumerate(vendor_id, product_id);
528 if (cur_dev->vendor_id == vendor_id &&
529 cur_dev->product_id == product_id) {
531 if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
532 path_to_open = cur_dev->path;
537 path_to_open = cur_dev->path;
541 cur_dev = cur_dev->next;
545 /* Open the device */
546 handle = hid_open_path(path_to_open);
549 hid_free_enumeration(devs);
554 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
558 PHIDP_PREPARSED_DATA pp_data = NULL;
562 if (hid_init() < 0) {
566 dev = new_hid_device();
568 /* Open a handle to the device */
569 dev->device_handle = open_device(path, FALSE);
571 /* Check validity of write_handle. */
572 if (dev->device_handle == INVALID_HANDLE_VALUE) {
573 /* Unable to open the device. */
574 register_error(dev, "CreateFile");
578 /* Set the Input Report buffer size to 64 reports. */
579 res = HidD_SetNumInputBuffers(dev->device_handle, 64);
581 register_error(dev, "HidD_SetNumInputBuffers");
585 /* Get the Input Report length for the device. */
586 res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
588 register_error(dev, "HidD_GetPreparsedData");
591 nt_res = HidP_GetCaps(pp_data, &caps);
592 if (nt_res != HIDP_STATUS_SUCCESS) {
593 register_error(dev, "HidP_GetCaps");
596 dev->output_report_length = caps.OutputReportByteLength;
597 dev->input_report_length = caps.InputReportByteLength;
598 HidD_FreePreparsedData(pp_data);
600 dev->read_buf = (char*) malloc(dev->input_report_length);
605 HidD_FreePreparsedData(pp_data);
607 free_hid_device(dev);
611 int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
618 memset(&ol, 0, sizeof(ol));
620 /* Make sure the right number of bytes are passed to WriteFile. Windows
621 expects the number of bytes which are in the _longest_ report (plus
622 one for the report number) bytes even if the data is a report
623 which is shorter than that. Windows gives us this value in
624 caps.OutputReportByteLength. If a user passes in fewer bytes than this,
625 create a temporary buffer which is the proper size. */
626 if (length >= dev->output_report_length) {
627 /* The user passed the right number of bytes. Use the buffer as-is. */
628 buf = (unsigned char *) data;
630 /* Create a temporary buffer and copy the user's data
631 into it, padding the rest with zeros. */
632 buf = (unsigned char *) malloc(dev->output_report_length);
633 memcpy(buf, data, length);
634 memset(buf + length, 0, dev->output_report_length - length);
635 length = dev->output_report_length;
638 res = WriteFile(dev->device_handle, buf, length, NULL, &ol);
641 if (GetLastError() != ERROR_IO_PENDING) {
642 /* WriteFile() failed. Return error. */
643 register_error(dev, "WriteFile");
645 goto end_of_function;
649 /* Wait here until the write is done. This makes
650 hid_write() synchronous. */
651 res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
653 /* The Write operation failed. */
654 register_error(dev, "WriteFile");
656 goto end_of_function;
663 return bytes_written;
667 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
669 DWORD bytes_read = 0;
673 /* Copy the handle for convenience. */
674 HANDLE ev = dev->ol.hEvent;
676 if (!dev->read_pending) {
677 /* Start an Overlapped I/O read. */
678 dev->read_pending = TRUE;
679 memset(dev->read_buf, 0, dev->input_report_length);
681 res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
684 if (GetLastError() != ERROR_IO_PENDING) {
685 /* ReadFile() has failed.
686 Clean up and return error. */
687 CancelIo(dev->device_handle);
688 dev->read_pending = FALSE;
689 goto end_of_function;
694 if (milliseconds >= 0) {
695 /* See if there is any data yet. */
696 res = WaitForSingleObject(ev, milliseconds);
697 if (res != WAIT_OBJECT_0) {
698 /* There was no data this time. Return zero bytes available,
699 but leave the Overlapped I/O running. */
704 /* Either WaitForSingleObject() told us that ReadFile has completed, or
705 we are in non-blocking mode. Get the number of bytes read. The actual
706 data has been copied to the data[] array which was passed to ReadFile(). */
707 res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
709 /* Set pending back to false, even if GetOverlappedResult() returned error. */
710 dev->read_pending = FALSE;
712 if (res && bytes_read > 0) {
713 if (dev->read_buf[0] == 0x0) {
714 /* If report numbers aren't being used, but Windows sticks a report
715 number (0x0) on the beginning of the report anyway. To make this
716 work like the other platforms, and to make it work more like the
717 HID spec, we'll skip over this byte. */
719 copy_len = length > bytes_read ? bytes_read : length;
720 memcpy(data, dev->read_buf+1, copy_len);
723 /* Copy the whole buffer, report number and all. */
724 copy_len = length > bytes_read ? bytes_read : length;
725 memcpy(data, dev->read_buf, copy_len);
731 register_error(dev, "GetOverlappedResult");
738 int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
740 return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
743 int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
745 dev->blocking = !nonblock;
746 return 0; /* Success */
749 int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
751 BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length);
753 register_error(dev, "HidD_SetFeature");
761 int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
765 res = HidD_GetFeature(dev->device_handle, data, length);
767 register_error(dev, "HidD_GetFeature");
770 return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */
772 DWORD bytes_returned;
775 memset(&ol, 0, sizeof(ol));
777 res = DeviceIoControl(dev->device_handle,
778 IOCTL_HID_GET_FEATURE,
781 &bytes_returned, &ol);
784 if (GetLastError() != ERROR_IO_PENDING) {
785 /* DeviceIoControl() failed. Return error. */
786 register_error(dev, "Send Feature Report DeviceIoControl");
791 /* Wait here until the write is done. This makes
792 hid_get_feature_report() synchronous. */
793 res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
795 /* The operation failed. */
796 register_error(dev, "Send Feature Report GetOverLappedResult");
800 /* bytes_returned does not include the first byte which contains the
801 report ID. The data buffer actually contains one more byte than
805 return bytes_returned;
809 void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
813 CancelIo(dev->device_handle);
814 free_hid_device(dev);
817 int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
821 res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
823 register_error(dev, "HidD_GetManufacturerString");
830 int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
834 res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
836 register_error(dev, "HidD_GetProductString");
843 int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
847 res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
849 register_error(dev, "HidD_GetSerialNumberString");
856 int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
860 res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
862 register_error(dev, "HidD_GetIndexedString");
870 HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
872 return (wchar_t*)dev->last_error_str;
880 unsigned short VendorID = 0xa0a0;
881 unsigned short ProductID = 0x0001;
885 unsigned short VendorID = 0x04d8;
886 unsigned short ProductID = 0x3f;
891 unsigned short VendorID = 0x04d8;
892 unsigned short ProductID = 0x0033;
897 int __cdecl main(int argc, char* argv[])
900 unsigned char buf[65];
902 UNREFERENCED_PARAMETER(argc);
903 UNREFERENCED_PARAMETER(argv);
905 /* Set up the command buffer. */
906 memset(buf,0x00,sizeof(buf));
911 /* Open the device. */
912 int handle = open(VendorID, ProductID, L"12345");
914 printf("unable to open device\n");
917 /* Toggle LED (cmd 0x80) */
919 res = write(handle, buf, 65);
921 printf("Unable to write()\n");
923 /* Request state (cmd 0x81) */
925 write(handle, buf, 65);
927 printf("Unable to write() (2)\n");
929 /* Read requested state */
930 read(handle, buf, 65);
932 printf("Unable to read()\n");
934 /* Print out the returned buffer. */
935 for (int i = 0; i < 4; i++)
936 printf("buf[%d]: %d\n", i, buf[i]);