summaryrefslogtreecommitdiffstats
path: root/hid_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'hid_test.c')
-rw-r--r--hid_test.c575
1 files changed, 575 insertions, 0 deletions
diff --git a/hid_test.c b/hid_test.c
new file mode 100644
index 0000000..ccc519d
--- /dev/null
+++ b/hid_test.c
@@ -0,0 +1,575 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#if !defined _WIN32 && !defined __CYGWIN__
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <asm/types.h>
+ #include <fcntl.h>
+ #include <linux/hiddev.h>
+ #include <linux/input.h>
+ #include <sys/timeb.h>
+#else
+ #include <windows.h>
+ #include <setupapi.h>
+ #include <hidusage.h>
+ #include <hidpi.h>
+ #include <math.h>
+ #include <sys/timeb.h>
+ #include <wchar.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <string.h>
+
+int FindDevice();
+
+#if !defined _WIN32 && !defined __CYGWIN__
+DWORD GetTickCount();
+struct hiddev_report_info rep_info_i,rep_info_u;
+struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u;
+struct hiddev_devinfo device_info;
+
+#else
+ #define write() Result = WriteFile(WriteHandle,bufferU,n,&BytesWritten,NULL);
+ #define read() Result = ReadFile(ReadHandle,bufferI,n,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped);\
+ Result = WaitForSingleObject(hEventObject,50);\
+ ResetEvent(hEventObject);\
+ if(Result!=WAIT_OBJECT_0){\
+ printf("communication timeout\r\n");\
+ }
+
+unsigned char bufferU[128],bufferI[128];
+DWORD NumberOfBytesRead,BytesWritten;
+ULONG Result;
+HANDLE WriteHandle,ReadHandle;
+OVERLAPPED HIDOverlapped;
+HANDLE hEventObject;
+
+#endif
+
+int vid=0x1209,pid=0x5432,info=0;
+
+int main (int argc, char **argv) {
+#define L_IT 0
+#define L_EN 1
+ int d=0,v=0,q=0,r=1,lang=L_EN,c,i,j,block=0,R=0;
+ char path[512]="";
+ char buf[256];
+ for(i=0;i<256;i++) buf[i]=0;
+ #if defined _WIN32
+ int n=65;
+ int langID=GetUserDefaultLangID();
+ if((langID&0xFF)==0x10) lang=L_IT;
+ #else
+ int n=64;
+ if(getenv("LANG")&&strstr(getenv("LANG"),"it")!=0) lang=L_IT;
+ #endif
+ opterr = 0;
+ int option_index = 0;
+ struct option long_options[] =
+ {
+ {"b", no_argument, &block, 1},
+ {"block", no_argument, &block, 1},
+ {"verbose", no_argument, &v, 1},
+ {"v", no_argument, &v, 1},
+ {"quiet", no_argument, &q, 1},
+ {"q", no_argument, &q, 1},
+ {"info", no_argument, &info, 1},
+ {"i", no_argument, &info, 1},
+ {"help", no_argument, 0, 'h'},
+ {"path", required_argument, 0, 'p'},
+ {"read", required_argument, 0, 'R'},
+ {"repeat", required_argument, 0, 'r'},
+ {"delay", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+ while ((c = getopt_long_only (argc, argv, "n:d:p:hr:R:",long_options,&option_index)) != -1)
+ switch (c)
+ {
+ case 'h': //guida
+ if(!lang) printf("hid_test [opzioni] [dati]\n"
+ "opzioni: \n"
+ "-b, block\tusa lettura bloccante\n"
+ "-d, delay\tritardo lettura (ms) [0]\n"
+ "-h, help\tguida\n"
+ "-i, info\tinformazioni sul dispositivo [no]\n"
+ "-n\t\tdimensione report [64]\n"
+ "-p, path\tpercorso dispositivo [/dev/usb/hiddev0] \n"
+ "-q, quiet\tmostra solo risposta [no]\n"
+ "-R, read\tripeti lettura N volte [0]\n\n"
+ "-r, repeat\tripeti scrittura-lettura N volte [1]\n\n"
+ "-v, verbose\tmostra funzioni [no]\n"
+ "es. hid_test -i 1 2 3 4\n");
+ else printf("hid_test [otions] [data]\n"
+ "options: \n"
+ "-b, block\tuse blocking read\n"
+ "-d, delay\tread delay (ms) [0]\n"
+ "-h, help\thelp\n"
+ "-i, info\tdevice info [no]\n"
+ "-n\t\treport size [64]\n"
+ "-p, path\tdevice path [/dev/usb/hiddev0]\n"
+ "-q, quiet\tprint response only [no]\n"
+ "-R, repeat\trepeat read N times [0]\n\n"
+ "-r, repeat\trepeat N times [1]\n\n"
+ "-v, verbose\tshow functions [no]\n"
+ "e.g. hid_test -i 1 2 3 4\n");
+ exit(1);
+ break;
+ case 'n': //dim report
+ n = atoi(optarg);
+ break;
+ case 'd': //ritardo lettura
+ d = atoi(optarg);
+ break;
+ case 'p': //percorso hiddev
+ strncpy(path,optarg,sizeof(path));
+ break;
+ case 'r': //ripeti IO
+ r = atoi(optarg);
+ break;
+ case 'R': //ripeti lettura
+ R = atoi(optarg);
+ break;
+ case '?':
+ if (optopt == 'c')
+ fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+ else if (isprint (optopt))
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr, "Unknown option character 0x%02x\n", optopt);
+ return 1;
+ default:
+ //abort ();
+ break;
+ }
+
+ for (j=0,i = optind; i < argc&&i<128; i++,j++) sscanf(argv[i], "%x", &buf[j]);
+ for (;j<n;j++) buf[j]=0;
+
+ int fd = -1;
+
+ if(FindDevice()<0) exit(1);
+
+ if(!q){
+ printf("-> ");
+ for(i=0;i<j;i++) printf("%02X ",(unsigned char)buf[i]);
+ printf("\n");
+ }
+ if(v) printf("%slocking read\n",block?"B":"Non b");
+
+#if !defined _WIN32 && !defined __CYGWIN__
+ struct hiddev_event ev[80];
+ rep_info.report_type=HID_REPORT_TYPE_OUTPUT;
+ rep_info.report_id=HID_REPORT_ID_FIRST;
+ rep_info.num_fields=1;
+ ref_multi.uref.report_type=HID_REPORT_TYPE_OUTPUT;
+ ref_multi.uref.report_id=HID_REPORT_ID_FIRST;
+ ref_multi.uref.field_index=0;
+ ref_multi.uref.usage_index=0;
+ ref_multi.num_values=n;
+ for(i=0;i<n;i++) ref_multi.values[i]=buf[i];
+ int res;
+ res=ioctl(fd, HIDIOCSUSAGES, &ref_multi);
+ if(v) printf("HIDIOCSUSAGES:%d\n",res);
+ res=ioctl(fd,HIDIOCSREPORT, &rep_info);
+ if(v) printf("HIDIOCSREPORT:%d\n",res);
+ if(!block) for(j=0;j<r;j++){
+ usleep(d*1000);
+ rep_info.report_type=HID_REPORT_TYPE_INPUT;
+ res=ioctl(fd,HIDIOCGREPORT, &rep_info);
+ if(v) printf("HIDIOCGREPORT:%d\n",res);
+ ref_multi.uref.report_type=HID_REPORT_TYPE_INPUT;
+ res=ioctl(fd, HIDIOCGUSAGES, &ref_multi);
+ if(v) printf("HIDIOCGUSAGES:%d\n",res);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ref_multi.values[i]);
+ printf("\n");
+ }
+ else for(j=0;j<r;j++){
+ usleep(d*1000);
+ res=read(fd, ev,sizeof(struct hiddev_event) *n);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ev[i].value);
+ printf("\n");
+ }
+ else for(j=0;j<R;j++){
+ usleep(d*1000);
+ res=read(fd, ev,sizeof(struct hiddev_event) *n);
+ if(!q) printf("<- ");
+ for(i=0;i<n;i++) printf("%02X ",ev[i].value);
+ printf("\n");
+ }
+ close(fd);
+#else
+ __int64 start,stop,freq;
+ QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
+ bufferU[0]=0;
+ for(i=0;i<n;i++) bufferU[i+1]=buf[i];
+ for(j=0;j<r;j++){
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ write();
+ Sleep(d);
+ read();
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ if(!q) printf("<- ");
+ for(i=1;i<n;i++) printf("%02X ",bufferI[i]);
+ printf("\nT=%.2fms\n",(stop-start)*1000.0/freq);
+ }
+ for(j=0;j<R;j++){
+ QueryPerformanceCounter((LARGE_INTEGER *)&start);
+ read();
+ QueryPerformanceCounter((LARGE_INTEGER *)&stop);
+ if(!q) printf("<- ");
+ for(i=1;i<n;i++) printf("%02X ",bufferI[i]);
+ printf("\nT=%.2fms\n",(stop-start)*1000.0/freq);
+ }
+
+#endif
+ return 0;
+}
+
+
+DWORD GetTickCount(){
+ struct timeb now;
+ ftime(&now);
+ return now.time*1000+now.millitm;
+}
+
+
+int FindDevice(){
+#if !defined _WIN32 && !defined __CYGWIN__
+ struct hiddev_devinfo device_info;
+ int i;
+ if(path[0]==0){ //search all devices
+ for(i=0;i<16;i++){
+ sprintf(path,"/dev/usb/hiddev%d",i);
+ if((fd = open(path, O_RDONLY ))>0){
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor==vid&&device_info.product==pid) break;
+ else close(fd);
+ }
+ }
+ if(i==16){
+ printf(strings[S_noprog]);
+ return -1;
+ }
+ }
+ else{ //user supplied path
+ if ((fd = open(path, O_RDONLY )) < 0) {
+ printf(strings[S_DevPermission],path);
+ exit(1);
+ }
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ if(device_info.vendor!=vid||device_info.product!=pid){
+ printf(strings[S_noprog]);
+ return -1;
+ }
+ }
+ printf(strings[S_progDev],path);
+
+ rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT;
+ rep_info_i.report_type=HID_REPORT_TYPE_INPUT;
+ rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST;
+ rep_info_u.num_fields=rep_info_i.num_fields=1;
+ ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT;
+ ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT;
+ ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST;
+ ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0;
+ ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0;
+ ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF;
+
+ if(info){
+ ioctl(fd, HIDIOCGDEVINFO, &device_info);
+ printf("vendor 0x%04hx product 0x%04hx version 0x%04hx ",
+ device_info.vendor, device_info.product, device_info.version);
+ printf("has %i application%s ", device_info.num_applications,
+ (device_info.num_applications==1?"":"s"));
+ printf("and is on bus: %d devnum: %d ifnum: %d\n",
+ device_info.busnum, device_info.devnum, device_info.ifnum);
+ char name[256]= "Unknown";
+ if(ioctl(fd, HIDIOCGNAME(sizeof(name)), name) < 0) perror("evdev ioctl");
+ printf("The device on %s says its name is %s\n", path, name);
+ }
+
+#else
+ char string[256];
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
+ HANDLE DeviceHandle;
+ HANDLE hDevInfo;
+ GUID HidGuid;
+ int MyDeviceDetected;
+ char MyDevicePathName[1024];
+ ULONG Length;
+ ULONG Required;
+ typedef struct _HIDD_ATTRIBUTES {
+ ULONG Size;
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+ } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+
+ typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid);
+ typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes);
+ typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers);
+ typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength);
+ HIDD_ATTRIBUTES Attributes;
+ SP_DEVICE_INTERFACE_DATA devInfoData;
+ int LastDevice = FALSE;
+ int MemberIndex = 0;
+ LONG Result;
+ //char UsageDescription[256];
+
+ Length=0;
+ detailData=NULL;
+ DeviceHandle=NULL;
+
+ HMODULE hHID=0;
+ GETHIDGUID HidD_GetHidGuid=0;
+ GETATTRIBUTES HidD_GetAttributes=0;
+ SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0;
+ GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0;
+ GETFEATURE HidD_GetFeature=0;
+ SETFEATURE HidD_SetFeature=0;
+ GETREPORT HidD_GetInputReport=0;
+ SETREPORT HidD_SetOutputReport=0;
+ GETMANUFACTURERSTRING HidD_GetManufacturerString=0;
+ GETPRODUCTSTRING HidD_GetProductString=0;
+ hHID = LoadLibrary("hid.dll");
+ if(!hHID){
+ printf("Can't find hid.dll");
+ return 0;
+ }
+ HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid");
+ HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes");
+ HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers");
+ HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers");
+ HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature");
+ HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature");
+ HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport");
+ HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport");
+ HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString");
+ HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString");
+ if(HidD_GetHidGuid==NULL\
+ ||HidD_GetAttributes==NULL\
+ ||HidD_GetFeature==NULL\
+ ||HidD_SetFeature==NULL\
+ ||HidD_GetInputReport==NULL\
+ ||HidD_SetOutputReport==NULL\
+ ||HidD_GetManufacturerString==NULL\
+ ||HidD_GetProductString==NULL\
+ ||HidD_SetNumInputBuffers==NULL\
+ ||HidD_GetNumInputBuffers==NULL) return -1;
+
+
+ HMODULE hSAPI=0;
+ hSAPI = LoadLibrary("setupapi.dll");
+ if(!hSAPI){
+ printf("Can't find setupapi.dll");
+ return 0;
+ }
+ typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD);
+ typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA);
+ typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA);
+ typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO);
+ SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0;
+ SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0;
+ SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0;
+ SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0;
+ SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA");
+ SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces");
+ SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA");
+ SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList");
+ if(SetupDiGetClassDevsA==NULL\
+ ||SetupDiEnumDeviceInterfaces==NULL\
+ ||SetupDiDestroyDeviceInfoList==NULL\
+ ||SetupDiGetDeviceInterfaceDetailA==NULL) return -1;
+
+
+ /*
+ The following code is adapted from Usbhidio_vc6 application example by Jan Axelson
+ for more information see see http://www.lvr.com/hidpage.htm
+ */
+
+ /*
+ API function: HidD_GetHidGuid
+ Get the GUID for all system HIDs.
+ Returns: the GUID in HidGuid.
+ */
+ HidD_GetHidGuid(&HidGuid);
+
+ /*
+ API function: SetupDiGetClassDevs
+ Returns: a handle to a device information set for all installed devices.
+ Requires: the GUID returned by GetHidGuid.
+ */
+ hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+ devInfoData.cbSize = sizeof(devInfoData);
+
+ //Step through the available devices looking for the one we want.
+ //Quit on detecting the desired device or checking all available devices without success.
+ MemberIndex = 0;
+ LastDevice = FALSE;
+ do
+ {
+ /*
+ API function: SetupDiEnumDeviceInterfaces
+ On return, MyDeviceInterfaceData contains the handle to a
+ SP_DEVICE_INTERFACE_DATA structure for a detected device.
+ Requires:
+ The DeviceInfoSet returned in SetupDiGetClassDevs.
+ The HidGuid returned in GetHidGuid.
+ An index to specify a device.
+ */
+ Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
+ if (Result != 0)
+ {
+ //A device has been detected, so get more information about it.
+ /*
+ API function: SetupDiGetDeviceInterfaceDetail
+ Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
+ containing information about a device.
+ To retrieve the information, call this function twice.
+ The first time returns the size of the structure in Length.
+ The second time returns a pointer to the data in DeviceInfoSet.
+ Requires:
+ A DeviceInfoSet returned by SetupDiGetClassDevs
+ The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
+
+ The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
+ This application doesn't retrieve or use the structure.
+ If retrieving the structure, set
+ MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
+ and pass the structure's address.
+ */
+ //Get the Length value.
+ //The call will return with a "buffer too small" error which can be ignored.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
+
+ //Allocate memory for the hDevInfo structure, using the returned Length.
+ detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+
+ //Set cbSize in the detailData structure.
+ detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ //Call the function again, this time passing it the returned buffer size.
+ Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL);
+
+ // Open a handle to the device.
+ // To enable retrieving information about a system mouse or keyboard,
+ // don't request Read or Write access for this handle.
+ /*
+ API function: CreateFile
+ Returns: a handle that enables reading and writing to the device.
+ Requires:
+ The DevicePath in the detailData structure
+ returned by SetupDiGetDeviceInterfaceDetail.
+ */
+ DeviceHandle=CreateFile(detailData->DevicePath,
+ 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
+
+ /*
+ API function: HidD_GetAttributes
+ Requests information from the device.
+ Requires: the handle returned by CreateFile.
+ Returns: a HIDD_ATTRIBUTES structure containing
+ the Vendor ID, Product ID, and Product Version Number.
+ Use this information to decide if the detected device is
+ the one we're looking for.
+ */
+
+ //Set the Size to the number of bytes in the structure.
+ Attributes.Size = sizeof(Attributes);
+ Result = HidD_GetAttributes(DeviceHandle,&Attributes);
+
+ //Is it the desired device?
+ MyDeviceDetected = FALSE;
+ if (Attributes.VendorID == vid)
+ {
+ if (Attributes.ProductID == pid)
+ {
+ //Both the Vendor ID and Product ID match.
+ MyDeviceDetected = TRUE;
+ strcpy(MyDevicePathName,detailData->DevicePath);
+
+ // Get a handle for writing Output reports.
+ WriteHandle=CreateFile(detailData->DevicePath,
+ GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL);
+
+ //Get a handle to the device for the overlapped ReadFiles.
+ ReadHandle=CreateFile(detailData->DevicePath,
+ GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
+
+ if (hEventObject) CloseHandle(hEventObject);
+ hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
+
+ //Set the members of the overlapped structure.
+ HIDOverlapped.hEvent = hEventObject;
+ HIDOverlapped.Offset = 0;
+ HIDOverlapped.OffsetHigh = 0;
+ Result=HidD_SetNumInputBuffers(DeviceHandle,64);
+ }
+ else
+ //The Product ID doesn't match.
+ CloseHandle(DeviceHandle);
+ }
+ else
+ //The Vendor ID doesn't match.
+ CloseHandle(DeviceHandle);
+ //Free the memory used by the detailData structure (no longer needed).
+ free(detailData);
+ }
+ else
+ //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
+ LastDevice=TRUE;
+ //If we haven't found the device yet, and haven't tried every available device,
+ //try the next one.
+ MemberIndex = MemberIndex + 1;
+ } //do
+ while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+ //Free the memory reserved for hDevInfo by SetupDiClassDevs.
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+
+ if (MyDeviceDetected == FALSE){
+ printf("Can't find device\n");
+ return -1;
+ }
+
+ if(info){
+ printf("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName);
+ if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string);
+ if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string);
+ }
+#endif
+ return 0;
+}