Subversion Repositories seema-scanner

Rev

Details | Last modification | View Log | RSS feed

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