43 #define _wcsdup wcsdup
58 #define HID_OUT_CTL_CODE(id) CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
59 #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
72 #pragma warning(disable : 4996)
79 #ifndef HIDAPI_USE_DDK
104 #define HIDP_STATUS_SUCCESS 0x110000
128 static HMODULE lib_handle = NULL;
129 static BOOLEAN initialized =
FALSE;
156 memset(&dev->
ol, 0,
sizeof(dev->
ol));
157 dev->
ol.hEvent = CreateEvent(NULL,
FALSE,
FALSE , NULL);
166 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
167 GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&msg, 0 , NULL);
188 #ifndef HIDAPI_USE_DDK
189 static int lookup_functions()
191 lib_handle = LoadLibraryA(
"hid.dll");
195 x = (x##_)GetProcAddress(lib_handle, #x); \
199 RESOLVE(HidD_GetSerialNumberString);
200 RESOLVE(HidD_GetManufacturerString);
201 RESOLVE(HidD_GetProductString);
204 RESOLVE(HidD_GetIndexedString);
205 RESOLVE(HidD_GetPreparsedData);
206 RESOLVE(HidD_FreePreparsedData);
217 static HANDLE open_device(
const char *path, BOOL enumerate)
220 DWORD desired_access = (enumerate) ? 0 : (GENERIC_WRITE | GENERIC_READ);
221 DWORD share_mode = (enumerate) ? FILE_SHARE_READ | FILE_SHARE_WRITE : FILE_SHARE_READ;
223 handle = CreateFileA(path, desired_access, share_mode, NULL, OPEN_EXISTING,
224 FILE_FLAG_OVERLAPPED,
232 #ifndef HIDAPI_USE_DDK
235 if (lookup_functions() < 0)
248 #ifndef HIDAPI_USE_DDK
250 FreeLibrary(lib_handle);
264 GUID InterfaceClassGuid = { 0x4d1e55b2, 0xf16f, 0x11cf, { 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
265 SP_DEVINFO_DATA devinfo_data;
266 SP_DEVICE_INTERFACE_DATA device_interface_data;
267 SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
268 HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
269 int device_index = 0;
276 memset(&devinfo_data, 0x0,
sizeof(devinfo_data));
277 devinfo_data.cbSize =
sizeof(SP_DEVINFO_DATA);
278 device_interface_data.cbSize =
sizeof(SP_DEVICE_INTERFACE_DATA);
281 device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
287 HANDLE write_handle = INVALID_HANDLE_VALUE;
288 DWORD required_size = 0;
291 res = SetupDiEnumDeviceInterfaces(device_info_set, NULL, &InterfaceClassGuid, device_index,
292 &device_interface_data);
304 res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, NULL, 0, &required_size, NULL);
307 device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)malloc(required_size);
308 device_interface_detail_data->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
313 res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, device_interface_detail_data,
314 required_size, NULL, NULL);
327 char driver_name[256];
331 res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
335 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_CLASS, NULL,
336 (PBYTE)driver_name,
sizeof(driver_name), NULL);
340 if (strcmp(driver_name,
"HIDClass") == 0)
343 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_DRIVER, NULL,
344 (PBYTE)driver_name,
sizeof(driver_name), NULL);
353 write_handle = open_device(device_interface_detail_data->DevicePath,
TRUE);
356 if (write_handle == INVALID_HANDLE_VALUE)
365 HidD_GetAttributes(write_handle, &attrib);
395 res = HidD_GetPreparsedData(write_handle, &pp_data);
398 nt_res = HidP_GetCaps(pp_data, &caps);
405 HidD_FreePreparsedData(pp_data);
409 cur_dev->
next = NULL;
410 str = device_interface_detail_data->DevicePath;
414 cur_dev->
path = (
char *)calloc(len + 1,
sizeof(
char));
415 strncpy(cur_dev->
path, str, len + 1);
416 cur_dev->
path[len] =
'\0';
419 cur_dev->
path = NULL;
422 res = HidD_GetSerialNumberString(write_handle, wstr,
sizeof(wstr));
430 res = HidD_GetManufacturerString(write_handle, wstr,
sizeof(wstr));
438 res = HidD_GetProductString(write_handle, wstr,
sizeof(wstr));
460 char *interface_component = strstr(cur_dev->
path,
"&mi_");
461 if (interface_component)
463 char *hex_str = interface_component + 4;
466 if (endptr == hex_str)
476 CloseHandle(write_handle);
479 free(device_interface_detail_data);
485 SetupDiDestroyDeviceInfoList(device_info_set);
511 const char *path_to_open = NULL;
524 path_to_open = cur_dev->
path;
530 path_to_open = cur_dev->
path;
534 cur_dev = cur_dev->
next;
561 dev = new_hid_device();
570 register_error(dev,
"CreateFile");
578 register_error(dev,
"HidD_GetPreparsedData");
581 nt_res = HidP_GetCaps(pp_data, &caps);
584 register_error(dev,
"HidP_GetCaps");
589 HidD_FreePreparsedData(pp_data);
596 HidD_FreePreparsedData(pp_data);
610 memset(&ol, 0,
sizeof(ol));
621 buf = (
unsigned char *)data;
628 memcpy(buf, data, length);
637 if (GetLastError() != ERROR_IO_PENDING)
640 register_error(dev,
"WriteFile");
642 goto end_of_function;
652 register_error(dev,
"WriteFile");
654 goto end_of_function;
661 return bytes_written;
666 DWORD bytes_read = 0;
670 HANDLE ev = dev->
ol.hEvent;
682 if (GetLastError() != ERROR_IO_PENDING)
688 goto end_of_function;
693 if (milliseconds >= 0)
696 res = WaitForSingleObject(ev, milliseconds);
697 if (res != WAIT_OBJECT_0)
713 if (res && bytes_read > 0)
723 copy_len = length > bytes_read ? bytes_read : length;
724 memcpy(data, dev->
read_buf + 1, copy_len);
729 size_t copy_len = length > bytes_read ? bytes_read : length;
730 memcpy(data, dev->
read_buf, copy_len);
737 register_error(dev,
"GetOverlappedResult");
757 BOOL res = HidD_SetFeature(dev->
device_handle, (PVOID)data, length);
760 register_error(dev,
"HidD_SetFeature");
774 register_error(dev,
"HidD_GetFeature");
779 DWORD bytes_returned;
782 memset(&ol, 0,
sizeof(ol));
788 if (GetLastError() != ERROR_IO_PENDING)
791 register_error(dev,
"Send Feature Report DeviceIoControl");
802 register_error(dev,
"Send Feature Report GetOverLappedResult");
805 return bytes_returned;
814 CloseHandle(dev->
ol.hEvent);
825 res = HidD_GetManufacturerString(dev->
device_handle,
string, 2 * maxlen);
828 register_error(dev,
"HidD_GetManufacturerString");
839 res = HidD_GetProductString(dev->
device_handle,
string, 2 * maxlen);
842 register_error(dev,
"HidD_GetProductString");
853 res = HidD_GetSerialNumberString(dev->
device_handle,
string, 2 * maxlen);
856 register_error(dev,
"HidD_GetSerialNumberString");
868 res = HidD_GetIndexedString(dev->
device_handle, string_index,
string, 2 * maxlen);
871 register_error(dev,
"HidD_GetIndexedString");
902 int __cdecl
main(
int argc,
char * argv[])
905 unsigned char buf[65];
907 UNREFERENCED_PARAMETER(argc);
908 UNREFERENCED_PARAMETER(argv);
911 memset(buf,0x00,
sizeof(buf));
919 printf(
"unable to open device\n");
924 res = write(handle, buf, 65);
926 printf(
"Unable to write()\n");
930 write(handle, buf, 65);
932 printf(
"Unable to write() (2)\n");
935 read(handle, buf, 65);
937 printf(
"Unable to read()\n");
940 for (
int i = 0; i < 4; i++)
941 printf(
"buf[%d]: %d\n", i, buf[i]);
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
Read an Input report from a HID device.
HID_API_EXPORT hid_device *HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally a serial number.
BOOLEAN(__stdcall * HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len)
int HID_API_EXPORT hid_init(void)
Initialize the HIDAPI library.
#define HIDP_STATUS_SUCCESS
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
Set the device handle to be non-blocking.
struct _HIDP_CAPS HIDP_CAPS
struct hid_device_info HID_API_EXPORT *HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
Enumerate the HID Devices.
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path)
Open a HID device by its path name.
BOOLEAN(__stdcall * HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len)
BOOLEAN(__stdcall * HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len)
BOOLEAN(__stdcall * HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length)
int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Product String from a HID device.
struct _HIDD_ATTRIBUTES * PHIDD_ATTRIBUTES
BOOLEAN(__stdcall * HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data)
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
Close a HID device.
int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Serial Number String from a HID device.
int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
Get a string from a HID device, based on its string index.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
Get a feature report from a HID device.
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
Write an Output report to a HID device.
void * PHIDP_PREPARSED_DATA
int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Manufacturer String from a HID device.
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error(hid_device *dev)
Get a string describing the last error which occurred.
NTSTATUS(__stdcall * HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps)
int HID_API_EXPORT hid_exit(void)
Finalize the HIDAPI library.
BOOLEAN(__stdcall * HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib)
BOOLEAN(__stdcall * HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len)
struct _HIDD_ATTRIBUTES HIDD_ATTRIBUTES
struct _HIDP_CAPS * PHIDP_CAPS
#define IOCTL_HID_GET_FEATURE
BOOLEAN(__stdcall * HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length)
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
Send a Feature report to the device.
BOOLEAN(__stdcall * HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data)
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
Free an enumeration Linked List.
#define HID_API_EXPORT_CALL
std::vector< uint8_t > buffer
USHORT FeatureReportByteLength
USHORT fields_not_used_by_hidapi[10]
USHORT OutputReportByteLength
USHORT InputReportByteLength
size_t input_report_length
libusb_device_handle * device_handle
USHORT output_report_length
unsigned short product_id
struct hid_device_info * next
wchar_t * manufacturer_string
unsigned short release_number
unsigned short usage_page