static CString GetUSBDevicePath (int num) { GUID guid; HidD_GetHidGuid(&guid); HDEVINFO DeviceInfo = SetupDiGetClassDevs (&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); SP_DEVICE_INTERFACE_DATA DeviceInterface; DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces (DeviceInfo, NULL, &guid, num, &DeviceInterface)) { SetupDiDestroyDeviceInfoList (DeviceInfo); return ""; } unsigned long size; SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, NULL, 0, &size, 0); PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(size); DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); CString ret; if (SetupDiGetDeviceInterfaceDetail (DeviceInfo, &DeviceInterface, DeviceDetail, size, &size, NULL)) ret = DeviceDetail->DevicePath; free(DeviceDetail); SetupDiDestroyDeviceInfoList (DeviceInfo); return ret; }
/********************************************************************* * * _Init * * Function description * Initialise the USBHID API and look for new HID devices that * comply with the Vendor page set. * * Return value: * 1 - O.K., devices have been found. * 0 - Error, no devices found. */ static int _Init(void) { HDEVINFO hDevList; SP_DEVICE_INTERFACE_DATA DevData; BOOL r; DWORD i; GUID HidGuid; // // Get the GUID for HID class from Windows // HidD_GetHidGuid(&HidGuid); // // Create a list of attached devices // hDevList = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hDevList == INVALID_HANDLE_VALUE) { printf("SetupDiGetClassDevs failed, err=%d\n",GetLastError()); return 0; } ZeroMemory(&DevData,sizeof(DevData)); DevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); _NumDevices = 0; // // Enumerate thru all HID devices // for (i = 0; i < 127; i++) { DWORD LastError; r = SetupDiEnumDeviceInterfaces(hDevList, NULL, &HidGuid, i, &DevData); if (r == 0) { LastError = GetLastError(); if (LastError == ERROR_NO_MORE_ITEMS) { break; } else { // // There are no devices attached using the USB HID class // SetupDiDestroyDeviceInfoList(hDevList); return 0; // Error: No HID devices found. } } // // Allocate memory for connection info if necessary. // if (_apConnInfo[_NumDevices] == NULL) { _apConnInfo[_NumDevices] = (CONN_INFO *)calloc(sizeof(CONN_INFO), 1); } // // Check and store information required into pConnInfo // if (_AddConnection(hDevList, &DevData, _apConnInfo[_NumDevices])) { if (++_NumDevices == USB_MAX_DEVICES) { break; } } } if (_NumDevices == 0) { return 0; // Error: No HID device found matching our requirements. } return 1; // O.K found devices. }
QList<QUsbHidInfo> QUsbHidEnumerator::getPorts(unsigned short vid, unsigned short pid) { QList<QUsbHidInfo> ports; GUID guid; HidD_GetHidGuid(&guid); enumerateDevicesWin(guid, &ports,vid, pid); return ports; }
// // Open USB channel to PIC... // int PicBootloader::open() { if (m_hDevice != INVALID_HANDLE_VALUE) close(); GUID HidGuid; HidD_GetHidGuid( &HidGuid); HDEVINFO hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) return PICRESULT_INVALID_HANDLE; SP_DEVICE_INTERFACE_DATA DevInterfaceData; bool done = false; unsigned long DevIndex = 0; while (!done) { memset (&DevInterfaceData,0,sizeof(DevInterfaceData)); DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, DevIndex, &DevInterfaceData)) break; unsigned long DetailsSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, NULL, 0, &DetailsSize, NULL); PSP_INTERFACE_DEVICE_DETAIL_DATA pDetails = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(DetailsSize); if (pDetails == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); return PICRESULT_MEMALLOCERROR_DEVICE_DETAIL; } memset (pDetails,0,DetailsSize); pDetails->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, pDetails, DetailsSize, NULL, NULL)) { free(pDetails); SetupDiDestroyDeviceInfoList(hDevInfo); return PICRESULT_GETDEVICEDETAIL_FAIL; } char *path = strdup(pDetails->DevicePath); if (isValidDevice(path)) { // valid device found m_hDevice = CreateFile(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); free(pDetails); break; } free(pDetails); DevIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); return (m_hDevice == INVALID_HANDLE_VALUE) ? PICRESULT_DEVICE_NOT_FOUND : PICRESULT_NOERROR; }
BOOLEAN TryToSwitchAllDevices( BOOL toHID ) { GUID hidGuid; HidD_GetHidGuid(&hidGuid); HDEVINFO hDevInfo = SetupDiGetClassDevs( &hidGuid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if ( hDevInfo == INVALID_HANDLE_VALUE ) { LbtReportFunctionError(TEXT("SetupDiGetClassDevs")); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return FALSE; } SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (DWORD dMemberIndex = 0; SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &hidGuid, dMemberIndex, &DeviceInterfaceData); dMemberIndex++ ) { DWORD RequiredSize; if ( SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, 0) || GetLastError() != ERROR_INSUFFICIENT_BUFFER ) { LbtReportFunctionError(TEXT("SetupDiGetDeviceInterfaceDetail")); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return FALSE; } PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc( GetProcessHeap(), 0, RequiredSize); if ( pDeviceInterfaceDetailData == NULL ) { LbtReportFunctionError(TEXT("HeapAlloc")); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return FALSE; } pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if ( !SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, pDeviceInterfaceDetailData, RequiredSize, NULL, 0) ) { LbtReportFunctionError(TEXT("SetupDiGetDeviceInterfaceDetail")); HeapFree(GetProcessHeap(), 0, pDeviceInterfaceDetailData); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return FALSE; } TryToSwitch(pDeviceInterfaceDetailData->DevicePath, toHID); HeapFree(GetProcessHeap(), 0, pDeviceInterfaceDetailData); } return TRUE; }
QUsbHidEnumerator::QUsbHidEnumerator(QObject *parent) : QObject(parent) { m_vid = 0; m_pid = 0; HidD_GetHidGuid(&hidGUID); if( !QMetaType::isRegistered( QMetaType::type("QUsbHidInfo") ) ) qRegisterMetaType<QUsbHidInfo>("QUsbHidInfo"); #if (defined QT_GUI_LIB) notificationWidget = 0; #endif // QT_GUI_LIB }
/* * \brief Open a hid device. * * \param vendor the vendor id of the hid device to open. * \param product the product id of the hid device to open. * * \return the identifier of the opened device (to be used in further operations), \ * or -1 in case of failure (e.g. no device found). */ int hidasync_open_ids(unsigned short vendor, unsigned short product) { int ret = -1; GUID guid; HDEVINFO info; DWORD reqd_size; SP_DEVICE_INTERFACE_DATA iface; SP_DEVICE_INTERFACE_DETAIL_DATA *details; int index; HidD_GetHidGuid(&guid); info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(info != INVALID_HANDLE_VALUE) { for(index = 0; ; ++index) { iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface) == FALSE) { break; //no more device } if(SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL) == FALSE) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; } } details = calloc(reqd_size, sizeof(char)); if(details == NULL) { fprintf(stderr, "%s:%d calloc failed\n", __FILE__, __LINE__); continue; } details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL) == FALSE) { ASYNC_PRINT_ERROR("SetupDiGetDeviceInterfaceDetail") free(details); details = NULL; continue; } int device = open_path(details->DevicePath, 0); free(details); details = NULL; if(device >= 0) { if(devices[device].hidInfo.vendor_id == vendor && devices[device].hidInfo.product_id == product) { ret = device; break; } async_close(device); } } } return ret; }
static HANDLE open_usb_device(int vid, int pid) { GUID guid; HDEVINFO info; DWORD index, required_size; SP_DEVICE_INTERFACE_DATA iface; SP_DEVICE_INTERFACE_DETAIL_DATA *details; HIDD_ATTRIBUTES attrib; HANDLE h; BOOL ret; HidD_GetHidGuid(&guid); info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (info == INVALID_HANDLE_VALUE) return NULL; for (index=0; 1 ;index++) { iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface); if (!ret) { SetupDiDestroyDeviceInfoList(info); break; } SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &required_size, NULL); details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(required_size); if (details == NULL) continue; memset(details, 0, required_size); details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, required_size, NULL, NULL); if (!ret) { free(details); continue; } h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); free(details); if (h == INVALID_HANDLE_VALUE) continue; attrib.Size = sizeof(HIDD_ATTRIBUTES); ret = HidD_GetAttributes(h, &attrib); if (!ret) { CloseHandle(h); continue; } if (attrib.VendorID != vid || attrib.ProductID != pid) { CloseHandle(h); continue; } SetupDiDestroyDeviceInfoList(info); return h; } return NULL; }
NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) { SP_DEVINFO_DATA Data; UNICODE_STRING nameW; NTSTATUS status; HDEVINFO devinfo; GUID hidGuid; BASE_DEVICE_EXTENSION *ext; HidD_GetHidGuid(&hidGuid); ext = device->DeviceExtension; RtlInitUnicodeString( &nameW, ext->device_name); devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_HIDCLASS, NULL, NULL, DIGCF_DEVICEINTERFACE); if (!devinfo) { FIXME( "failed to get ClassDevs %x\n", GetLastError()); return STATUS_UNSUCCESSFUL; } Data.cbSize = sizeof(Data); if (!SetupDiCreateDeviceInfoW(devinfo, ext->instance_id, &GUID_DEVCLASS_HIDCLASS, NULL, NULL, DICD_INHERIT_CLASSDRVS, &Data)) { if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) { SetupDiDestroyDeviceInfoList(devinfo); return STATUS_SUCCESS; } FIXME( "failed to Create Device Info %x\n", GetLastError()); goto error; } if (!SetupDiRegisterDeviceInfo( devinfo, &Data, 0, NULL, NULL, NULL )) { FIXME( "failed to Register Device Info %x\n", GetLastError()); goto error; } SetupDiDestroyDeviceInfoList(devinfo); status = IoRegisterDeviceInterface(device, &hidGuid, NULL, &ext->link_name); if (status != STATUS_SUCCESS) { FIXME( "failed to register device interface %x\n", status ); return status; } return STATUS_SUCCESS; error: SetupDiDestroyDeviceInfoList(devinfo); return STATUS_UNSUCCESSFUL; }
// 用于查找HID设备 USBHIDDLL_API bool __stdcall USBHIDFindUSBHIDDevice() { GUID Guid; HidD_GetHidGuid(&Guid); void* info; info=SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (info!=INVALID_HANDLE_VALUE) { DWORD devIndex; SP_INTERFACE_DEVICE_DATA ifData; ifData.cbSize=sizeof(ifData); for (devIndex=0;SetupDiEnumDeviceInterfaces(info, NULL, &Guid, devIndex, &ifData);++devIndex) { DWORD needed; SetupDiGetDeviceInterfaceDetail(info, &ifData, NULL, 0, &needed, NULL); PSP_INTERFACE_DEVICE_DETAIL_DATA detail=(PSP_INTERFACE_DEVICE_DETAIL_DATA)new BYTE[needed]; detail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); SP_DEVINFO_DATA did={sizeof(SP_DEVINFO_DATA)}; if (SetupDiGetDeviceInterfaceDetail(info, &ifData, detail, needed, NULL, &did)) { // 查找特定设备 查到后则返回。 if(strstr(detail->DevicePath, "vid_0483") != NULL) { memset(GlobalUSBHIDDevicePath, '\0', sizeof(GlobalUSBHIDDevicePath)); memcpy(GlobalUSBHIDDevicePath, detail->DevicePath, strlen(detail->DevicePath)); if (!SetupDiGetDeviceRegistryProperty(info, &did, SPDRP_DEVICEDESC, NULL, (PBYTE)GlobalUSBHIDDeviceName, sizeof(GlobalUSBHIDDeviceName), NULL)) { memset(GlobalUSBHIDDeviceName, '\0', sizeof(GlobalUSBHIDDeviceName)); char* hint = "(Unnamed HID device)"; memcpy(GlobalUSBHIDDeviceName, hint, strlen(hint)); } delete[] (PBYTE)detail; SetupDiDestroyDeviceInfoList(info); return true; } } delete[] (PBYTE)detail; } SetupDiDestroyDeviceInfoList(info); } return false; }
BOOL OpenPortalHandle(PHANDLE phPortalHandle) { BOOL OK; GUID guid; // Try to open XBox portal handle first OK = OpenPortalHandleFromGUID(xbox_guid, phPortalHandle); if(OK) { g_bIsXboxPortal = TRUE; return OK; } g_bIsXboxPortal = FALSE; HidD_GetHidGuid(&guid); OK = OpenPortalHandleFromGUID(guid, phPortalHandle); return OK; }
HANDLE SearchMatchingHwID ( USAGE myUsagePage, USAGE myUsage ) { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; SP_DEVINFO_DATA devInfoData; GUID hidguid; int i; HidD_GetHidGuid(&hidguid); hardwareDeviceInfo = SetupDiGetClassDevs ((LPGUID)&hidguid, NULL, NULL, // Define no (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE)); if (INVALID_HANDLE_VALUE == hardwareDeviceInfo) { printf("SetupDiGetClassDevs failed: %x\n", GetLastError()); return INVALID_HANDLE_VALUE; } deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); // // Enumerate devices of this interface class // printf("\n....looking for our HID device (with UP=0x%x " "and Usage=0x%x)\n", myUsagePage, myUsage); for (i = 0; SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs (LPGUID)&hidguid, i, // &deviceInterfaceData); i++) { // // Open the device interface and Check if it is our device // by matching the Usage page and Usage from Hid_Caps. // If this is our device then send the hid request. // HANDLE file = OpenDeviceInterface(hardwareDeviceInfo, &deviceInterfaceData, myUsagePage, myUsage); if (file != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return file; } // //device was not found so loop around. // } printf("Failure: Could not find our HID device \n"); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return INVALID_HANDLE_VALUE; }
BOOL OpenDevice(USHORT usVID, USHORT usPID) { //CString MyDevPathName=""; TCHAR MyDevPathName[MAX_PATH]; //定義一個GUID的結構體HidGuid來保存HID設備的接口類GUID。 GUID HidGuid; //定義一個DEVINFO的句柄hDevInfoSet來保存獲取到的設備信息集合句柄。 HDEVINFO hDevInfoSet; //定義MemberIndex,表示當前搜索到第幾個設備,0表示第一個設備。 DWORD MemberIndex; //DevInterfaceData,用來保存設備的驅動接口信息 SP_DEVICE_INTERFACE_DATA DevInterfaceData; //定義一個BOOL變量,保存函數調用是否返回成功 BOOL Result; //定義一個RequiredSize的變量,用來接收需要保存詳細信息的緩衝長度。 DWORD RequiredSize; //定義一個指向設備詳細信息的結構體指針。 PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetailData; //定義一個用來保存打開設備的句柄。 HANDLE hDevHandle; //定義一個HIDD_ATTRIBUTES的結構體變量,保存設備的屬性。 HIDD_ATTRIBUTES DevAttributes; //初始化設備未找到 BOOL MyDevFound=FALSE; //初始化讀、寫句柄為無效句柄。 m_hReadHandle=INVALID_HANDLE_VALUE; m_hWriteHandle=INVALID_HANDLE_VALUE; //對DevInterfaceData結構體的cbSize初始化為結構體大小 DevInterfaceData.cbSize=sizeof(DevInterfaceData); //對DevAttributes結構體的Size初始化為結構體大小 DevAttributes.Size=sizeof(DevAttributes); //調用HidD_GetHidGuid函數獲取HID設備的GUID,並保存在HidGuid中。 HidD_GetHidGuid(&HidGuid); //根據HidGuid來獲取設備信息集合。其中Flags參數設置為 //DIGCF_DEVICEINTERFACE|DIGCF_PRESENT,前者表示使用的GUID為 //接口類GUID,後者表示只列舉正在使用的設備,因為我們這裡只 //查找已經連接上的設備。返回的句柄保存在hDevinfo中。注意設備 //信息集合在使用完畢後,要使用函數SetupDiDestroyDeviceInfoList //銷毀,不然會造成內存洩漏。 hDevInfoSet=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE|DIGCF_PRESENT); //AddToInfOut("開始查找設備"); //然後對設備集合中每個設備進行列舉,檢查是否是我們要找的設備 //當找到我們指定的設備,或者設備已經查找完畢時,就退出查找。 //首先指向第一個設備,即將MemberIndex置為0。 MemberIndex=0; while(1) { //調用SetupDiEnumDeviceInterfaces在設備信息集合中獲取編號為 //MemberIndex的設備信息。 Result=SetupDiEnumDeviceInterfaces(hDevInfoSet, NULL, &HidGuid, MemberIndex, &DevInterfaceData); //如果獲取信息失敗,則說明設備已經查找完畢,退出循環。 if(Result==FALSE) break; //將MemberIndex指向下一個設備 MemberIndex++; //如果獲取信息成功,則繼續獲取該設備的詳細信息。在獲取設備 //詳細信息時,需要先知道保存詳細信息需要多大的緩衝區,這通過 //第一次調用函數SetupDiGetDeviceInterfaceDetail來獲取。這時 //提供緩衝區和長度都為NULL的參數,並提供一個用來保存需要多大 //緩衝區的變量RequiredSize。 Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, NULL, NULL, &RequiredSize, NULL); //然後,分配一個大小為RequiredSize緩衝區,用來保存設備詳細信息。 pDevDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize); if(pDevDetailData==NULL) //如果內存不足,則直接返回。 { //MessageBox("內存不足!"); SetupDiDestroyDeviceInfoList(hDevInfoSet); return FALSE; } //並設置pDevDetailData的cbSize為結構體的大小(注意只是結構體大小, //不包括後面緩衝區)。 pDevDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //然後再次調用SetupDiGetDeviceInterfaceDetail函數來獲取設備的 //詳細信息。這次調用設置使用的緩衝區以及緩衝區大小。 Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, pDevDetailData, RequiredSize, NULL, NULL); //將設備路徑複製出來,然後銷毀剛剛申請的內存。 //MyDevPathName=pDevDetailData->DevicePath; //_tcscpy(MyDevPathName, pDevDetailData->DevicePath); wcscpy_s(MyDevPathName, pDevDetailData->DevicePath); free(pDevDetailData); //如果調用失敗,則查找下一個設備。 if(Result==FALSE) continue; //如果調用成功,則使用不帶讀寫訪問的CreateFile函數 //來獲取設備的屬性,包括VID、PID、版本號等。 //對於一些獨佔設備(例如USB鍵盤),使用讀訪問方式是無法打開的, //而使用不帶讀寫訪問的格式才可以打開這些設備,從而獲取設備的屬性。 hDevHandle=CreateFile(MyDevPathName, NULL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //如果打開成功,則獲取設備屬性。 if(hDevHandle!=INVALID_HANDLE_VALUE) { //獲取設備的屬性並保存在DevAttributes結構體中 Result=HidD_GetAttributes(hDevHandle, &DevAttributes); //關閉剛剛打開的設備 CloseHandle(hDevHandle); //獲取失敗,查找下一個 if(Result==FALSE) continue; //如果獲取成功,則將屬性中的VID、PID以及設備版本號與我們需要的 //進行比較,如果都一致的話,則說明它就是我們要找的設備。 if(DevAttributes.VendorID == usVID && DevAttributes.ProductID == usPID){ MyDevFound=TRUE; //設置設備已經找到 //AddToInfOut("設備已經找到"); //那麼就是我們要找的設備,分別使用讀寫方式打開之,並保存其句柄 //並且選擇為異步訪問方式。 //讀方式打開設備 m_hReadHandle=CreateFile(MyDevPathName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, FILE_ATTRIBUTE_NORMAL, NULL); //if(hReadHandle!=INVALID_HANDLE_VALUE)AddToInfOut("讀訪問打開設備成功"); //else AddToInfOut("讀訪問打開設備失敗"); //寫方式打開設備 m_hWriteHandle=CreateFile(MyDevPathName, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, FILE_ATTRIBUTE_NORMAL, NULL); //if(hWriteHandle!=INVALID_HANDLE_VALUE)AddToInfOut("寫訪問打開設備成功"); //else AddToInfOut("寫訪問打開設備失敗"); //手動觸發事件,讓讀報告線程恢復運行。因為在這之前並沒有調用 //讀數據的函數,也就不會引起事件的產生,所以需要先手動觸發一 //次事件,讓讀報告線程恢復運行。 //SetEvent(ReadOverlapped.hEvent); //顯示設備的狀態。 //SetDlgItemText(IDC_DS,"設備已打開"); //找到設備,退出循環。本程序只檢測一個目標設備,查找到後就退出 //查找了。如果你需要將所有的目標設備都列出來的話,可以設置一個 //數組,找到後就保存在數組中,直到所有設備都查找完畢才退出查找 break; } } //如果打開失敗,則查找下一個設備 else continue; } //調用SetupDiDestroyDeviceInfoList函數銷毀設備信息集合 SetupDiDestroyDeviceInfoList(hDevInfoSet); //如果設備已經找到,那麼應該使能各操作按鈕,並同時禁止打開設備按鈕 return MyDevFound; }
NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device, LPCWSTR serial, LPCWSTR index) { WCHAR regname[255]; WCHAR dev_link[255]; SP_DEVINFO_DATA Data; UNICODE_STRING nameW, linkW; NTSTATUS status; HDEVINFO devinfo; GUID hidGuid; BASE_DEVICE_EXTENSION *ext; HidD_GetHidGuid(&hidGuid); ext = device->DeviceExtension; sprintfW(dev_link, device_link_fmtW, ext->information.VendorID, ext->information.ProductID, index, ext->information.VersionNumber, serial, class_guid); struprW(dev_link); RtlInitUnicodeString( &nameW, ext->device_name); RtlInitUnicodeString( &linkW, dev_link ); TRACE("Create link %s\n", debugstr_w(dev_link)); ext->link_name = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(dev_link) + 1)); lstrcpyW(ext->link_name, dev_link); status = IoCreateSymbolicLink( &linkW, &nameW ); if (status) { FIXME( "failed to create link error %x\n", status ); return status; } sprintfW(regname, device_regname_fmtW, ext->information.VendorID, ext->information.ProductID, index, ext->information.VersionNumber, serial); devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_HIDCLASS, NULL, NULL, DIGCF_DEVICEINTERFACE); if (!devinfo) { FIXME( "failed to get ClassDevs %x\n", GetLastError()); return GetLastError(); } Data.cbSize = sizeof(Data); if (!SetupDiCreateDeviceInfoW(devinfo, regname, &GUID_DEVCLASS_HIDCLASS, NULL, NULL, DICD_INHERIT_CLASSDRVS, &Data)) { if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) { SetupDiDestroyDeviceInfoList(devinfo); return ERROR_SUCCESS; } FIXME( "failed to Create Device Info %x\n", GetLastError()); return GetLastError(); } if (!SetupDiRegisterDeviceInfo( devinfo, &Data, 0, NULL, NULL, NULL )) { FIXME( "failed to Register Device Info %x\n", GetLastError()); return GetLastError(); } if (!SetupDiCreateDeviceInterfaceW( devinfo, &Data, &hidGuid, NULL, 0, NULL)) { FIXME( "failed to Create Device Interface %x\n", GetLastError()); return GetLastError(); } SetupDiDestroyDeviceInfoList(devinfo); return S_OK; }
static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type_win32(int vid, int pid) { /* TODO: Remove the check for !defined(_MSC_VER) after making sure this builds on MSVC */ /* HID API is available since Windows 2000 */ #if defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) && _WIN32_WINNT >= 0x0500 HDEVINFO hDeviceInfo; SP_DEVINFO_DATA DeviceInfoData; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; HANDLE hDeviceHandle = INVALID_HANDLE_VALUE; BOOL bResult = TRUE; BOOL success = FALSE; GUID guidDeviceInterface = {0}; PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL; ULONG requiredLength = 0; LPTSTR lpDevicePath = NULL; char *devicePath = NULL; DWORD index = 0; DWORD intIndex = 0; size_t nLength = 0; unsigned len = 0; unsigned i = 0; char vidPidString[32] = {0}; char vidString[5] = {0}; char pidString[5] = {0}; char report[USB_PACKET_CTRL_LEN + 1] = {0}; snprintf(vidString, sizeof(vidString), "%04x", vid); snprintf(pidString, sizeof(pidString), "%04x", pid); strlcat(vidPidString, "vid_", sizeof(vidPidString)); strlcat(vidPidString, vidString, sizeof(vidPidString)); strlcat(vidPidString, "&pid_", sizeof(vidPidString)); strlcat(vidPidString, pidString, sizeof(vidPidString)); HidD_GetHidGuid(&guidDeviceInterface); if (!memcmp(&guidDeviceInterface, &GUID_NULL, sizeof(GUID_NULL))) { RARCH_ERR("[Autoconf]: null guid\n"); return NULL; } /* Get information about all the installed devices for the specified * device interface class. */ hDeviceInfo = SetupDiGetClassDevs( &guidDeviceInterface, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDeviceInfo == INVALID_HANDLE_VALUE) { RARCH_ERR("[Autoconf]: Error in SetupDiGetClassDevs: %d.\n", GetLastError()); goto done; } /* Enumerate all the device interfaces in the device information set. */ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); while (!success) { success = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); /* Reset for this iteration */ if (lpDevicePath) { LocalFree(lpDevicePath); lpDevicePath = NULL; } if (pInterfaceDetailData) { LocalFree(pInterfaceDetailData); pInterfaceDetailData = NULL; } /* Check if this is the last item */ if (GetLastError() == ERROR_NO_MORE_ITEMS) break; deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); /* Get information about the device interface. */ for (intIndex = 0; (bResult = SetupDiEnumDeviceInterfaces( hDeviceInfo, &DeviceInfoData, &guidDeviceInterface, intIndex, &deviceInterfaceData)); intIndex++) { /* Check if this is the last item */ if (GetLastError() == ERROR_NO_MORE_ITEMS) break; /* Check for some other error */ if (!bResult) { RARCH_ERR("[Autoconf]: Error in SetupDiEnumDeviceInterfaces: %d.\n", GetLastError()); goto done; } /* Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA * which we need to allocate, so we have to call this function twice. * First to get the size so that we know how much to allocate, and * second to do the actual call with the allocated buffer. */ bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL); /* Check for some other error */ if (!bResult) { if ((ERROR_INSUFFICIENT_BUFFER == GetLastError()) && (requiredLength > 0)) { /* we got the size, now allocate buffer */ pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength); if (!pInterfaceDetailData) { RARCH_ERR("[Autoconf]: Error allocating memory for the device detail buffer.\n"); goto done; } } else { RARCH_ERR("[Autoconf]: Other error: %d.\n", GetLastError()); goto done; } } /* get the interface detailed data */ pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); /* Now call it with the correct size and allocated buffer */ bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo, &deviceInterfaceData, pInterfaceDetailData, requiredLength, NULL, &DeviceInfoData); /* Check for some other error */ if (!bResult) { RARCH_LOG("[Autoconf]: Error in SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError()); goto done; } /* copy device path */ nLength = _tcslen(pInterfaceDetailData->DevicePath) + 1; lpDevicePath = (TCHAR*)LocalAlloc(LPTR, nLength * sizeof(TCHAR)); StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath); devicePath = (char*)malloc(nLength); for (len = 0; len < nLength; len++) devicePath[len] = lpDevicePath[len]; lpDevicePath[nLength - 1] = 0; if (strstr(devicePath, vidPidString)) goto found; } success = FALSE; index++; } if (!lpDevicePath) { RARCH_ERR("[Autoconf]: No devicepath. Error %d.", GetLastError()); goto done; } found: /* Open the device */ hDeviceHandle = CreateFileA( devicePath, GENERIC_READ, /* | GENERIC_WRITE,*/ FILE_SHARE_READ, /* | FILE_SHARE_WRITE,*/ NULL, OPEN_EXISTING, 0, /*FILE_FLAG_OVERLAPPED,*/ NULL); if (hDeviceHandle == INVALID_HANDLE_VALUE) { /* Windows sometimes erroneously fails to open with a sharing violation: * https://github.com/signal11/hidapi/issues/231 * If this happens, trying again with read + write usually works for some reason. */ /* Open the device */ hDeviceHandle = CreateFileA( devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, /*FILE_FLAG_OVERLAPPED,*/ NULL); if (hDeviceHandle == INVALID_HANDLE_VALUE) { RARCH_ERR("[Autoconf]: Can't open device for reading and writing: %d.", GetLastError()); runloop_msg_queue_push("Bliss-Box already in use. Please make sure other programs are not using it.", 2, 300, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); goto done; } } done: free(devicePath); LocalFree(lpDevicePath); LocalFree(pInterfaceDetailData); bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo); devicePath = NULL; lpDevicePath = NULL; pInterfaceDetailData = NULL; if (!bResult) RARCH_ERR("[Autoconf]: Could not destroy device info list.\n"); if (!hDeviceHandle || hDeviceHandle == INVALID_HANDLE_VALUE) { /* device is not connected */ return NULL; } report[0] = BLISSBOX_USB_FEATURE_REPORT_ID; HidD_GetFeature(hDeviceHandle, report, sizeof(report)); CloseHandle(hDeviceHandle); for (i = 0; i < sizeof(blissbox_pad_types) / sizeof(blissbox_pad_types[0]); i++) { const blissbox_pad_type_t *pad = &blissbox_pad_types[i]; if (!pad || string_is_empty(pad->name)) continue; if (pad->index == report[0]) return pad; } RARCH_LOG("[Autoconf]: Could not find connected pad in Bliss-Box port#%d.\n", pid - BLISSBOX_PID); #endif return NULL; }
bool AIOTestAdapter::open() { GUID HidGuid; SP_DEVICE_INTERFACE_DATA devInfoData; int index = 0; BOOL result; bool done = false; MemoryBlock detailDataBlock(1024); HidD_GetHidGuid(&HidGuid); HANDLE hDevInfo = SetupDiGetClassDevs (&HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); devInfoData.cbSize = sizeof(devInfoData); do { result = SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, index, &devInfoData); if (result) { PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; ULONG bytesNeeded; SetupDiGetDeviceInterfaceDetail (hDevInfo, &devInfoData, NULL, 0, &bytesNeeded, NULL); if (bytesNeeded > detailDataBlock.getSize()) { detailDataBlock.setSize(bytesNeeded); } detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detailDataBlock.getData(); detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); SetupDiGetDeviceInterfaceDetail (hDevInfo, &devInfoData, detailData, detailDataBlock.getSize(), &bytesNeeded, NULL); deviceHandle = CreateFile (detailData->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); if (deviceHandle != INVALID_HANDLE_VALUE) { HIDD_ATTRIBUTES attributes; zerostruct(attributes); attributes.Size = sizeof(attributes); BOOL attributes_result = HidD_GetAttributes(deviceHandle,&attributes); if (attributes_result && ECHO_VENDOR_ID == attributes.VendorID) { bool match = false; switch (attributes.ProductID) { #if SUPPORT_TEST_ADAPTER_V200 case ECHO_HID_TESTER_PRODUCT_ID_V100: case ECHO_HID_TESTER_PRODUCT_ID_V200: #endif case ECHO_HID_TESTER_PRODUCT_ID_V210: DBG("Test adapter found"); match = true; productIDs.add(attributes.ProductID); break; } if (match) { readHandle = CreateFile (detailData->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); writeHandle = CreateFile (detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); break; } } CloseHandle(deviceHandle); deviceHandle = INVALID_HANDLE_VALUE; } } else { done = true; } index++; } while (false == done); SetupDiDestroyDeviceInfoList(hDevInfo); return deviceHandle != INVALID_HANDLE_VALUE && readHandle != INVALID_HANDLE_VALUE && writeHandle != INVALID_HANDLE_VALUE; }
std::vector<device> find_devices(size_t max_wiimotes) { // VID = Nintendo, PID = Wiimote // must be sorted! static std::pair<USHORT, USHORT> const vid_pids[] = { std::make_pair(0x0001, 0x0002), std::make_pair(0x0002, 0x00f7), std::make_pair(0x057e, 0x0306), }; auto const vid_pids_end = vid_pids + 3; // TODO: s/3/sizeof... std::vector<device> found_wiimotes; // Get the device id GUID device_id; HidD_GetHidGuid(&device_id); // Get all hid devices connected HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, nullptr, nullptr, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); DWORD index = 0; while (found_wiimotes.size() != max_wiimotes) { // Query the next hid device info SP_DEVICE_INTERFACE_DATA device_data; device_data.cbSize = sizeof(device_data); if (!SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index++, &device_data)) break; // Get the size of the data block required DWORD len = 0; SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr); std::unique_ptr<u8> const detail_array(new u8[len]); PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detail_array.get(); detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Query the data for this device if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr, nullptr)) continue; // Open new device HANDLE const dev = CreateFile(detail_data->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); if (INVALID_HANDLE_VALUE == dev) continue; // Get device attributes HIDD_ATTRIBUTES attr; attr.Size = sizeof(attr); HidD_GetAttributes(dev, &attr); if (std::binary_search(vid_pids, vid_pids_end, std::make_pair(attr.VendorID, attr.ProductID))) { // This is a wiimote found_wiimotes.push_back(device(dev)); } else CloseHandle(dev); } SetupDiDestroyDeviceInfoList(device_info); return found_wiimotes; }
int thirdspacevest_open_win32(thirdspacevest_device* dev, unsigned int device_index, int get_count) { //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. HIDD_ATTRIBUTES Attributes; SP_DEVICE_INTERFACE_DATA devInfoData; BOOL LastDevice = FALSE; int MemberIndex = 0; LONG Result; int device_count = 0; Length = 0; detailData = NULL; dev->_dev = NULL; /* 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 Requires: The DeviceInfoSet returned in SetupDiGetClassDevs. The HidGuid returned in GetHidGuid. An index to specify a */ 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 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 // 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 Requires: The DevicePath in the detailData structure returned by SetupDiGetDeviceInterfaceDetail. */ dev->_dev =CreateFile (detailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); /* API function: HidD_GetAttributes Requests information from the 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 (dev->_dev, &Attributes); //Is it the desired device? MyDeviceDetected = FALSE; if ((Attributes.VendorID == THIRDSPACEVEST_VID && Attributes.ProductID == THIRDSPACEVEST_PID)) { if(get_count) { ++device_count; CloseHandle(dev->_dev); } else { MyDeviceDetected = TRUE; MyDevicePathName = detailData->DevicePath; GetDeviceCapabilities(dev->_dev); break; } } else { CloseHandle(dev->_dev); } free(detailData); } //if (Result != 0) else { LastDevice=TRUE; } //If we haven't found the device yet, and haven't tried every available device, //try the next one. MemberIndex = MemberIndex + 1; } while (!LastDevice); SetupDiDestroyDeviceInfoList(hDevInfo); if(get_count) return device_count; if(MyDeviceDetected) return 0; return -1; }
int usbOpenDevice(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 = USB_ERROR_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 = USB_ERROR_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 = USB_ERROR_NOTFOUND; if(vendorName != NULL && productName != NULL){ char buffer[512]; if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ DEBUG_PRINT(("error obtaining vendor name\n")); errorCode = USB_ERROR_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 = USB_ERROR_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; }
bool CLCDConnectionLogitech::HIDInit() { if (GetConnectionState() != CONNECTED || m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //LGLCD_DEVICE_FAMILY_KEYBOARD_G15) return false; // Logitech G15 int VendorID = 0x046d; int ProductID = 0xc222; //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. HIDD_ATTRIBUTES Attributes; SP_DEVICE_INTERFACE_DATA devInfoData; bool LastDevice = FALSE; int MemberIndex = 0; LONG Result; DWORD Length = 0; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; HANDLE hDevInfo = NULL; GUID HidGuid; ULONG Required = 0; bool MyDeviceDetected = false; /* 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. */ m_hHIDDeviceHandle = CreateFile (detailData->DevicePath, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 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 (m_hHIDDeviceHandle, &Attributes); //Is it the desired device? MyDeviceDetected = FALSE; if (Attributes.VendorID == VendorID) { if (Attributes.ProductID == ProductID) { //Both the Vendor ID and Product ID match. MyDeviceDetected = TRUE; } else CloseHandle(m_hHIDDeviceHandle); } else CloseHandle(m_hHIDDeviceHandle); //Free the memory used by the detailData structure (no longer needed). free(detailData); } else LastDevice = TRUE; MemberIndex = MemberIndex + 1; } //do while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); if (MyDeviceDetected) { PHIDP_PREPARSED_DATA PreparsedData; HidD_GetPreparsedData (m_hHIDDeviceHandle, &PreparsedData); HidP_GetCaps (PreparsedData, &m_HIDCapabilities); HidD_FreePreparsedData(PreparsedData); } //Free the memory reserved for hDevInfo by SetupDiClassDevs. SetupDiDestroyDeviceInfoList(hDevInfo); return MyDeviceDetected; }
BOOL CUSBDrive::WriteData(LPVOID lpBuffer) { if(m_HidHandle == INVALID_HANDLE_VALUE) { /* //MessageBox("设备未连接"); return false; } char reportbuf[9]; ::memcpy( &reportbuf[1],lpBuffer,8); reportbuf[0]=0; OVERLAPPED op={0}; HANDLE hEvent=CreateEvent(NULL,false,false,NULL); op.hEvent=hEvent; ULONG nWritten; if(!WriteFile(m_HidHandle, &reportbuf[0],9,&nWritten, &op))//0)) { DWORD dwErr=::GetLastError(); //AfxMessageBox("发送erase command失败!"); if(dwErr != ERROR_IO_PENDING ) { CloseHandle(hEvent); return false; } else { DWORD dwObj=WaitForSingleObject(op.hEvent,50); if(dwObj==WAIT_OBJECT_0) { CloseHandle(hEvent); return true; } else if(dwObj==WAIT_TIMEOUT) { CancelIo(m_HidHandle); CloseHandle(hEvent); return false; } } // return false; } //AfxMessageBox("发送erase command ok! 3s后可以写flash"); CloseHandle(hEvent); return true;*/ } BOOL CUSBDrive::ReadData(LPVOID lpBuffer) { if(m_HidHandle == INVALID_HANDLE_VALUE) { //MessageBox("设备未连接"); return false; } char reportbuf[9]; memset(reportbuf,0,9); // reportbuf[0]=2; OVERLAPPED op={0}; HANDLE hEvent=CreateEvent(NULL,false,false,NULL); op.hEvent=hEvent; ULONG nWritten; if(!ReadFile(m_HidHandle, &reportbuf[0],9,&nWritten, &op))//0)) { DWORD dwErr=::GetLastError(); //AfxMessageBox("发送erase command失败!"); if(dwErr != ERROR_IO_PENDING ) { CloseHandle(hEvent); return false; } else { DWORD dwObj=WaitForSingleObject(op.hEvent,1200); if(dwObj==WAIT_OBJECT_0) { ::memcpy(lpBuffer,&reportbuf[1],8); CloseHandle(hEvent); return true; } else if(dwObj==WAIT_TIMEOUT) { CancelIo(m_HidHandle); CloseHandle(hEvent); return false; } } // return false; } ::memcpy(lpBuffer,&reportbuf[1],8); //AfxMessageBox("发送erase command ok! 3s后可以写flash"); CloseHandle(hEvent); return true; } HANDLE CUSBDrive::FindHandle() { HANDLE hidHandle=INVALID_HANDLE_VALUE; //查找本系统中HID类的GUID标识 GUID hidGuid; HidD_GetHidGuid(&hidGuid); //准备查找符合HID规范的USB设备,获取HID类设备信息集 HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if(hDevInfo==INVALID_HANDLE_VALUE) { //m_Status.SetWindowText("获取HID设备信息失败!"); hidHandle=INVALID_HANDLE_VALUE; return hidHandle; } SP_DEVICE_INTERFACE_DATA devInfoData; devInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); int deviceNo = 0; BOOL bSuccess=false; // SetLastError(NO_ERROR); // while(GetLastError() != ERROR_NO_MORE_ITEMS) do { // 枚举设备接口信息 bSuccess=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &hidGuid, deviceNo, &devInfoData); //找到了可用的USB设备 if(bSuccess&&(GetLastError()!=ERROR_NO_MORE_ITEMS)) { //若找到了一个USB设备,则获取该设备的细节信息 ULONG requiredLength = 0; PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail; SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &requiredLength, NULL); devDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (requiredLength); devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if(! SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, devDetail, requiredLength, NULL, NULL)) { //AfxMessageBox("获取HID设备细节信息失败!"); free(devDetail); hidHandle=INVALID_HANDLE_VALUE; return hidHandle; } hidHandle = CreateFile(devDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL, //NULL, NULL); DWORD err; err=GetLastError(); free(devDetail); if(hidHandle==INVALID_HANDLE_VALUE) { // AfxMessageBox("获取HID设备句柄失败!"); ++deviceNo; continue; } HIDD_ATTRIBUTES hidAttributes; if(!HidD_GetAttributes(hidHandle, &hidAttributes)) { // AfxMessageBox("获取HID设备属性失败!"); CloseHandle(hidHandle); hidHandle=INVALID_HANDLE_VALUE; return hidHandle; } if(USB_VID == hidAttributes.VendorID && //USB_VID USB_PID == hidAttributes.ProductID && //USB_PID USBRS232_VERSION == hidAttributes.VersionNumber) { SetupDiDestroyDeviceInfoList(hDevInfo); return hidHandle; } else { CloseHandle(hidHandle); ++deviceNo; } } else break;//没有找到可用的设备或者没找到更多的可用设备 }while(bSuccess); SetupDiDestroyDeviceInfoList(hDevInfo); hidHandle=INVALID_HANDLE_VALUE; return hidHandle; } BOOL CUSBDrive::WriteData(int Address, unsigned char Data) { unsigned char buf[8]; buf[0]=(char)WriteCommandWord; buf[3]=(char)EndMark; buf[4]=(char)WriteCommandWord; buf[5]=Data; buf[6]=(char)0x00; buf[7]=(char)EndMark; unsigned char ADDR_H = Address/256; unsigned char ADDR_L = Address%256; buf[1]=ADDR_H; buf[2]=ADDR_L; if(!WriteData(buf)) return FALSE; if(!ReadData(buf)) return FALSE; for (int i = 0; i < 8; i++){ if(buf[i] != 0xA5) return FALSE; } return TRUE; }
s_hid_dev * hidasync_enumerate(unsigned short vendor, unsigned short product) { s_hid_dev * hid_devs = NULL; unsigned int nb_hid_devs = 0; GUID guid; HidD_GetHidGuid(&guid); HDEVINFO info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(info != INVALID_HANDLE_VALUE) { int index; for(index = 0; ; ++index) { SP_DEVICE_INTERFACE_DATA iface; iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface) == FALSE) { break; //no more device } DWORD reqd_size; if(SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL) == FALSE) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; } } SP_DEVICE_INTERFACE_DETAIL_DATA * details = calloc(reqd_size, sizeof(char)); if(details == NULL) { fprintf(stderr, "%s:%d calloc failed\n", __FILE__, __LINE__); continue; } details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL) == FALSE) { ASYNC_PRINT_ERROR("SetupDiGetDeviceInterfaceDetail") free(details); continue; } int device = open_path(details->DevicePath, 0); free(details); if(device >= 0) { if(vendor) { if (devices[device].hidInfo.vendor_id != vendor) { async_close(device); continue; } if(product) { if(devices[device].hidInfo.product_id != product) { async_close(device); continue; } } } char * path = strdup(devices[device].path); if(path == NULL) { PRINT_ERROR_OTHER("strdup failed") async_close(device); continue; } void * ptr = realloc(hid_devs, (nb_hid_devs + 1) * sizeof(*hid_devs)); if(ptr == NULL) { PRINT_ERROR_ALLOC_FAILED("realloc") free(path); async_close(device); continue; } hid_devs = ptr; if(nb_hid_devs > 0) { hid_devs[nb_hid_devs - 1].next = 1; } hid_devs[nb_hid_devs].path = path; hid_devs[nb_hid_devs].vendor_id = devices[device].hidInfo.vendor_id; hid_devs[nb_hid_devs].product_id = devices[device].hidInfo.product_id; hid_devs[nb_hid_devs].next = 0; ++nb_hid_devs; async_close(device); } } } return hid_devs; }
bool Controller::registerController(int pDeviceId) { //Required variables to iterate over the device interface DWORD result = 0; LPGUID hidguid = (LPGUID)malloc(sizeof(GUID)); HDEVINFO deviceset; PSP_DEVICE_INTERFACE_DATA deviceInterfaceData = nullptr; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceInfo = nullptr; DWORD buffersize = 0; //malloc check CHECK_NULL(hidguid, SETUP_ERROR); //get hid guid HidD_GetHidGuid(hidguid); //get device list deviceset = SetupDiGetClassDevs(hidguid, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceset == INVALID_HANDLE_VALUE) { goto SETUP_ERROR; } int deviceindex = 0; deviceInterfaceData = (PSP_DEVICE_INTERFACE_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DATA)); //malloc check CHECK_NULL(deviceInterfaceData, SETUP_ERROR); deviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //iterate through devices while (SetupDiEnumDeviceInterfaces(deviceset, nullptr, hidguid, deviceindex, deviceInterfaceData)) { //this should fail originally in order to get buffer size if (deviceInterfaceInfo != nullptr) { free(deviceInterfaceInfo); deviceInterfaceInfo = 0; } if (SetupDiGetDeviceInterfaceDetail(deviceset, deviceInterfaceData, nullptr, 0, (PDWORD)&buffersize, nullptr) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto SETUP_ERROR; } deviceInterfaceInfo = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(buffersize); //malloc check CHECK_NULL(deviceInterfaceInfo, SETUP_ERROR); deviceInterfaceInfo->cbSize = sizeof(*deviceInterfaceInfo); //device info buffer allocated, get details if (!SetupDiGetDeviceInterfaceDetail(deviceset, deviceInterfaceData, deviceInterfaceInfo, buffersize, (PDWORD)&buffersize, nullptr)) { goto SETUP_ERROR; } //you must pass in the device id of the hid client to read from if (deviceindex == pDeviceId) { _controllerHandle = CreateFile( deviceInterfaceInfo->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ); if (_controllerHandle == INVALID_HANDLE_VALUE) { Log(L"Error opening HID Device: Error No: %d", GetLastError()); goto HID_SETUP_FAILURE; } else { //get preparsed data if (HidD_GetPreparsedData(_controllerHandle, &_pPreparsedData) == FALSE) { goto HID_SETUP_FAILURE; } //get device capabilities _pCaps = (PHIDP_CAPS)(malloc(sizeof(HIDP_CAPS))); //malloc check CHECK_NULL(_pCaps, HID_SETUP_FAILURE); _succ = HidP_GetCaps(_pPreparsedData, _pCaps); CHECK_HID(_succ, HID_SETUP_FAILURE); //get button capabilities _pButtonCaps = (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS)* _pCaps->NumberInputButtonCaps); //malloc check CHECK_NULL(_pButtonCaps, HID_SETUP_FAILURE); USHORT numInputButtonCaps = _pCaps->NumberInputButtonCaps; _succ = HidP_GetButtonCaps(HidP_Input, _pButtonCaps, &numInputButtonCaps, _pPreparsedData); CHECK_HID(_succ, HID_SETUP_FAILURE); //prep the button usage data structs _pButtonUsages = (PUSAGE)malloc(sizeof(USAGE)*(_pButtonCaps->Range.DataIndexMax - _pButtonCaps->Range.DataIndexMin + 1)); //malloc check CHECK_NULL(_pButtonUsages, HID_SETUP_FAILURE); ULONG numButtonUsages = _pButtonCaps->Range.UsageMax - _pButtonCaps->Range.UsageMin + 1; //get max data length _pInputReport = (PCHAR)malloc(_pCaps->InputReportByteLength); //malloc check CHECK_NULL(_pInputReport, HID_SETUP_FAILURE); DWORD readbytecount = 0; //get value caps _pValueCaps = (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS)* _pCaps->NumberInputValueCaps); //malloc check CHECK_NULL(_pValueCaps, HID_SETUP_FAILURE); USHORT numInputValueCaps = _pCaps->NumberInputValueCaps; _succ = HidP_GetValueCaps(HidP_Input, _pValueCaps, &numInputValueCaps, _pPreparsedData); CHECK_HID(_succ, HID_SETUP_FAILURE); goto SETUP_DONE; HID_SETUP_FAILURE: clearHidStructures(); return false; } } deviceindex++; deviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); } goto SETUP_DONE; SETUP_ERROR: int err = GetLastError(); return false; SETUP_DONE: if (deviceset != INVALID_HANDLE_VALUE && deviceset != nullptr) { SetupDiDestroyDeviceInfoList(deviceset); } if (hidguid != nullptr) { free(hidguid); } if (deviceInterfaceData != nullptr) { free(deviceInterfaceData); } if (deviceInterfaceInfo != nullptr) { free(deviceInterfaceInfo); } return true; }
_HS_INIT() { HidD_GetHidGuid(&hid_guid); InitializeCriticalSection(&controllers_lock); }
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) { BOOL res; struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; /* Windows objects for interacting with the driver. */ GUID InterfaceClassGuid; HidD_GetHidGuid(&InterfaceClassGuid); SP_DEVINFO_DATA devinfo_data; SP_DEVICE_INTERFACE_DATA device_interface_data; SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; int device_index = 0; int i; if (hid_init() < 0) return NULL; /* Initialize the Windows objects. */ memset(&devinfo_data, 0x0, sizeof(devinfo_data)); devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); /* Get information for all the devices belonging to the HID class. */ device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); /* Iterate over each device in the HID class, looking for the right one. */ for (;;) { HANDLE write_handle = INVALID_HANDLE_VALUE; DWORD required_size = 0; HIDD_ATTRIBUTES attrib; res = SetupDiEnumDeviceInterfaces(device_info_set, NULL, &InterfaceClassGuid, device_index, &device_interface_data); if (!res) { /* A return of FALSE from this function means that there are no more devices. */ break; } /* Call with 0-sized detail size, and let the function tell us how long the detail struct needs to be. The size is put in &required_size. */ res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, NULL, 0, &required_size, NULL); /* Allocate a long enough structure for device_interface_detail_data. */ device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); /* Get the detailed data for this device. The detail data gives us the device path for this device, which is then passed into CreateFile() to get a handle to the device. */ res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, device_interface_detail_data, required_size, NULL, NULL); if (!res) { /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); Continue to the next device. */ goto cont; } /* Make sure this device is of Setup Class "HIDClass" and has a driver bound to it. */ for (i = 0; ; i++) { char driver_name[256]; /* Populate devinfo_data. This function will return failure when there are no more interfaces left. */ res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); if (!res) goto cont; res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); if (!res) goto cont; if (strcmp(driver_name, "HIDClass") == 0) { /* See if there's a driver bound. */ res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); if (res) break; } } //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); /* Open a handle to the device */ write_handle = open_device(device_interface_detail_data->DevicePath, TRUE); /* Check validity of write_handle. */ if (write_handle == INVALID_HANDLE_VALUE) { /* Unable to open the device. */ //register_error(dev, "CreateFile"); goto cont_close; } /* Get the Vendor ID and Product ID for this device. */ attrib.Size = sizeof(HIDD_ATTRIBUTES); HidD_GetAttributes(write_handle, &attrib); //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); /* Check the VID/PID to see if we should add this device to the enumeration list. */ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && (product_id == 0x0 || attrib.ProductID == product_id)) { #define WSTR_LEN 512 const char *str; struct hid_device_info *tmp; PHIDP_PREPARSED_DATA pp_data = NULL; HIDP_CAPS caps; BOOLEAN res; NTSTATUS nt_res; wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ size_t len; /* VID/PID match. Create the record. */ tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Get the Usage Page and Usage for this device. */ res = HidD_GetPreparsedData(write_handle, &pp_data); if (res) { nt_res = HidP_GetCaps(pp_data, &caps); if (nt_res == HIDP_STATUS_SUCCESS) { cur_dev->usage_page = caps.UsagePage; cur_dev->usage = caps.Usage; } HidD_FreePreparsedData(pp_data); } /* Fill out the record */ cur_dev->next = NULL; str = device_interface_detail_data->DevicePath; if (str) { len = strlen(str); cur_dev->path = (char*) calloc(len+1, sizeof(char)); strncpy(cur_dev->path, str, len+1); cur_dev->path[len] = '\0'; } else cur_dev->path = NULL; /* Serial Number */ res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->serial_number = _wcsdup(wstr); } /* Manufacturer String */ res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->manufacturer_string = _wcsdup(wstr); } /* Product String */ res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->product_string = _wcsdup(wstr); } /* VID/PID */ cur_dev->vendor_id = attrib.VendorID; cur_dev->product_id = attrib.ProductID; /* Release Number */ cur_dev->release_number = attrib.VersionNumber; /* Interface Number. It can sometimes be parsed out of the path on Windows if a device has multiple interfaces. See http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or search for "Hardware IDs for HID Devices" at MSDN. If it's not in the path, it's set to -1. */ cur_dev->interface_number = -1; if (cur_dev->path) { char *interface_component = strstr(cur_dev->path, "&mi_"); if (interface_component) { char *hex_str = interface_component + 4; char *endptr = NULL; cur_dev->interface_number = strtol(hex_str, &endptr, 16); if (endptr == hex_str) { /* The parsing failed. Set interface_number to -1. */ cur_dev->interface_number = -1; } } } } cont_close: CloseHandle(write_handle); cont: /* We no longer need the detail data. It can be freed */ free(device_interface_detail_data); device_index++; } /* Close the device information handle. */ SetupDiDestroyDeviceInfoList(device_info_set); return root; }
bool CUsbhidioc::FindTheHID(int unitNumber) { //Use a series of API calls to find a HID with a matching Vendor and Product ID. HIDD_ATTRIBUTES Attributes; SP_DEVICE_INTERFACE_DATA devInfoData; bool LastDevice = FALSE; int MemberIndex; LONG Result; int unitIndex; char unitIDSerial[64]; //These are the vendor and product IDs to look for. const unsigned int VendorID = 0x04d8; // Uses Microchip's Vendor ID. const unsigned int ProductID = 0x0033; // PICkit 2 Flash Starter Kit Length = 0; detailData = NULL; DeviceHandle=NULL; /* 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; unitIndex = 0; LastDevice = FALSE; do { DeviceDetected=false; /* 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); // **** IMPORTANT **** // sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) should equal 5. // In C++ Builder, go to Project/Options/Advanced Compiler/Data Alignment // and select "byte" align. //Call the function again, this time passing it the returned buffer size. Result = SetupDiGetDeviceInterfaceDetail (hDevInfo, &devInfoData, detailData, Length, &Required, NULL); Result = GetLastError (); //Open a handle to the device. /* 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, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); if ((int)DeviceHandle != -1) { /* 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); if (Result != 0) { //Is it the desired device? DeviceDetected = false; if (Attributes.VendorID == VendorID) { if (Attributes.ProductID == ProductID) { //Both the Product and Vendor IDs match. if (unitNumber == unitIndex) { // Get Unit ID serial string HidD_GetSerialNumberString(DeviceHandle, unitIDSerial, 64); int x = 2; if ((unitIDSerial[0] == 0x09) || (unitIDSerial[0] == 0x00)) { m_UnitID[0] = '-'; m_UnitID[1] = 0; } else { m_UnitID[0] = unitIDSerial[0]; for (; x < 28; x+=2) { m_UnitID[x/2] = unitIDSerial[x]; if ((unitIDSerial[x] == 0) || (unitIDSerial[x] == 0xE0)) break; m_UnitID[x] = 0; m_UnitID[x+1] = 0; } } DeviceDetected = true; PrepareForOverlappedTransfer(); } else { CloseHandle(DeviceHandle); unitIndex++; } } //if (Attributes.ProductID == ProductID) else //The Product ID doesn't match. CloseHandle(DeviceHandle); } //if (Attributes.VendorID == VendorID) else //The Vendor ID doesn't match. CloseHandle(DeviceHandle); //Free the memory used by the detailData structure (no longer needed). free(detailData); } //if (Result != 0) 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) && (DeviceDetected == false) && (MemberIndex < 24)); // check 24 devices max //Free the memory reserved for hDevInfo by SetupDiClassDevs. SetupDiDestroyDeviceInfoList(hDevInfo); return DeviceDetected; }
BOOLEAN FindKnownHidDevices ( OUT PHID_DEVICE * HidDevices, // A array of struct _HID_DEVICE OUT PULONG NumberDevices // the length of this array. ) /*++ Routine Description: Do the required PnP things in order to find all the HID devices in the system at this time. --*/ { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInfoData; ULONG i; BOOLEAN done; PHID_DEVICE hidDeviceInst; GUID hidGuid; PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; PHID_DEVICE newHidDevices; HidD_GetHidGuid (&hidGuid); *HidDevices = NULL; *NumberDevices = 0; // // Open a handle to the plug and play dev node. // hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE)); // Function class devices. // // Take a wild guess to start // *NumberDevices = 4; done = FALSE; deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); i=0; while (!done) { *NumberDevices *= 2; if (*HidDevices) { newHidDevices = realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE))); if (NULL == newHidDevices) { free(*HidDevices); } *HidDevices = newHidDevices; } else { *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE)); } if (NULL == *HidDevices) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } hidDeviceInst = *HidDevices + i; for (; i < *NumberDevices; i++, hidDeviceInst++) { if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs &hidGuid, i, &deviceInfoData)) { // // allocate a function class device data structure to receive the // goods about this particular device. // SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInfoData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL); // not interested in the specific dev-node predictedLength = requiredLength; functionClassDeviceData = malloc (predictedLength); if (functionClassDeviceData) { functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); } else { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } // // Retrieve the information from Plug and Play. // if (! SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return FALSE; } // // Open device with just generic query abilities to begin with // if (! OpenHidDevice (functionClassDeviceData -> DevicePath, FALSE, // ReadAccess - none FALSE, // WriteAccess - none FALSE, // Overlapped - no FALSE, // Exclusive - no hidDeviceInst)) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return FALSE; } } else { if (ERROR_NO_MORE_ITEMS == GetLastError()) { done = TRUE; break; } } } } *NumberDevices = i; SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return TRUE; }
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { GUID device_id; HANDLE dev; HDEVINFO device_info; int i, index; DWORD len; SP_DEVICE_INTERFACE_DATA device_data; PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; HIDD_ATTRIBUTES attr; int found = 0; (void) timeout; /* unused */ device_data.cbSize = sizeof(device_data); index = 0; /* get the device id */ HidD_GetHidGuid(&device_id); /* get all hid devices connected */ device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); for (;; ++index) { if (detail_data) { free(detail_data); detail_data = NULL; } /* query the next hid device info */ if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) { break; } /* get the size of the data block required */ i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*)malloc(len); detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); /* query the data for this device */ if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) { continue; } /* open the device */ dev = CreateFile(detail_data->DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev == INVALID_HANDLE_VALUE) { continue; } /* get device attributes */ attr.Size = sizeof(attr); i = HidD_GetAttributes(dev, &attr); if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) { /* this is a wiimote */ wm[found]->dev_handle = dev; wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, ""); wm[found]->hid_overlap.Offset = 0; wm[found]->hid_overlap.OffsetHigh = 0; WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND); WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); /* try to set the output report to see if the device is actually connected */ if (!wiiuse_set_report_type(wm[found])) { WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); continue; } /* do the handshake */ wiiuse_handshake(wm[found], NULL, 0); WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid); ++found; if (found >= max_wiimotes) { break; } } else { /* not a wiimote */ CloseHandle(dev); } } if (detail_data) { free(detail_data); } SetupDiDestroyDeviceInfoList(device_info); return found; }
unsigned int USBDeviceFactory_DiscoverDevices( LPSKYETEK_DEVICE** lpDevices ) { GUID hidGuid; HDEVINFO deviceInfo; BOOL isSuccess = FALSE; unsigned long bytes = 0; SP_INTERFACE_DEVICE_DATA deviceData; PSP_INTERFACE_DEVICE_DETAIL_DATA deviceInterfaceData = 0; unsigned int ix, deviceCount = 0; size_t size = 0; SKYETEK_STATUS status; if((lpDevices == NULL) || (*lpDevices != NULL)) return 0; g_usbDevCount = 0; HidD_GetHidGuid (&hidGuid); deviceInfo = SetupDiGetClassDevs ( &hidGuid, 0, 0, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE )); if ( deviceInfo == INVALID_HANDLE_VALUE ) return 0; *lpDevices = (LPSKYETEK_DEVICE*)malloc(20 * sizeof(LPSKYETEK_DEVICE)); memset(*lpDevices,0,(20*sizeof(LPSKYETEK_DEVICE))); size = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); for ( ix = 0; ix < 20; ix++ ) { memset( &deviceData, 0, sizeof(SP_INTERFACE_DEVICE_DATA) ); deviceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA); isSuccess = SetupDiEnumDeviceInterfaces ( deviceInfo, 0, &hidGuid, ix, &deviceData); if ( !isSuccess ) { if ( ERROR_NO_MORE_ITEMS == GetLastError() ) break; else continue; } SetupDiGetInterfaceDeviceDetail( deviceInfo, &deviceData, 0, 0, &bytes, 0); deviceInterfaceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(bytes * sizeof(BYTE)); if ( !deviceInterfaceData ) { SetupDiDestroyDeviceInfoList( deviceInfo ); return deviceCount; } memset( deviceInterfaceData, 0, bytes ); deviceInterfaceData->cbSize = size; isSuccess = SetupDiGetInterfaceDeviceDetail( deviceInfo, &deviceData, deviceInterfaceData, bytes, &bytes, 0); if ( !isSuccess ) { free(deviceInterfaceData); SetupDiDestroyDeviceInfoList( deviceInfo ); return deviceCount; } if((_tcsstr(deviceInterfaceData->DevicePath, _T("vid_afef")) != NULL) && (_tcsstr(deviceInterfaceData->DevicePath, _T("pid_0f01")) != NULL)) { /*printf("DevicePath = %s\r\n", deviceInterfaceData->DevicePath);*/ status = USBDeviceFactory_CreateDevice(deviceInterfaceData->DevicePath, &((*lpDevices)[deviceCount])); if( status != SKYETEK_SUCCESS ) { free(deviceInterfaceData); continue; } deviceCount++; } free(deviceInterfaceData); } return deviceCount; }
struct ols_boot_t *BOOT_Init(uint16_t vid, uint16_t pid) { #if IS_WIN32 GUID HidGuid; HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA DevInterfaceData; unsigned long DevIndex = 0; unsigned long DetailsSize; PSP_INTERFACE_DEVICE_DETAIL_DATA pDetails; HANDLE hHidDevice; HIDD_ATTRIBUTES Attr; #endif struct ols_boot_t *ob; int ret; ob = malloc(sizeof(struct ols_boot_t)); if (ob == NULL) { fprintf(stderr, "Not enough memory \n"); return NULL; } memset(ob, 0, sizeof(struct ols_boot_t)); #if IS_WIN32 HidD_GetHidGuid( &HidGuid); hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) { fprintf(stderr, "INVALID_HANDLE_VALUE\n"); return NULL; } DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // iterate thgough all HID devices // this part is inspirated by Diolan's fw_update while(1) { int bad = 0; if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, DevIndex, &DevInterfaceData)) { fprintf(stderr, "Device does not exist\n"); return NULL; } SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, NULL, 0, &DetailsSize, NULL); pDetails = malloc(DetailsSize); if (pDetails == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); fprintf(stderr, "Not enough memory \n"); return NULL; } pDetails->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, pDetails, DetailsSize, NULL, NULL)) { free(pDetails); SetupDiDestroyDeviceInfoList(hDevInfo); fprintf(stderr, "SetupDiGetDeviceInterfaceDetail failed\n"); return NULL; } hHidDevice = CreateFile(pDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hHidDevice == INVALID_HANDLE_VALUE) { bad = 1; } if ((bad == 0) && (!HidD_GetAttributes (hHidDevice, &Attr))) { bad = 2; } if ((bad == 0) && (Attr.VendorID == vid) && (Attr.ProductID == pid)) { ob->hDevice = hHidDevice; free(pDetails); break; } if (bad > 1) { CloseHandle(hHidDevice); } free(pDetails); DevIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); #else ret = libusb_init(&ob->ctx); if (ret != 0) { fprintf(stderr, "libusb_init proobem\n"); } libusb_set_debug(ob->ctx, 4); ob->dev = libusb_open_device_with_vid_pid(ob->ctx, vid, pid); if (ob->dev == NULL) { fprintf(stderr, "USB Device (%04x:%04x) not found, is OLS in bootloader mode ?\n", vid, pid); free(ob); return NULL; } if (libusb_kernel_driver_active(ob->dev, 0)) { // reattach later ob->attach = 1; if (libusb_detach_kernel_driver(ob->dev, 0)) { fprintf(stderr, "Error detaching kernel driver \n"); free(ob); return NULL; } } ret = libusb_claim_interface(ob->dev, 0); if (ret != 0) { fprintf(stderr, "Cannot claim USB device\n"); } ret = libusb_set_interface_alt_setting(ob->dev, 0, 0); if (ret != 0) { fprintf(stderr, "Unable to set alternative interface \n"); } #endif return ob; }