?? hiddata.c
字號:
/* Name: hiddata.c * Author: Christian Starkjohann * Creation Date: 2008-04-11 * Tabsize: 4 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) * This Revision: $Id: hiddata.c 692 2008-11-07 15:07:40Z cs $ */#include <stdio.h>#include "hiddata.h"/* ######################################################################## */#if defined(WIN32) /* ##################################################### *//* ######################################################################## */#include <windows.h>#include <setupapi.h>#include "hidsdi.h"#include <ddk/hidpi.h>#ifdef DEBUG#define DEBUG_PRINT(arg) printf arg#else#define DEBUG_PRINT(arg)#endif/* ------------------------------------------------------------------------ */static void convertUniToAscii(char *buffer){unsigned short *uni = (void *)buffer;char *ascii = buffer; while(*uni != 0){ if(*uni >= 256){ *ascii++ = '?'; }else{ *ascii++ = *uni++; } } *ascii++ = 0;}int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs){GUID hidGuid; /* GUID for HID driver */HDEVINFO deviceInfoList;SP_DEVICE_INTERFACE_DATA deviceInfo;SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;DWORD size;int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */int errorCode = USBOPEN_ERR_NOTFOUND;HANDLE handle = INVALID_HANDLE_VALUE;HIDD_ATTRIBUTES deviceAttributes; HidD_GetHidGuid(&hidGuid); deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); deviceInfo.cbSize = sizeof(deviceInfo); for(i=0;;i++){ if(handle != INVALID_HANDLE_VALUE){ CloseHandle(handle); handle = INVALID_HANDLE_VALUE; } if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo)) break; /* no more entries */ /* first do a dummy call just to determine the actual size required */ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); if(deviceDetails != NULL) free(deviceDetails); deviceDetails = malloc(size); deviceDetails->cbSize = sizeof(*deviceDetails); /* this call is for real: */ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath)); /* attempt opening for R/W -- we don't care about devices which can't be accessed */ handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); if(handle == INVALID_HANDLE_VALUE){ DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError())); /* errorCode = USBOPEN_ERR_ACCESS; opening will always fail for mouse -- ignore */ continue; } deviceAttributes.Size = sizeof(deviceAttributes); HidD_GetAttributes(handle, &deviceAttributes); DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID)); if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product) continue; /* ignore this device */ errorCode = USBOPEN_ERR_NOTFOUND; if(vendorName != NULL && productName != NULL){ char buffer[512]; if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ DEBUG_PRINT(("error obtaining vendor name\n")); errorCode = USBOPEN_ERR_IO; continue; } convertUniToAscii(buffer); DEBUG_PRINT(("vendorName = \"%s\"\n", buffer)); if(strcmp(vendorName, buffer) != 0) continue; if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){ DEBUG_PRINT(("error obtaining product name\n")); errorCode = USBOPEN_ERR_IO; continue; } convertUniToAscii(buffer); DEBUG_PRINT(("productName = \"%s\"\n", buffer)); if(strcmp(productName, buffer) != 0) continue; } break; /* we have found the device we are looking for! */ } SetupDiDestroyDeviceInfoList(deviceInfoList); if(deviceDetails != NULL) free(deviceDetails); if(handle != INVALID_HANDLE_VALUE){ *device = (usbDevice_t *)handle; errorCode = 0; } return errorCode;}/* ------------------------------------------------------------------------ */void usbhidCloseDevice(usbDevice_t *device){ CloseHandle((HANDLE)device);}/* ------------------------------------------------------------------------ */int usbhidSetReport(usbDevice_t *device, char *buffer, int len){BOOLEAN rval; rval = HidD_SetFeature((HANDLE)device, buffer, len); return rval == 0 ? USBOPEN_ERR_IO : 0;}/* ------------------------------------------------------------------------ */int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len){BOOLEAN rval = 0; buffer[0] = reportNumber; rval = HidD_GetFeature((HANDLE)device, buffer, *len); return rval == 0 ? USBOPEN_ERR_IO : 0;}/* ------------------------------------------------------------------------ *//* ######################################################################## */#else /* defined WIN32 #################################################### *//* ######################################################################## */#include <string.h>#include <usb.h>#define usbDevice usb_dev_handle /* use libusb's device structure *//* ------------------------------------------------------------------------- */#define USBRQ_HID_GET_REPORT 0x01#define USBRQ_HID_SET_REPORT 0x09#define USB_HID_REPORT_TYPE_FEATURE 3static int usesReportIDs;/* ------------------------------------------------------------------------- */static int usbhidGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen){char buffer[256];int rval, i; if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ return rval; if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) return rval; if(buffer[1] != USB_DT_STRING){ *buf = 0; return 0; } if((unsigned char)buffer[0] < rval) rval = (unsigned char)buffer[0]; rval /= 2; /* lossy conversion to ISO Latin1: */ for(i=1;i<rval;i++){ if(i > buflen) /* destination buffer overflow */ break; buf[i-1] = buffer[2 * i]; if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ buf[i-1] = '?'; } buf[i-1] = 0; return i-1;}int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs){struct usb_bus *bus;struct usb_device *dev;usb_dev_handle *handle = NULL;int errorCode = USBOPEN_ERR_NOTFOUND;static int didUsbInit = 0; if(!didUsbInit){ usb_init(); didUsbInit = 1; } usb_find_busses(); usb_find_devices(); for(bus=usb_get_busses(); bus; bus=bus->next){ for(dev=bus->devices; dev; dev=dev->next){ if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){ char string[256]; int len; handle = usb_open(dev); /* we need to open the device in order to query strings */ if(!handle){ errorCode = USBOPEN_ERR_ACCESS; fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); continue; } if(vendorName == NULL && productName == NULL){ /* name does not matter */ break; } /* now check whether the names match: */ len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string)); if(len < 0){ errorCode = USBOPEN_ERR_IO; fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ if(strcmp(string, vendorName) == 0){ len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string)); if(len < 0){ errorCode = USBOPEN_ERR_IO; fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* fprintf(stderr, "seen product ->%s<-\n", string); */ if(strcmp(string, productName) == 0) break; } } } usb_close(handle); handle = NULL; } } if(handle) break; } if(handle != NULL){ errorCode = 0; *device = (void *)handle; usesReportIDs = _usesReportIDs; } return errorCode;}/* ------------------------------------------------------------------------- */void usbhidCloseDevice(usbDevice_t *device){ if(device != NULL) usb_close((void *)device);}/* ------------------------------------------------------------------------- */int usbhidSetReport(usbDevice_t *device, char *buffer, int len){int bytesSent; if(!usesReportIDs){ buffer++; /* skip dummy report ID */ len--; } bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (buffer[0] & 0xff), 0, buffer, len, 5000); if(bytesSent != len){ if(bytesSent < 0) fprintf(stderr, "Error sending message: %s\n", usb_strerror()); return USBOPEN_ERR_IO; } return 0;}/* ------------------------------------------------------------------------- */int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len){int bytesReceived, maxLen = *len; if(!usesReportIDs){ buffer++; /* make room for dummy report ID */ maxLen--; } bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000); if(bytesReceived < 0){ fprintf(stderr, "Error sending message: %s\n", usb_strerror()); return USBOPEN_ERR_IO; } *len = bytesReceived; if(!usesReportIDs){ buffer[-1] = reportNumber; /* add dummy report ID */ (*len)++; } return 0;}/* ######################################################################## */#endif /* defined WIN32 ################################################### *//* ######################################################################## */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -