bool pjrc_rawhid::getDeviceDetailsWin( USBPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam ) { portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); if( wParam == DBT_DEVICEARRIVAL) portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); QRegExp idRx("VID_(\\w+)&PID_(\\w+)"); if( hardwareIDs.toUpper().contains(idRx) ) { bool dummy; portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); portInfo->productID = idRx.cap(2).toInt(&dummy, 16); } return true; }
bool QextSerialEnumerator::getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam ) { portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); if( wParam == DBT_DEVICEARRIVAL) portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); HKEY devKey = SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); portInfo->portName = QextSerialPort::fullPortNameWin( getRegKeyValue(devKey, TEXT("PortName")) ); QRegExp idRx("VID_(\\w+)&PID_(\\w+)&"); if( hardwareIDs.toUpper().contains(idRx) ) { bool dummy; portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); portInfo->productID = idRx.cap(2).toInt(&dummy, 16); //qDebug() << "got vid:" << vid << "pid:" << pid; } return true; }
//static void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList) { HDEVINFO devInfo = INVALID_HANDLE_VALUE; DWORD dwGuids = 0; SetupDiClassGuidsFromName(TEXT("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) { qCritical("SetupDiClassGuidsFromName failed. Error code: %ld", GetLastError()); return; } GUID *pGuids = new GUID[dwGuids]; if (!SetupDiClassGuidsFromName(TEXT("Ports"), pGuids, dwGuids, &dwGuids)) { qCritical("SetupDiClassGuidsFromName second call failed. Error code: %ld", GetLastError()); return; } devInfo = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if(devInfo == INVALID_HANDLE_VALUE) { qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError()); return; } //enumerate the devices bool ok = true; SP_DEVICE_INTERFACE_DATA ifcData; ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL; SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)}; for (DWORD i = 0; ok; i++) { ok = SetupDiEnumDeviceInfo(devInfo, i, &devData); if (ok) { // Got a device. Get the details. QextPortInfo info; info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME); info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME); //anyway, to get the port name we must still open registry directly :( ??? //Eh... HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); info.portName = getRegKeyValue(devKey, TEXT("PortName")); RegCloseKey(devKey); if(info.portName.startsWith("COM")) { infoList.append(info); } } else { if (GetLastError() != ERROR_NO_MORE_ITEMS) { delete [] detData; qCritical("SetupDiEnumDeviceInfo failed. Error code: %ld", GetLastError()); return; } } } delete [] detData; delete[] pGuids; }
//static void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList) { HDEVINFO devInfo = INVALID_HANDLE_VALUE; GUID * guidDev = (GUID *) & GUID_CLASS_COMPORT; devInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(devInfo == INVALID_HANDLE_VALUE) { qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError()); return; } //enumerate the devices bool ok = true; SP_DEVICE_INTERFACE_DATA ifcData; ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL; DWORD detDataSize = 0; DWORD oldDetDataSize = 0; for (DWORD i = 0; ok; i++) { ok = SetupDiEnumDeviceInterfaces(devInfo, NULL, guidDev, i, &ifcData); if (ok) { SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)}; //check for required detData size SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, NULL, 0, & detDataSize, & devData); //if larger than old detData size then reallocate the buffer if (detDataSize > oldDetDataSize) { delete [] detData; detData = (SP_DEVICE_INTERFACE_DETAIL_DATA *) new char[detDataSize]; detData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); oldDetDataSize = detDataSize; } //check the details if (SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, detData, detDataSize, NULL, & devData)) { // Got a device. Get the details. QextPortInfo info; info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME); info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME); //anyway, to get the port name we must still open registry directly :( ??? //Eh... HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); info.portName = getRegKeyValue(devKey, TEXT("PortName")); RegCloseKey(devKey); infoList.append(info); } else { qCritical("SetupDiGetDeviceInterfaceDetail failed. Error code: %ld", GetLastError()); delete [] detData; return; } } else { if (GetLastError() != ERROR_NO_MORE_ITEMS) { delete [] detData; qCritical("SetupDiEnumDeviceInterfaces failed. Error code: %ld", GetLastError()); return; } } } delete [] detData; }
bool remove(const std::wstring& hardware_id, bool& reboot_required) { bool result = false; HDEVINFO devices = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL); if (devices != INVALID_HANDLE_VALUE) { std::wcerr << "Got device information set." << std::endl; SP_DEVINFO_LIST_DETAIL_DATA device_info_list_detail; memset(&device_info_list_detail, 0x00, sizeof(device_info_list_detail)); device_info_list_detail.cbSize = sizeof(device_info_list_detail); if (SetupDiGetDeviceInfoListDetail(devices, &device_info_list_detail)) { std::wcerr << "Got device information list details." << std::endl; SP_DEVINFO_DATA device_info; device_info.cbSize = sizeof(device_info); for (DWORD index = 0; SetupDiEnumDeviceInfo(devices, index, &device_info); ++index) { TCHAR device_id[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_ID_Ex(device_info.DevInst, device_id, MAX_DEVICE_ID_LEN, 0, device_info_list_detail.RemoteMachineHandle) == CR_SUCCESS) { std::list<std::wstring> device_hardware_id_list; if (getDeviceProperty(devices, device_info, SPDRP_HARDWAREID, device_hardware_id_list)) { bool match = false; for (std::list<std::wstring>::const_iterator device_hardware_id = device_hardware_id_list.begin(); device_hardware_id != device_hardware_id_list.end(); ++device_hardware_id) { if (*device_hardware_id == hardware_id) { match = true; break; } } if (match) { std::wstring friendly_name; if (getDeviceProperty(devices, device_info, SPDRP_FRIENDLYNAME, friendly_name) && (friendly_name.length() > 0)) { std::wcerr << "Removing device: " << friendly_name << " (" << device_id << ")" << std::endl; } else { std::wcerr << "Removing device: " << device_id << std::endl; } SP_REMOVEDEVICE_PARAMS remove_device_params; remove_device_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); remove_device_params.ClassInstallHeader.InstallFunction = DIF_REMOVE; remove_device_params.Scope = DI_REMOVEDEVICE_GLOBAL; remove_device_params.HwProfile = 0; result = true; if (!SetupDiSetClassInstallParams(devices, &device_info, &remove_device_params.ClassInstallHeader, sizeof(remove_device_params)) || !SetupDiCallClassInstaller(DIF_REMOVE, devices, &device_info)) { std::wcerr << "Failed to set the class installer." << std::endl; result = false; } if (result) { reboot_required = false; SP_DEVINSTALL_PARAMS device_params; if (SetupDiGetDeviceInstallParams(devices, &device_info, &device_params)) { if (device_params.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) { reboot_required = true; } } } } } } } } SetupDiDestroyDeviceInfoList(devices); } return result; }
QueryData genDrivers(QueryContext& context) { QueryData results; auto devInfoset = setupDevInfoSet(); if (devInfoset == nullptr) { win32LogWARNING("Error getting device handle"); return results; } std::vector<SP_DEVINFO_DATA> devices; auto ret = getDeviceList(devInfoset, devices); if (!ret.ok()) { win32LogWARNING(ret.getMessage(), ret.getCode()); return results; } for (auto& device : devices) { char devId[MAX_DEVICE_ID_LEN] = {0}; if (CM_Get_Device_ID(device.DevInst, devId, MAX_DEVICE_ID_LEN, 0) != CR_SUCCESS) { win32LogWARNING("Failed to get device ID"); return QueryData(); } SP_DRVINFO_DATA drvInfo = {0}; SP_DRVINFO_DETAIL_DATA drvInfoDetail = {0}; ret = getDeviceDriverInfo(devInfoset, device, drvInfo, drvInfoDetail); Row r; r["device_id"] = devId; r["inf"] = drvInfoDetail.InfFileName; r["provider"] = drvInfo.ProviderName; r["manufacturer"] = drvInfo.MfgName; r["date"] = std::to_string(osquery::filetimeToUnixtime(drvInfo.DriverDate)); r["description"] = drvInfo.Description; ULARGE_INTEGER version; version.QuadPart = drvInfo.DriverVersion; r["version"] = std::to_string(HIWORD(version.HighPart)) + "." + std::to_string(HIWORD(version.LowPart)) + "." + std::to_string(LOWORD(version.HighPart)) + "." + std::to_string(LOWORD(version.LowPart)); for (const auto& elem : kAdditionalDeviceProps) { std::string val; ret = getDeviceProperty(devInfoset, device, elem.second, val); r[elem.first] = std::move(val); } if (r.count("driver_key") > 0) { if (!r.at("driver_key").empty()) { r["driver_key"].insert(0, kDriverKeyPath); } } if (r.count("service") > 0) { if (!r.at("service").empty()) { r["service_key"] = kServiceKeyPath + r["service"]; r["image"] = getDriverImagePath(r["service_key"]); } } results.push_back(r); } return results; }