#windows #winapi #usb
Имею symbolic link на USB Root Hub вида "\\.\USB#ROOT_HUB#4&e097488&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}" и хочу получить VID:PID для хаба. Работаю в user mode, IOCTLы слать могу. Но среди описанных в MSDN (https://msdn.microsoft.com/en-us/library/windows/hardware/ff537421%28v=vs.85%29.aspx) не нахожу подходящего. Как быть?
Ответы
Ответ 1
VID и PID для USB Hub можно определить разбором его Hardware ID. Hardware ID можно получить с помощью функции SetupDiGetDeviceRegistryProperty (Setup API). Функция возвращает несколько значений, нужно взять первое с вхождением подстрок VID/PID. Для корневого концентратора формат строки выглядит так: USB\ROOT_HUB30&VID8086&PID8C31&REV0005 Пример кода на c++ для вывода symbolic link, названия, VID и PID для всех USB Hub-ов; основан на этом ответе. #pragma comment(lib,"Setupapi.lib") #include#include #include #include #include #include #include #include #include void ErrorMes(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); wprintf(L"%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } int main() { setlocale(LC_ALL,"Russian"); GUID guid; HRESULT hr = CLSIDFromString(L"{F18A0E88-C30C-11D0-8815-00A0C906BED8}", (LPCLSID)&guid);//USB Hub HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfoHandle != INVALID_HANDLE_VALUE) { int deviceIndex = 0; while (true) { SP_DEVICE_INTERFACE_DATA deviceInterface = { 0 }; deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //перечисление всех интерфейсов USB Hub if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, deviceIndex, &deviceInterface)) { DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[cbRequired]); memset(deviceInterfaceDetail, 0, cbRequired); deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, deviceInterfaceDetail, cbRequired, &cbRequired, 0)) { deviceIndex++; continue; } // Initialize the structure before using it. memset(deviceInterfaceDetail, 0, cbRequired); deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Call the API a second time to retrieve the actual // device path string. BOOL status = SetupDiGetDeviceInterfaceDetail( deviceInfoHandle, // Handle to device information set &deviceInterface, // Pointer to current node in devinfo set deviceInterfaceDetail, // Pointer to buffer to receive device path cbRequired, // Length of user-allocated buffer &cbRequired, // Pointer to arg to receive required buffer length NULL); // Not interested in additional data wprintf(deviceInterfaceDetail->DevicePath);//вывод symbolic link wprintf(L"\n"); //получение информации о устройстве DEVPROPTYPE dpt=0; wchar_t buffer[1000]=L""; DWORD RequiredSize = 0; SP_DEVINFO_DATA devinfo = { 0 }; devinfo.cbSize = sizeof(SP_DEVINFO_DATA); BOOL success = SetupDiEnumDeviceInfo(deviceInfoHandle, deviceIndex, &devinfo); if(success==FALSE){ErrorMes(L"SetupDiEnumDeviceInfo");} BOOL res; //name res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_DeviceDesc,&dpt,(PBYTE)buffer,1000,NULL,0); printf("Name: "); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(buffer); printf("\n"); //hardware id DWORD regType = REG_MULTI_SZ; unsigned char* ptr = new unsigned char[2048]; if (SetupDiGetDeviceRegistryProperty(deviceInfoHandle, &devinfo, SPDRP_HARDWAREID, ®Type, ptr, 2048, &RequiredSize)) { wchar_t* input=reinterpret_cast (ptr); wchar_t sep[]=L"&\\"; wchar_t vid[5]=L""; wchar_t pid[5]=L""; bool found=false; /*проходим по всем элементам REG_MULTI_SZ*/ while(true){ wchar_t* tok=NULL; wchar_t* pos=NULL; //разбор hardware id tok=wcstok(input,sep); while( tok != NULL ) { pos=wcsstr(tok,L"VID"); if(pos!=NULL){ pos+=3; if(pos[0]==L'_')pos++; StringCchCopy(vid,5,pos); found=true; } pos=wcsstr(tok,L"PID"); if(pos!=NULL){ pos+=3; if(pos[0]==L'_')pos++; StringCchCopy(pid,5,pos); found=true; } tok = wcstok( NULL, sep ); }//конец разбора hardware id if(found!=false)break; input+=wcslen(input)+1;//переход к следующему элементу REG_MULTI_SZ if(wcscmp(input,L"")==0)break; }//конец прохода if(found!=false) { wprintf( L"VID: %s\n", vid ); wprintf( L"PID: %s\n", pid ); } else { wprintf( L"Not found\n"); } } else ErrorMes(L"SetupDiGetDeviceRegistryProperty"); delete[] ptr; delete[] deviceInterfaceDetail; printf("\n"); } } else { break; } ++deviceIndex; } SetupDiDestroyDeviceInfoList(deviceInfoHandle); } system("PAUSE"); return 0; }
Комментариев нет:
Отправить комментарий