bool USBDeviceWin32::Open(int VID, int PID, int blocksize, int num) { DWORD index = 0; CString path; while ((path = GetUSBDevicePath (index++)) != "") { HANDLE h = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(h == INVALID_HANDLE_VALUE) continue; HIDD_ATTRIBUTES attr; if (!HidD_GetAttributes (h, &attr)) { CloseHandle(h); continue; } CloseHandle(h); if ((VID != -1 && attr.VendorID != VID) && (PID != -1 && attr.ProductID != PID)) continue; /* This isn't it. */ /* The VID and PID match. */ if(num-- > 0) continue; io.Open(path, blocksize); return true; } return false; }
int open_path(const char * path, int print) { int device = async_open_path(path, print); if(device >= 0) { HIDD_ATTRIBUTES attributes = { .Size = sizeof(HIDD_ATTRIBUTES) }; if(HidD_GetAttributes(devices[device].handle, &attributes) == TRUE) { PHIDP_PREPARSED_DATA preparsedData; HIDP_CAPS hidCapabilities; if(HidD_GetPreparsedData(devices[device].handle, &preparsedData) == TRUE) { if(HidP_GetCaps(preparsedData, &hidCapabilities) == HIDP_STATUS_SUCCESS ) { devices[device].write.size = hidCapabilities.OutputReportByteLength; async_set_read_size(device, hidCapabilities.InputReportByteLength); devices[device].hidInfo.vendor_id = attributes.VendorID; devices[device].hidInfo.product_id = attributes.ProductID; devices[device].hidInfo.bcdDevice = attributes.VersionNumber; } else { if (print) { ASYNC_PRINT_ERROR("HidP_GetCaps") } async_close(device); device = -1; } HidD_FreePreparsedData(preparsedData); } else { if (print) { ASYNC_PRINT_ERROR("HidD_GetPreparsedData") } async_close(device); device = -1; } }
bool CUSBDevice::Connect(const DWORD *vendorID, const DWORD *productID, const DWORD *versionNumber) { Disconnect(); handle = INVALID_HANDLE_VALUE; DWORD index = 0; HIDD_ATTRIBUTES deviceAttributes; BOOL matched = FALSE; // LPCWSTR dummy ( L"" ); // while (!matched && (handle = ConnectToIthDevice (index)) != INVALID_HANDLE_VALUE) while (!matched) { if (!HidD_GetAttributes (handle, &deviceAttributes)) return INVALID_HANDLE_VALUE; if ((vendorID == 0 || deviceAttributes.VendorID == *vendorID) && (productID == 0 || deviceAttributes.ProductID == *productID) && (versionNumber == 0 || deviceAttributes.VersionNumber == *versionNumber)) { EventObject = CreateEvent(NULL, TRUE, TRUE, NULL); //Set the members of the overlapped structure. HIDOverlapped.Offset = 0; HIDOverlapped.OffsetHigh = 0; HIDOverlapped.hEvent = EventObject; return true; /* matched */ } CloseHandle (handle); /* not a match - close and try again */ index++; } return false; }
bool HIDDeviceManager::initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const { HIDD_ATTRIBUTES attr; attr.Size = sizeof(attr); if (!HidD_GetAttributes(hidDev, &attr)) return false; desc->VendorId = attr.VendorID; desc->ProductId = attr.ProductID; desc->VersionNumber = attr.VersionNumber; return true; }
int _ykusb_get_vid_pid(void *yk, int *vid, int *pid) { HIDD_ATTRIBUTES devInfo; int rc = HidD_GetAttributes(yk, &devInfo); if (rc) { *vid = devInfo.VendorID; *pid = devInfo.ProductID; return 1; } yk_errno = YK_EUSBERR; return 0; }
BOOL CUSBDrive::CheckHandle() { m_HidHandle=FindHandle(); _HIDD_ATTRIBUTES hidAttributes; if(!HidD_GetAttributes(m_HidHandle, &hidAttributes)) { CloseHandle(m_HidHandle); return false; } return true; }
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; }
BOOLEAN CheckIfOurDevice( HANDLE file, USAGE myUsagePage, USAGE myUsage) { PHIDP_PREPARSED_DATA Ppd = NULL; // The opaque parser info describing this device HIDD_ATTRIBUTES Attributes; // The Attributes of this hid device. HIDP_CAPS Caps; // The Capabilities of this hid device. BOOLEAN result = FALSE; if (!HidD_GetPreparsedData (file, &Ppd)) { printf("Error: HidD_GetPreparsedData failed \n"); goto cleanup; } if (!HidD_GetAttributes(file, &Attributes)) { printf("Error: HidD_GetAttributes failed \n"); goto cleanup; } if (Attributes.VendorID == vmultib_VID && Attributes.ProductID == vmultib_PID) { if (!HidP_GetCaps (Ppd, &Caps)) { printf("Error: HidP_GetCaps failed \n"); goto cleanup; } if ((Caps.UsagePage == myUsagePage) && (Caps.Usage == myUsage)) { printf("Success: Found my device.. \n"); result = TRUE; } } cleanup: if (Ppd != NULL) { HidD_FreePreparsedData (Ppd); } return result; }
int RawInputPad::Open() { PHIDP_PREPARSED_DATA pPreparsedData = NULL; //TODO Better place? LoadMappings(mapVector); memset(&this->ovl, 0, sizeof(OVERLAPPED)); memset(&this->ovlW, 0, sizeof(OVERLAPPED)); //this->padState.initStage = 0; this->doPassthrough = !!conf.DFPPass;//TODO per player this->usbHandle = INVALID_HANDLE_VALUE; std::wstring path; { CONFIGVARIANT var(N_JOYSTICK, CONFIG_TYPE_WCHAR); if (LoadSetting(mPort, APINAME, var)) path = var.wstrValue; else return 1; } this->usbHandle = CreateFileW(path.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if(this->usbHandle != INVALID_HANDLE_VALUE) { this->ovl.hEvent = CreateEvent(0, 0, 0, 0); this->ovlW.hEvent = CreateEvent(0, 0, 0, 0); HidD_GetAttributes(this->usbHandle, &(this->attr)); HidD_GetPreparsedData(this->usbHandle, &pPreparsedData); HidP_GetCaps(pPreparsedData, &(this->caps)); HidD_FreePreparsedData(pPreparsedData); return 0; } else fwprintf(stderr, L"Could not open device '%s'.\nPassthrough and FFB will not work.\n", path.c_str()); return 1; }
// 获取设备一些能力信息 USBHIDDLL_API void __stdcall USBHIDGetDeviceCapabilities(USBHANDLE handle, PHIDD_ATTRIBUTES attributes, PHIDP_CAPS caps) { if (handle != INVALID_HANDLE_VALUE) { HidD_GetAttributes(handle, attributes); //Get the Capabilities structure for the device. PHIDP_PREPARSED_DATA PreparsedData; /* API function: HidD_GetPreparsedData Returns: a pointer to a buffer containing the information about the device's capabilities. Requires: A handle returned by CreateFile. There's no need to access the buffer directly, but HidP_GetCaps and other API functions require a pointer to the buffer. */ HidD_GetPreparsedData (handle, &PreparsedData); //DisplayLastError("HidD_GetPreparsedData: "); /* API function: HidP_GetCaps Learn the device's capabilities. For standard devices such as joysticks, you can find out the specific capabilities of the device. For a custom device, the software will probably know what the device is capable of, and the call only verifies the information. Requires: the pointer to the buffer returned by HidD_GetPreparsedData. Returns: a Capabilities structure containing the information. */ HidP_GetCaps (PreparsedData, caps); //No need for PreparsedData any more, so free the memory it's using. HidD_FreePreparsedData(PreparsedData); //DisplayLastError("HidD_FreePreparsedData: ") ; } }
void parse_info_from_path(hid_event* event, char* device_path) { auto write_handle = open_device(device_path, TRUE); /* Check validity of write_handle. */ if (write_handle == INVALID_HANDLE_VALUE) { /* Unable to open the device. */ //register_error(dev, "CreateFile"); //goto cont_close; return; } //TODO: clean this shit up HIDD_ATTRIBUTES attrib; attrib.Size = sizeof(HIDD_ATTRIBUTES); HidD_GetAttributes(write_handle, &attrib); event->device_info->product_id = attrib.ProductID; event->device_info->vendor_id = attrib.VendorID; event->device_info->release_number = attrib.VersionNumber; PHIDP_PREPARSED_DATA pp_data = NULL; auto res = HidD_GetPreparsedData(write_handle, &pp_data); if (res) { HIDP_CAPS caps; auto nt_res = HidP_GetCaps(pp_data, &caps); if (nt_res == HIDP_STATUS_SUCCESS) { event->device_info->usage_page = caps.UsagePage; event->device_info->usage = caps.Usage; } HidD_FreePreparsedData(pp_data); } CloseHandle(write_handle); }
BOOLEAN TryToSwitch( LPTSTR devPath, BOOL toHID ) { HANDLE hHidDevice = CreateFile(devPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 ); if ( hHidDevice == INVALID_HANDLE_VALUE ) return FALSE; HIDD_ATTRIBUTES HidAttributes; HidAttributes.Size = sizeof(HIDD_ATTRIBUTES); if ( !HidD_GetAttributes( hHidDevice, &HidAttributes) ) { CloseHandle( hHidDevice ); return FALSE; } ConversionFunction conversionFunction; if (LPTSTR lptstrDongleName = IsBTHidDevice(HidAttributes.VendorID, HidAttributes.ProductID, &conversionFunction)) (*conversionFunction)(lptstrDongleName, hHidDevice, toHID); CloseHandle( hHidDevice ); return TRUE; }
// // Make sure specified USB device has corrent vendor/product ID's... // bool PicBootloader::isValidDevice(char *DevicePath) { HANDLE hHidDevice = CreateFile(DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // no special create flags 0, // no special attributes NULL); // no template file if (hHidDevice == INVALID_HANDLE_VALUE) return NULL; HIDD_ATTRIBUTES Attr; memset (&Attr, 0, sizeof(Attr)); BOOL result = HidD_GetAttributes (hHidDevice, &Attr); CloseHandle(hHidDevice); //printf ("%s\n",DevicePath); //printf ("device: vid=%x, pid=%x\n", Attr.VendorID, Attr.ProductID); return (result && (Attr.VendorID == m_vid) && (Attr.ProductID == m_pid)); }
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; }
// open - open 1 or more devices // // Inputs: // max = maximum number of devices to open // vid = Vendor ID, or -1 if any // pid = Product ID, or -1 if any // usage_page = top level usage page, or -1 if any // usage = top level usage number, or -1 if any // Output: // actual number of devices opened // int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) { GUID guid; HDEVINFO info; DWORD index=0, reqd_size; SP_DEVICE_INTERFACE_DATA iface; SP_DEVICE_INTERFACE_DETAIL_DATA *details; HIDD_ATTRIBUTES attrib; PHIDP_PREPARSED_DATA hid_data; HIDP_CAPS capabilities; HANDLE h; BOOL ret; hid_t *hid; int count=0; if (first_hid) free_all_hid(); if (max < 1) return 0; if (!rx_event) { rx_event = CreateEvent(NULL, TRUE, TRUE, NULL); tx_event = CreateEvent(NULL, TRUE, TRUE, NULL); InitializeCriticalSection(&rx_mutex); InitializeCriticalSection(&tx_mutex); } HidD_GetHidGuid(&guid); info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (info == INVALID_HANDLE_VALUE) return 0; for (index=0; 1 ;index++) { iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface); if (!ret) return count; SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL); details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(reqd_size); if (details == NULL) continue; memset(details, 0, reqd_size); details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_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); if (h == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); // I get ERROR_ACCESS_DENIED with most/all my input devices (mice/trackballs/tablet). // Let's not log it :) if (err == ERROR_ACCESS_DENIED) { free(details); continue; } // qDebug wipes the GetLastError() it seems, so do that after print_win32_err(). print_win32_err(err); qDebug() << "Problem opening handle, path: " << QString().fromWCharArray(details->DevicePath); free(details); continue; } free(details); attrib.Size = sizeof(HIDD_ATTRIBUTES); ret = HidD_GetAttributes(h, &attrib); //printf("vid: %4x\n", attrib.VendorID); if (!ret || (vid > 0 && attrib.VendorID != vid) || (pid > 0 && attrib.ProductID != pid) || !HidD_GetPreparsedData(h, &hid_data)) { CloseHandle(h); continue; } if (!HidP_GetCaps(hid_data, &capabilities) || (usage_page > 0 && capabilities.UsagePage != usage_page) || (usage > 0 && capabilities.Usage != usage)) { HidD_FreePreparsedData(hid_data); CloseHandle(h); continue; } HidD_FreePreparsedData(hid_data); hid = (struct hid_struct *)malloc(sizeof(struct hid_struct)); if (!hid) { CloseHandle(h); continue; } // COMMTIMEOUTS CommTimeouts; // CommTimeouts.ReadIntervalTimeout = 100; // 100ms // CommTimeouts.ReadTotalTimeoutConstant = 5; // ms // CommTimeouts.ReadTotalTimeoutMultiplier = 1; // // CommTimeouts.WriteTotalTimeoutConstant = 5; // ms // CommTimeouts.WriteTotalTimeoutMultiplier = 1; // // if (!SetCommTimeouts(h, &CommTimeouts)) // { //// DWORD err = GetLastError(); // // } qDebug("Open: Handle address: %li for num: %i", (long int) h, count); hid->handle = h; add_hid(hid); count++; if (count >= max) return count; } return count; }
BOOLEAN Hid::GetAttributes(HANDLE HidDeviceObject, ATTRIBUTES *Attributes) { return HidD_GetAttributes(HidDeviceObject, Attributes); }
/********************************************************************* * * _AddConnection * * Function description * Checks the information about the queried device, if complying with * out vendor page information, add the device to the connection list. * * * Return value: * 1 - O.K., HID device added. * 0 - HID device not compatible. * */ static int _AddConnection(HANDLE hDevList, SP_DEVICE_INTERFACE_DATA * pDevData, CONN_INFO * pConnInfo) { SP_INTERFACE_DEVICE_DETAIL_DATA * pDevDetail; DWORD ReqLen; BOOL succ; HANDLE hDevice; int r; r = 0; ReqLen = 0; pDevDetail = NULL; // Get length of INTERFACE_DEVICE_DETAIL_DATA, allocate buffer // This function call returns the system error "buffer too small" (code 122). // We ignore this return code. SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, NULL, ReqLen, &ReqLen, NULL); pDevDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(ReqLen); if (pDevDetail == NULL ) { // Memory allocation failed return 0; } // Now get the INTERFACE_DEVICE_DETAIL_DATA struct ZeroMemory(pDevDetail,ReqLen); pDevDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); succ = SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, pDevDetail, ReqLen, &ReqLen, NULL); if (succ == FALSE) { // // Could not retrieve information about the device // free(pDevDetail); return 0; } // // Open a device handle to the HID device and retriece HID information // hDevice = CreateFile(pDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { PHIDP_PREPARSED_DATA pPreparsedData; HIDP_CAPS Capabilities; // // Parse the information from HID device // HidD_GetPreparsedData(hDevice, &pPreparsedData); HidP_GetCaps(pPreparsedData, &Capabilities); // // Does the device match the Vendor specific page implementation? // if (Capabilities.UsagePage == _VendorPage) { HIDD_ATTRIBUTES Attributes; memset(&Attributes, 0, sizeof(Attributes)); Attributes.Size = sizeof(Attributes); HidD_GetAttributes(hDevice, &Attributes); strcpy(pConnInfo->acDevicePath, pDevDetail->DevicePath); pConnInfo->InputReportByteLength = Capabilities.InputReportByteLength; pConnInfo->OutputReportByteLength = Capabilities.OutputReportByteLength; pConnInfo->ProductId = Attributes.ProductID; pConnInfo->VendorId = Attributes.VendorID; r = 1; } CloseHandle(hDevice); } free(pDevDetail); return r; }
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; }
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; }
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; }
/* Func: open_hid() Desc: finds & opens device having specified VID & PID. Retn: Handle of open device or INVALID_HANDLE_VALUE on fail Note this routine is a modified function from: usbhidiocDlg.cpp : implementation file Project: usbhidioc.cpp Version: 3.0 Date: 7/18/05 by Jan Axelson ([email protected]) */ static HANDLE open_hid(unsigned short vid, unsigned short pid) { //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. HANDLE returnHandle = INVALID_HANDLE_VALUE; HIDD_ATTRIBUTES Attributes; // DWORD DeviceUsage; SP_DEVICE_INTERFACE_DATA devInfoData; BOOL LastDevice = FALSE; int MemberIndex = 0; LONG Result; // were global, now just local scrap DWORD Length = 0; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; HANDLE DeviceHandle=NULL; GUID HidGuid; HANDLE hDevInfo; ULONG Required; BOOL MyDeviceDetected = 0; /* API function: HidD_GetHidGuid Get the GUID for all system HIDs. Returns: the GUID in HidGuid. */ HidD_GetHidGuid(&HidGuid); DEBUG("\nHidD_GetHidGuid returned.\n"); /* 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); DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo); 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); DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result); 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); DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result); //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); DEBUG("CreateFile(): %s\n", detailData->DevicePath); /* 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); DEBUG("HidD_GetAttributes returned 0x%x\n", Result); DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID); //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; // Get a handle for us to use. returnHandle = CreateFile (detailData->DevicePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); } //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) && (MyDeviceDetected == FALSE)); if (MyDeviceDetected == FALSE) DEBUG("Device not detected\n"); else DEBUG("Device detected\n"); //Free the memory reserved for hDevInfo by SetupDiClassDevs. DEBUG("Calling SetupDiDestroyDeviceInfoList\n"); SetupDiDestroyDeviceInfoList(hDevInfo); return returnHandle; }
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; }
BOOLEAN OpenHidDevice ( IN PCHAR DevicePath, IN BOOL HasReadAccess, IN BOOL HasWriteAccess, IN BOOL IsOverlapped, IN BOOL IsExclusive, IN OUT PHID_DEVICE HidDevice ) /*++ RoutineDescription: Given the HardwareDeviceInfo, representing a handle to the plug and play information, and deviceInfoData, representing a specific hid device, open that device and fill in all the relivant information in the given HID_DEVICE structure. return if the open and initialization was successfull or not. --*/ { DWORD accessFlags = 0; DWORD sharingFlags = 0; BOOLEAN bSuccess; INT iDevicePathSize; HRESULT stringReturn; iDevicePathSize = strlen(DevicePath) + 1; HidDevice -> DevicePath = malloc(iDevicePathSize); if (NULL == HidDevice -> DevicePath) { return (FALSE); } stringReturn = StringCbCopy(HidDevice -> DevicePath, iDevicePathSize, DevicePath); if (HasReadAccess) { accessFlags |= GENERIC_READ; } if (HasWriteAccess) { accessFlags |= GENERIC_WRITE; } if (!IsExclusive) { sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE; } // // The hid.dll api's do not pass the overlapped structure into deviceiocontrol // so to use them we must have a non overlapped device. If the request is for // an overlapped device we will close the device below and get a handle to an // overlapped device // HidDevice->HidDevice = CreateFile (DevicePath, accessFlags, sharingFlags, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags 0, // Open device as non-overlapped so we can get data NULL); // No template file if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) { free(HidDevice -> DevicePath); HidDevice -> DevicePath = INVALID_HANDLE_VALUE ; return FALSE; } HidDevice -> OpenedForRead = HasReadAccess; HidDevice -> OpenedForWrite = HasWriteAccess; HidDevice -> OpenedOverlapped = IsOverlapped; HidDevice -> OpenedExclusive = IsExclusive; // // If the device was not opened as overlapped, then fill in the rest of the // HidDevice structure. However, if opened as overlapped, this handle cannot // be used in the calls to the HidD_ exported functions since each of these // functions does synchronous I/O. // if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) { free(HidDevice -> DevicePath); HidDevice -> DevicePath = NULL ; CloseHandle(HidDevice -> HidDevice); HidDevice -> HidDevice = INVALID_HANDLE_VALUE ; return FALSE; } if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes)) { free(HidDevice -> DevicePath); HidDevice -> DevicePath = NULL; CloseHandle(HidDevice -> HidDevice); HidDevice -> HidDevice = INVALID_HANDLE_VALUE; HidD_FreePreparsedData (HidDevice->Ppd); HidDevice->Ppd = NULL; return FALSE; } if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps)) { free(HidDevice -> DevicePath); HidDevice -> DevicePath = NULL; CloseHandle(HidDevice -> HidDevice); HidDevice -> HidDevice = INVALID_HANDLE_VALUE; HidD_FreePreparsedData (HidDevice->Ppd); HidDevice->Ppd = NULL; return FALSE; } // // At this point the client has a choice. It may chose to look at the // Usage and Page of the top level collection found in the HIDP_CAPS // structure. In this way it could just use the usages it knows about. // If either HidP_GetUsages or HidP_GetUsageValue return an error then // that particular usage does not exist in the report. // This is most likely the preferred method as the application can only // use usages of which it already knows. // In this case the app need not even call GetButtonCaps or GetValueCaps. // // In this example, however, we will call FillDeviceInfo to look for all // of the usages in the device. // bSuccess = FillDeviceInfo(HidDevice); if (FALSE == bSuccess) { CloseHidDevice(HidDevice); return (FALSE); } if (IsOverlapped) { CloseHandle(HidDevice->HidDevice); HidDevice->HidDevice = CreateFile (DevicePath, accessFlags, sharingFlags, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags FILE_FLAG_OVERLAPPED, // Now we open the device as overlapped NULL); // No template file if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) { CloseHidDevice(HidDevice); return FALSE; } } return (TRUE); }
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; }
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; }
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; }
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; }
void * _ykusb_open_device(int vendor_id, int product_id) { HDEVINFO hi; SP_DEVICE_INTERFACE_DATA di; PSP_DEVICE_INTERFACE_DETAIL_DATA pi; int i, numDev = 0; LPTSTR path = 0; DWORD len, rc; HANDLE ret_handle = NULL; yk_errno = YK_EUSBERR; hi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_KEYBOARD, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hi == INVALID_HANDLE_VALUE) return NULL; di.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); for (i = 0; i < 1000; i++) { if (!SetupDiEnumDeviceInterfaces(hi, 0, &GUID_DEVINTERFACE_KEYBOARD, i, &di)) break; if (SetupDiGetDeviceInterfaceDetail(hi, &di, 0, 0, &len, 0) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; pi = malloc (len); if (!pi) { yk_errno = YK_ENOMEM; goto done; } pi->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); rc = SetupDiGetDeviceInterfaceDetail(hi, &di, pi, len, &len, 0); if (rc) { HANDLE m_handle; m_handle = CreateFile(pi->DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (m_handle != INVALID_HANDLE_VALUE) { HIDD_ATTRIBUTES devInfo; if (HidD_GetAttributes(m_handle, &devInfo)) { if (devInfo.VendorID == vendor_id && devInfo.ProductID == product_id) { ret_handle = m_handle; free (pi); goto done; } } } CloseHandle (m_handle); } free (pi); if (!rc) break; } yk_errno = YK_ENOKEY; done: SetupDiDestroyDeviceInfoList(hi); return ret_handle; }
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; }