rb-blink1 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/blink1/blink1-lib.c +106 -74
- data/ext/blink1/blink1-lib.h +9 -7
- data/ext/blink1/blink1.c +15 -0
- data/ext/blink1/hid.c.libusb +108 -109
- data/ext/blink1/hid.c.mac +115 -160
- data/ext/blink1/hid.c.windows +115 -112
- data/ext/blink1/hidapi.h +3 -2
- data/ext/blink1/osccal.h +7 -7
- data/ext/blink1/usbconfig.h +3 -3
- data/lib/blink1.rb +5 -5
- data/lib/blink1/version.rb +1 -1
- data/spec/blink1_spec.rb +11 -3
- data/spec/spec_helper.rb +7 -1
- metadata +2 -2
data/ext/blink1/hid.c.windows
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
8/22/2009
|
9
9
|
|
10
10
|
Copyright 2009, All Rights Reserved.
|
11
|
-
|
11
|
+
|
12
12
|
At the discretion of the user of this library,
|
13
13
|
this software may be licensed under the terms of the
|
14
14
|
GNU Public License v3, a BSD-Style license, or the
|
@@ -36,7 +36,7 @@ typedef LONG NTSTATUS;
|
|
36
36
|
#define _wcsdup wcsdup
|
37
37
|
#endif
|
38
38
|
|
39
|
-
|
39
|
+
/*#define HIDAPI_USE_DDK*/
|
40
40
|
|
41
41
|
#ifdef __cplusplus
|
42
42
|
extern "C" {
|
@@ -47,13 +47,13 @@ extern "C" {
|
|
47
47
|
#include <hidsdi.h>
|
48
48
|
#endif
|
49
49
|
|
50
|
-
|
50
|
+
/* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
|
51
51
|
#define HID_OUT_CTL_CODE(id) \
|
52
52
|
CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
53
53
|
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
|
54
54
|
|
55
55
|
#ifdef __cplusplus
|
56
|
-
}
|
56
|
+
} /* extern "C" */
|
57
57
|
#endif
|
58
58
|
|
59
59
|
#include <stdio.h>
|
@@ -63,7 +63,7 @@ extern "C" {
|
|
63
63
|
#include "hidapi.h"
|
64
64
|
|
65
65
|
#ifdef _MSC_VER
|
66
|
-
|
66
|
+
/* Thanks Microsoft, but I know how to use strncpy(). */
|
67
67
|
#pragma warning(disable:4996)
|
68
68
|
#endif
|
69
69
|
|
@@ -72,10 +72,10 @@ extern "C" {
|
|
72
72
|
#endif
|
73
73
|
|
74
74
|
#ifndef HIDAPI_USE_DDK
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
/* Since we're not building with the DDK, and the HID header
|
76
|
+
files aren't part of the SDK, we have to define all this
|
77
|
+
stuff here. In lookup_functions(), the function pointers
|
78
|
+
defined below are set. */
|
79
79
|
typedef struct _HIDD_ATTRIBUTES{
|
80
80
|
ULONG Size;
|
81
81
|
USHORT VendorID;
|
@@ -120,7 +120,7 @@ extern "C" {
|
|
120
120
|
|
121
121
|
static HMODULE lib_handle = NULL;
|
122
122
|
static BOOLEAN initialized = FALSE;
|
123
|
-
#endif
|
123
|
+
#endif /* HIDAPI_USE_DDK */
|
124
124
|
|
125
125
|
struct hid_device_ {
|
126
126
|
HANDLE device_handle;
|
@@ -151,6 +151,14 @@ static hid_device *new_hid_device()
|
|
151
151
|
return dev;
|
152
152
|
}
|
153
153
|
|
154
|
+
static void free_hid_device(hid_device *dev)
|
155
|
+
{
|
156
|
+
CloseHandle(dev->ol.hEvent);
|
157
|
+
CloseHandle(dev->device_handle);
|
158
|
+
LocalFree(dev->last_error_str);
|
159
|
+
free(dev->read_buf);
|
160
|
+
free(dev);
|
161
|
+
}
|
154
162
|
|
155
163
|
static void register_error(hid_device *device, const char *op)
|
156
164
|
{
|
@@ -162,11 +170,11 @@ static void register_error(hid_device *device, const char *op)
|
|
162
170
|
NULL,
|
163
171
|
GetLastError(),
|
164
172
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
165
|
-
(
|
173
|
+
(LPVOID)&msg, 0/*sz*/,
|
166
174
|
NULL);
|
167
|
-
|
168
|
-
|
169
|
-
|
175
|
+
|
176
|
+
/* Get rid of the CR and LF that FormatMessage() sticks at the
|
177
|
+
end of the message. Thanks Microsoft! */
|
170
178
|
ptr = msg;
|
171
179
|
while (*ptr) {
|
172
180
|
if (*ptr == '\r') {
|
@@ -176,8 +184,8 @@ static void register_error(hid_device *device, const char *op)
|
|
176
184
|
ptr++;
|
177
185
|
}
|
178
186
|
|
179
|
-
|
180
|
-
|
187
|
+
/* Store the message off in the Device entry so that
|
188
|
+
the hid_error() function can pick it up. */
|
181
189
|
LocalFree(device->last_error_str);
|
182
190
|
device->last_error_str = msg;
|
183
191
|
}
|
@@ -220,7 +228,7 @@ static HANDLE open_device(const char *path, BOOL enumerate)
|
|
220
228
|
share_mode,
|
221
229
|
NULL,
|
222
230
|
OPEN_EXISTING,
|
223
|
-
FILE_FLAG_OVERLAPPED
|
231
|
+
FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
|
224
232
|
0);
|
225
233
|
|
226
234
|
return handle;
|
@@ -254,10 +262,10 @@ int HID_API_EXPORT hid_exit(void)
|
|
254
262
|
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
|
255
263
|
{
|
256
264
|
BOOL res;
|
257
|
-
struct hid_device_info *root = NULL;
|
265
|
+
struct hid_device_info *root = NULL; /* return object */
|
258
266
|
struct hid_device_info *cur_dev = NULL;
|
259
267
|
|
260
|
-
|
268
|
+
/* Windows objects for interacting with the driver. */
|
261
269
|
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
|
262
270
|
SP_DEVINFO_DATA devinfo_data;
|
263
271
|
SP_DEVICE_INTERFACE_DATA device_interface_data;
|
@@ -269,16 +277,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
269
277
|
if (hid_init() < 0)
|
270
278
|
return NULL;
|
271
279
|
|
272
|
-
|
280
|
+
/* Initialize the Windows objects. */
|
273
281
|
memset(&devinfo_data, 0x0, sizeof(devinfo_data));
|
274
282
|
devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
|
275
283
|
device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
276
284
|
|
277
|
-
|
285
|
+
/* Get information for all the devices belonging to the HID class. */
|
278
286
|
device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
279
|
-
|
280
|
-
|
281
|
-
|
287
|
+
|
288
|
+
/* Iterate over each device in the HID class, looking for the right one. */
|
289
|
+
|
282
290
|
for (;;) {
|
283
291
|
HANDLE write_handle = INVALID_HANDLE_VALUE;
|
284
292
|
DWORD required_size = 0;
|
@@ -289,16 +297,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
289
297
|
&InterfaceClassGuid,
|
290
298
|
device_index,
|
291
299
|
&device_interface_data);
|
292
|
-
|
300
|
+
|
293
301
|
if (!res) {
|
294
|
-
|
295
|
-
|
302
|
+
/* A return of FALSE from this function means that
|
303
|
+
there are no more devices. */
|
296
304
|
break;
|
297
305
|
}
|
298
306
|
|
299
|
-
|
300
|
-
|
301
|
-
|
307
|
+
/* Call with 0-sized detail size, and let the function
|
308
|
+
tell us how long the detail struct needs to be. The
|
309
|
+
size is put in &required_size. */
|
302
310
|
res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
|
303
311
|
&device_interface_data,
|
304
312
|
NULL,
|
@@ -306,13 +314,13 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
306
314
|
&required_size,
|
307
315
|
NULL);
|
308
316
|
|
309
|
-
|
317
|
+
/* Allocate a long enough structure for device_interface_detail_data. */
|
310
318
|
device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
|
311
319
|
device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
|
312
320
|
|
313
|
-
|
314
|
-
|
315
|
-
|
321
|
+
/* Get the detailed data for this device. The detail data gives us
|
322
|
+
the device path for this device, which is then passed into
|
323
|
+
CreateFile() to get a handle to the device. */
|
316
324
|
res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
|
317
325
|
&device_interface_data,
|
318
326
|
device_interface_detail_data,
|
@@ -321,18 +329,18 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
321
329
|
NULL);
|
322
330
|
|
323
331
|
if (!res) {
|
324
|
-
|
325
|
-
|
332
|
+
/* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
|
333
|
+
Continue to the next device. */
|
326
334
|
goto cont;
|
327
335
|
}
|
328
336
|
|
329
|
-
|
330
|
-
|
337
|
+
/* Make sure this device is of Setup Class "HIDClass" and has a
|
338
|
+
driver bound to it. */
|
331
339
|
for (i = 0; ; i++) {
|
332
340
|
char driver_name[256];
|
333
341
|
|
334
|
-
|
335
|
-
|
342
|
+
/* Populate devinfo_data. This function will return failure
|
343
|
+
when there are no more interfaces left. */
|
336
344
|
res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
|
337
345
|
if (!res)
|
338
346
|
goto cont;
|
@@ -343,7 +351,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
343
351
|
goto cont;
|
344
352
|
|
345
353
|
if (strcmp(driver_name, "HIDClass") == 0) {
|
346
|
-
|
354
|
+
/* See if there's a driver bound. */
|
347
355
|
res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
|
348
356
|
SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
|
349
357
|
if (res)
|
@@ -353,26 +361,26 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
353
361
|
|
354
362
|
//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
|
355
363
|
|
356
|
-
|
364
|
+
/* Open a handle to the device */
|
357
365
|
write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);
|
358
366
|
|
359
|
-
|
367
|
+
/* Check validity of write_handle. */
|
360
368
|
if (write_handle == INVALID_HANDLE_VALUE) {
|
361
|
-
|
369
|
+
/* Unable to open the device. */
|
362
370
|
//register_error(dev, "CreateFile");
|
363
371
|
goto cont_close;
|
364
|
-
}
|
372
|
+
}
|
365
373
|
|
366
374
|
|
367
|
-
|
375
|
+
/* Get the Vendor ID and Product ID for this device. */
|
368
376
|
attrib.Size = sizeof(HIDD_ATTRIBUTES);
|
369
377
|
HidD_GetAttributes(write_handle, &attrib);
|
370
378
|
//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
|
371
379
|
|
372
|
-
|
373
|
-
|
374
|
-
if ((vendor_id == 0x0
|
375
|
-
|
380
|
+
/* Check the VID/PID to see if we should add this
|
381
|
+
device to the enumeration list. */
|
382
|
+
if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
|
383
|
+
(product_id == 0x0 || attrib.ProductID == product_id)) {
|
376
384
|
|
377
385
|
#define WSTR_LEN 512
|
378
386
|
const char *str;
|
@@ -381,7 +389,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
381
389
|
HIDP_CAPS caps;
|
382
390
|
BOOLEAN res;
|
383
391
|
NTSTATUS nt_res;
|
384
|
-
wchar_t wstr[WSTR_LEN];
|
392
|
+
wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
|
385
393
|
size_t len;
|
386
394
|
|
387
395
|
/* VID/PID match. Create the record. */
|
@@ -394,7 +402,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
394
402
|
}
|
395
403
|
cur_dev = tmp;
|
396
404
|
|
397
|
-
|
405
|
+
/* Get the Usage Page and Usage for this device. */
|
398
406
|
res = HidD_GetPreparsedData(write_handle, &pp_data);
|
399
407
|
if (res) {
|
400
408
|
nt_res = HidP_GetCaps(pp_data, &caps);
|
@@ -405,7 +413,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
405
413
|
|
406
414
|
HidD_FreePreparsedData(pp_data);
|
407
415
|
}
|
408
|
-
|
416
|
+
|
409
417
|
/* Fill out the record */
|
410
418
|
cur_dev->next = NULL;
|
411
419
|
str = device_interface_detail_data->DevicePath;
|
@@ -469,14 +477,14 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|
469
477
|
cont_close:
|
470
478
|
CloseHandle(write_handle);
|
471
479
|
cont:
|
472
|
-
|
480
|
+
/* We no longer need the detail data. It can be freed */
|
473
481
|
free(device_interface_detail_data);
|
474
482
|
|
475
483
|
device_index++;
|
476
484
|
|
477
485
|
}
|
478
486
|
|
479
|
-
|
487
|
+
/* Close the device information handle. */
|
480
488
|
SetupDiDestroyDeviceInfoList(device_info_set);
|
481
489
|
|
482
490
|
return root;
|
@@ -485,7 +493,7 @@ cont:
|
|
485
493
|
|
486
494
|
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
|
487
495
|
{
|
488
|
-
|
496
|
+
/* TODO: Merge this with the Linux version. This function is platform-independent. */
|
489
497
|
struct hid_device_info *d = devs;
|
490
498
|
while (d) {
|
491
499
|
struct hid_device_info *next = d->next;
|
@@ -501,11 +509,11 @@ void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *d
|
|
501
509
|
|
502
510
|
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
|
503
511
|
{
|
504
|
-
|
512
|
+
/* TODO: Merge this functions with the Linux version. This function should be platform independent. */
|
505
513
|
struct hid_device_info *devs, *cur_dev;
|
506
514
|
const char *path_to_open = NULL;
|
507
515
|
hid_device *handle = NULL;
|
508
|
-
|
516
|
+
|
509
517
|
devs = hid_enumerate(vendor_id, product_id);
|
510
518
|
cur_dev = devs;
|
511
519
|
while (cur_dev) {
|
@@ -531,7 +539,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
|
|
531
539
|
}
|
532
540
|
|
533
541
|
hid_free_enumeration(devs);
|
534
|
-
|
542
|
+
|
535
543
|
return handle;
|
536
544
|
}
|
537
545
|
|
@@ -549,17 +557,17 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
|
|
549
557
|
|
550
558
|
dev = new_hid_device();
|
551
559
|
|
552
|
-
|
560
|
+
/* Open a handle to the device */
|
553
561
|
dev->device_handle = open_device(path, FALSE);
|
554
562
|
|
555
|
-
|
563
|
+
/* Check validity of write_handle. */
|
556
564
|
if (dev->device_handle == INVALID_HANDLE_VALUE) {
|
557
|
-
|
565
|
+
/* Unable to open the device. */
|
558
566
|
register_error(dev, "CreateFile");
|
559
567
|
goto err;
|
560
568
|
}
|
561
569
|
|
562
|
-
|
570
|
+
/* Get the Input Report length for the device. */
|
563
571
|
res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
|
564
572
|
if (!res) {
|
565
573
|
register_error(dev, "HidD_GetPreparsedData");
|
@@ -567,7 +575,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
|
|
567
575
|
}
|
568
576
|
nt_res = HidP_GetCaps(pp_data, &caps);
|
569
577
|
if (nt_res != HIDP_STATUS_SUCCESS) {
|
570
|
-
register_error(dev, "HidP_GetCaps");
|
578
|
+
register_error(dev, "HidP_GetCaps");
|
571
579
|
goto err_pp_data;
|
572
580
|
}
|
573
581
|
dev->output_report_length = caps.OutputReportByteLength;
|
@@ -580,9 +588,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
|
|
580
588
|
|
581
589
|
err_pp_data:
|
582
590
|
HidD_FreePreparsedData(pp_data);
|
583
|
-
err:
|
584
|
-
|
585
|
-
free(dev);
|
591
|
+
err:
|
592
|
+
free_hid_device(dev);
|
586
593
|
return NULL;
|
587
594
|
}
|
588
595
|
|
@@ -614,21 +621,21 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
|
|
614
621
|
}
|
615
622
|
|
616
623
|
res = WriteFile(dev->device_handle, buf, length, NULL, &ol);
|
617
|
-
|
624
|
+
|
618
625
|
if (!res) {
|
619
626
|
if (GetLastError() != ERROR_IO_PENDING) {
|
620
|
-
|
627
|
+
/* WriteFile() failed. Return error. */
|
621
628
|
register_error(dev, "WriteFile");
|
622
629
|
bytes_written = -1;
|
623
630
|
goto end_of_function;
|
624
631
|
}
|
625
632
|
}
|
626
633
|
|
627
|
-
|
628
|
-
|
634
|
+
/* Wait here until the write is done. This makes
|
635
|
+
hid_write() synchronous. */
|
629
636
|
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
|
630
637
|
if (!res) {
|
631
|
-
|
638
|
+
/* The Write operation failed. */
|
632
639
|
register_error(dev, "WriteFile");
|
633
640
|
bytes_written = -1;
|
634
641
|
goto end_of_function;
|
@@ -647,20 +654,20 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
|
|
647
654
|
DWORD bytes_read = 0;
|
648
655
|
BOOL res;
|
649
656
|
|
650
|
-
|
657
|
+
/* Copy the handle for convenience. */
|
651
658
|
HANDLE ev = dev->ol.hEvent;
|
652
659
|
|
653
660
|
if (!dev->read_pending) {
|
654
|
-
|
661
|
+
/* Start an Overlapped I/O read. */
|
655
662
|
dev->read_pending = TRUE;
|
656
663
|
memset(dev->read_buf, 0, dev->input_report_length);
|
657
664
|
ResetEvent(ev);
|
658
665
|
res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
|
659
|
-
|
666
|
+
|
660
667
|
if (!res) {
|
661
668
|
if (GetLastError() != ERROR_IO_PENDING) {
|
662
|
-
|
663
|
-
|
669
|
+
/* ReadFile() has failed.
|
670
|
+
Clean up and return error. */
|
664
671
|
CancelIo(dev->device_handle);
|
665
672
|
dev->read_pending = FALSE;
|
666
673
|
goto end_of_function;
|
@@ -669,21 +676,21 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
|
|
669
676
|
}
|
670
677
|
|
671
678
|
if (milliseconds >= 0) {
|
672
|
-
|
679
|
+
/* See if there is any data yet. */
|
673
680
|
res = WaitForSingleObject(ev, milliseconds);
|
674
681
|
if (res != WAIT_OBJECT_0) {
|
675
|
-
|
676
|
-
|
682
|
+
/* There was no data this time. Return zero bytes available,
|
683
|
+
but leave the Overlapped I/O running. */
|
677
684
|
return 0;
|
678
685
|
}
|
679
686
|
}
|
680
687
|
|
681
|
-
|
682
|
-
|
683
|
-
|
688
|
+
/* Either WaitForSingleObject() told us that ReadFile has completed, or
|
689
|
+
we are in non-blocking mode. Get the number of bytes read. The actual
|
690
|
+
data has been copied to the data[] array which was passed to ReadFile(). */
|
684
691
|
res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
|
685
|
-
|
686
|
-
|
692
|
+
|
693
|
+
/* Set pending back to false, even if GetOverlappedResult() returned error. */
|
687
694
|
dev->read_pending = FALSE;
|
688
695
|
|
689
696
|
if (res && bytes_read > 0) {
|
@@ -703,13 +710,13 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
|
|
703
710
|
memcpy(data, dev->read_buf, copy_len);
|
704
711
|
}
|
705
712
|
}
|
706
|
-
|
713
|
+
|
707
714
|
end_of_function:
|
708
715
|
if (!res) {
|
709
716
|
register_error(dev, "GetOverlappedResult");
|
710
717
|
return -1;
|
711
718
|
}
|
712
|
-
|
719
|
+
|
713
720
|
return bytes_read;
|
714
721
|
}
|
715
722
|
|
@@ -760,17 +767,17 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned
|
|
760
767
|
|
761
768
|
if (!res) {
|
762
769
|
if (GetLastError() != ERROR_IO_PENDING) {
|
763
|
-
|
770
|
+
/* DeviceIoControl() failed. Return error. */
|
764
771
|
register_error(dev, "Send Feature Report DeviceIoControl");
|
765
772
|
return -1;
|
766
773
|
}
|
767
774
|
}
|
768
775
|
|
769
|
-
|
770
|
-
|
776
|
+
/* Wait here until the write is done. This makes
|
777
|
+
hid_get_feature_report() synchronous. */
|
771
778
|
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
|
772
779
|
if (!res) {
|
773
|
-
|
780
|
+
/* The operation failed. */
|
774
781
|
register_error(dev, "Send Feature Report GetOverLappedResult");
|
775
782
|
return -1;
|
776
783
|
}
|
@@ -783,18 +790,14 @@ void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
|
|
783
790
|
if (!dev)
|
784
791
|
return;
|
785
792
|
CancelIo(dev->device_handle);
|
786
|
-
|
787
|
-
CloseHandle(dev->device_handle);
|
788
|
-
LocalFree(dev->last_error_str);
|
789
|
-
free(dev->read_buf);
|
790
|
-
free(dev);
|
793
|
+
free_hid_device(dev);
|
791
794
|
}
|
792
795
|
|
793
796
|
int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
|
794
797
|
{
|
795
798
|
BOOL res;
|
796
799
|
|
797
|
-
res = HidD_GetManufacturerString(dev->device_handle, string,
|
800
|
+
res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * maxlen);
|
798
801
|
if (!res) {
|
799
802
|
register_error(dev, "HidD_GetManufacturerString");
|
800
803
|
return -1;
|
@@ -807,7 +810,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wch
|
|
807
810
|
{
|
808
811
|
BOOL res;
|
809
812
|
|
810
|
-
res = HidD_GetProductString(dev->device_handle, string,
|
813
|
+
res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * maxlen);
|
811
814
|
if (!res) {
|
812
815
|
register_error(dev, "HidD_GetProductString");
|
813
816
|
return -1;
|
@@ -820,7 +823,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *de
|
|
820
823
|
{
|
821
824
|
BOOL res;
|
822
825
|
|
823
|
-
res = HidD_GetSerialNumberString(dev->device_handle, string,
|
826
|
+
res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * maxlen);
|
824
827
|
if (!res) {
|
825
828
|
register_error(dev, "HidD_GetSerialNumberString");
|
826
829
|
return -1;
|
@@ -833,7 +836,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
|
|
833
836
|
{
|
834
837
|
BOOL res;
|
835
838
|
|
836
|
-
res = HidD_GetIndexedString(dev->device_handle, string_index, string,
|
839
|
+
res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * maxlen);
|
837
840
|
if (!res) {
|
838
841
|
register_error(dev, "HidD_GetIndexedString");
|
839
842
|
return -1;
|
@@ -849,10 +852,10 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
|
849
852
|
}
|
850
853
|
|
851
854
|
|
852
|
-
|
853
|
-
|
855
|
+
/*#define PICPGM*/
|
856
|
+
/*#define S11*/
|
854
857
|
#define P32
|
855
|
-
#ifdef S11
|
858
|
+
#ifdef S11
|
856
859
|
unsigned short VendorID = 0xa0a0;
|
857
860
|
unsigned short ProductID = 0x0001;
|
858
861
|
#endif
|
@@ -878,36 +881,36 @@ int __cdecl main(int argc, char* argv[])
|
|
878
881
|
UNREFERENCED_PARAMETER(argc);
|
879
882
|
UNREFERENCED_PARAMETER(argv);
|
880
883
|
|
881
|
-
|
884
|
+
/* Set up the command buffer. */
|
882
885
|
memset(buf,0x00,sizeof(buf));
|
883
886
|
buf[0] = 0;
|
884
887
|
buf[1] = 0x81;
|
885
|
-
|
886
888
|
|
887
|
-
|
889
|
+
|
890
|
+
/* Open the device. */
|
888
891
|
int handle = open(VendorID, ProductID, L"12345");
|
889
892
|
if (handle < 0)
|
890
893
|
printf("unable to open device\n");
|
891
894
|
|
892
895
|
|
893
|
-
|
896
|
+
/* Toggle LED (cmd 0x80) */
|
894
897
|
buf[1] = 0x80;
|
895
898
|
res = write(handle, buf, 65);
|
896
899
|
if (res < 0)
|
897
900
|
printf("Unable to write()\n");
|
898
901
|
|
899
|
-
|
902
|
+
/* Request state (cmd 0x81) */
|
900
903
|
buf[1] = 0x81;
|
901
904
|
write(handle, buf, 65);
|
902
905
|
if (res < 0)
|
903
906
|
printf("Unable to write() (2)\n");
|
904
907
|
|
905
|
-
|
908
|
+
/* Read requested state */
|
906
909
|
read(handle, buf, 65);
|
907
910
|
if (res < 0)
|
908
911
|
printf("Unable to read()\n");
|
909
912
|
|
910
|
-
|
913
|
+
/* Print out the returned buffer. */
|
911
914
|
for (int i = 0; i < 4; i++)
|
912
915
|
printf("buf[%d]: %d\n", i, buf[i]);
|
913
916
|
|
@@ -916,5 +919,5 @@ int __cdecl main(int argc, char* argv[])
|
|
916
919
|
#endif
|
917
920
|
|
918
921
|
#ifdef __cplusplus
|
919
|
-
}
|
920
|
-
#endif
|
922
|
+
} /* extern "C" */
|
923
|
+
#endif
|