MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Windows: как определить драйвера, которые система загрузит для составного USB-устройства?"
Answer 740938
Для составных устройств с помощью SetupAPI можно получить перечень дочерних устройств (DEVPKEY_Device_Children) и вывести их драйвера. Свойство возвращает список InstanceID дочерних устройств, разделенных нулевым байтом (REG_SZ_MULTI). Затем нужно выполнить перечисление всех устройств, отфильтровать нужные устройства по InstanceID и можно получить сведения о драйвере.
Пример кода на C++ для вывода имени драйвера, пути к INF-файлу и версии драйвера для всех USB-устройств и их дочерних устройств:
#pragma comment(lib,"Setupapi.lib") #include <Windows.h> #include <Setupapi.h> #include <winusb.h> #include <stdlib.h> #include <Devpkey.h> #include <iostream> #include <string> #include <memory> #include <strsafe.h> 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 and exit the process 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); } /*Вывод информации об устройстве с указанным InstanceID*/ BOOL PrintDevice(wchar_t* id) { unsigned index; HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; TCHAR id_upper[1024]=L""; TCHAR buf[1024]=L""; TCHAR match[1024]; DEVPROPTYPE dpt=0; for(int i=0;i<wcslen(id);i++){ id_upper[i]=toupper(id[i]);//преобразование в заглавные буквы } // List all connected devices hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); for (index = 0; ; index++) { DeviceInfoData.cbSize = sizeof(DeviceInfoData); if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) { return FALSE; // no match } BOOL res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData, &DEVPKEY_Device_InstanceId,&dpt,(PBYTE)buf,1000,NULL,0); if(res==FALSE)continue; if(wcscmp(buf,id_upper)==0){ //устройство найдено res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData, &DEVPKEY_Device_DeviceDesc,&dpt,(PBYTE)buf,1000,NULL,0); //name if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"\n\t * %s\n ",buf); //service res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData, &DEVPKEY_Device_Service,&dpt,(PBYTE)buf,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"\tDriver: %s\n ",buf); //driver res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData, &DEVPKEY_Device_DriverInfPath,&dpt,(PBYTE)buf,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"\tINF File: %s\n ",buf); //version res=SetupDiGetDeviceProperty(hDevInfo,&DeviceInfoData, &DEVPKEY_Device_DriverVersion,&dpt,(PBYTE)buf,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"\tVersion: %s\n ",buf); return TRUE; } } return FALSE;//устройство не найдено } int main() { setlocale(LC_ALL,"Russian"); GUID guid; HRESULT hr = CLSIDFromString(L"{A5DCBF10-6530-11D2-901F-00C04FB951ED}", (LPCLSID)&guid);//USB device 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); //перечисление устройств if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, deviceIndex, &deviceInterface)) { DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { //получение информации о устройстве 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; //location res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_LocationInfo,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"%s\n",buffer); //name res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_DeviceDesc,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"Name: %s\n",buffer); //service res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_Service,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"Driver: %s\n",buffer); //driver res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_DriverInfPath,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"INF file: %s\n",buffer); //version res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_DriverVersion,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE)ErrorMes(L"SetupDiGetDeviceProperty"); else wprintf(L"Version: %s\n",buffer); //children res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_Children,&dpt,(PBYTE)buffer,1000,NULL,0); if(res!=FALSE){ printf("Children: \n"); wchar_t* p=buffer;//указатель на текущий элемент REG_SZ_MULTI //вывод дочерних устройств while(true){ if(wcscmp(p,L"")==0)break; PrintDevice(p); p+=wcslen(p)+1; //переход к следующему элементу REG_SZ_MULTI } }//endif } } else { break; } ++deviceIndex; printf("\n"); }//end while SetupDiDestroyDeviceInfoList(deviceInfoHandle); } system("PAUSE"); return 0; }
Пример вывода:
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.