//可以查看按游戏手柄按钮时的情况. //USB接口的游戏手柄 //编译环境:Windows 2000 server+VC++ 6.0+Win2K DDK #include #include #include #include extern "C" { #include } void main() { GUID HidGuid; // 查找本系统中HID类的GUID标识 HidD_GetHidGuid(&HidGuid); _tprintf("系统中HID类的GUID标识为:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/n", HidGuid.Data1,HidGuid.Data2 ,HidGuid.Data3 , HidGuid.Data4[0],HidGuid.Data4[1],HidGuid.Data4[2], HidGuid.Data4[3],HidGuid.Data4[4],HidGuid.Data4[5], HidGuid.Data4[6],HidGuid.Data4[7]); // 准备查找符合HID规范的USB设备 HDEVINFO hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { _tprintf("符合HID规范的USB设备发生错误/n"); return; } _tprintf("正在查找可用的USB设备.../n"); DWORD MemberIndex = 0; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; BOOL bSuccess = FALSE; DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); do { bSuccess = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, MemberIndex, &DeviceInterfaceData); if ((!bSuccess) && (GetLastError() == ERROR_NO_MORE_ITEMS)) { if(MemberIndex == 0) _tprintf("抱歉,未找到可用的USB设备!/n"); else _tprintf("没有更多的可用的USB设备!/n"); SetupDiDestroyDeviceInfoList(hDevInfo); return; } _tprintf("找到了一个USB设备:/n"); //若找到了一个USB设备,则获取该设备的细节信息 PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData; DWORD Length = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, NULL, 0, &Length, NULL); pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //MUST BE!!! if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, pDeviceInterfaceDetailData, Length, NULL, NULL)) _tprintf("查找路径设备时出错!/n"); else _tprintf("设备路径:%s/n",pDeviceInterfaceDetailData->DevicePath ); //打开设备句柄 HANDLE hDeviceHandle = CreateFile(pDeviceInterfaceDetailData->DevicePath , GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDeviceHandle == INVALID_HANDLE_VALUE) _tprintf("打开设备路径出错!/n"); else { HIDD_ATTRIBUTES Attributes; HidD_GetAttributes(hDeviceHandle,&Attributes); //将有关该设备的标识显示出来 _tprintf("供应商ID/t:0X%04X/n",Attributes.VendorID); _tprintf("产品ID/t:0X%04X/n",Attributes.ProductID); _tprintf("产品版本号:0X%04X/n",Attributes.VersionNumber); WCHAR mString[256]; TCHAR Buffer[256]; HidD_GetManufacturerString(hDeviceHandle,mString,sizeof(mString)); if (wcstombs(Buffer,mString,256) == -1) // fail Buffer[0] = NULL; _tprintf("生产商:/t%s/n",Buffer); HidD_GetProductString(hDeviceHandle,mString,sizeof(mString)); if (wcstombs(Buffer,mString,256) == -1) Buffer[0] = NULL; _tprintf("产品名称:/t%s/n",Buffer); // 通信: PHIDP_PREPARSED_DATA pHidpPreparsedData; HIDP_CAPS hidPCaps; if (!HidD_GetPreparsedData(hDeviceHandle,&pHidpPreparsedData)) { _tprintf("获取 HID PREPARED DATA 失败!/n"); return; } NTSTATUS status = HidP_GetCaps(pHidpPreparsedData,&hidPCaps); if (status == HIDP_STATUS_SUCCESS) { _tprintf("CAP信息如下:/n"); _tprintf(" InputReportByteLength %d/n", hidPCaps.InputReportByteLength); _tprintf(" OutputReportByteLength %d/n", hidPCaps.OutputReportByteLength); } DWORD nReadBytes = 0; BYTE *pInputReport = new BYTE[hidPCaps.InputReportByteLength]; memset(pInputReport,0,hidPCaps.InputReportByteLength); do { ReadFile(hDeviceHandle,pInputReport,hidPCaps.InputReportByteLength,&nReadBytes,NULL); if (hidPCaps.InputReportByteLength == nReadBytes) { for(unsigned int i=0; i<(nReadBytes-1);i++) _tprintf("%02x-",pInputReport[i]); _tprintf("%02x/r",pInputReport[nReadBytes-1]); } if (pInputReport[nReadBytes-2] == 0x20) //break the loop when pressing a specific key { _tprintf("/n"); break; } Sleep(10); }while(hidPCaps.InputReportByteLength == nReadBytes); //释放句柄资源 CloseHandle(hDeviceHandle); } MemberIndex++; }while(bSuccess); SetupDiDestroyDeviceInfoList(hDevInfo); } |