QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { static const QString usbVendorIdentifierPrefix(QStringLiteral("VID_")); static const QString usbProductIdentifierPrefix(QStringLiteral("PID_")); static const QString pciVendorIdentifierPrefix(QStringLiteral("VEN_")); static const QString pciDeviceIdentifierPrefix(QStringLiteral("DEV_")); static const int vendorIdentifierSize = 4; static const int productIdentifierSize = 4; QList<QSerialPortInfo> serialPortInfoList; foreach (const GuidFlagsPair &uniquePair, guidFlagsPairs()) { const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(reinterpret_cast<const GUID *>(&uniquePair.first), NULL, 0, uniquePair.second); if (deviceInfoSet == INVALID_HANDLE_VALUE) return serialPortInfoList; SP_DEVINFO_DATA deviceInfoData; ::memset(&deviceInfoData, 0, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(deviceInfoData); DWORD index = 0; while (::SetupDiEnumDeviceInfo(deviceInfoSet, index++, &deviceInfoData)) { QSerialPortInfo serialPortInfo; QString s = devicePortName(deviceInfoSet, &deviceInfoData); if (s.isEmpty() || s.contains(QStringLiteral("LPT"))) continue; if (std::find_if(serialPortInfoList.begin(), serialPortInfoList.end(), SerialPortNameEqualFunctor(s)) != serialPortInfoList.end()) { continue; } serialPortInfo.d_ptr->portName = s; serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(s); serialPortInfo.d_ptr->description = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC).toString(); serialPortInfo.d_ptr->manufacturer = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_MFG).toString(); s = deviceInstanceIdentifier(deviceInfoSet, &deviceInfoData).toUpper(); int index = s.indexOf(usbVendorIdentifierPrefix); if (index != -1) { serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + usbVendorIdentifierPrefix.size(), vendorIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); } else { index = s.indexOf(pciVendorIdentifierPrefix); if (index != -1) serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + pciVendorIdentifierPrefix.size(), vendorIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); } index = s.indexOf(usbProductIdentifierPrefix); if (index != -1) { serialPortInfo.d_ptr->productIdentifier = s.mid(index + usbProductIdentifierPrefix.size(), productIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); } else { index = s.indexOf(pciDeviceIdentifierPrefix); if (index != -1) serialPortInfo.d_ptr->productIdentifier = s.mid(index + pciDeviceIdentifierPrefix.size(), productIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); } serialPortInfoList.append(serialPortInfo); } ::SetupDiDestroyDeviceInfoList(deviceInfoSet); } return serialPortInfoList; }
QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { static const QString usbVendorIdentifierPrefix(QLatin1String("VID_")); static const QString usbProductIdentifierPrefix(QLatin1String("PID_")); static const QString pciVendorIdentifierPrefix(QLatin1String("VEN_")); static const QString pciDeviceIdentifierPrefix(QLatin1String("DEV_")); static const int vendorIdentifierSize = 4; static const int productIdentifierSize = 4; QList<QSerialPortInfo> serialPortInfoList; static const int guidCount = sizeof(guidsArray)/sizeof(guidsArray[0]); for (int i = 0; i < guidCount; ++i) { const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(&guidsArray[i], NULL, 0, DIGCF_PRESENT); if (deviceInfoSet == INVALID_HANDLE_VALUE) return serialPortInfoList; SP_DEVINFO_DATA deviceInfoData; ::memset(&deviceInfoData, 0, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(deviceInfoData); DWORD index = 0; while (::SetupDiEnumDeviceInfo(deviceInfoSet, index++, &deviceInfoData)) { QSerialPortInfo serialPortInfo; QString s = devicePortName(deviceInfoSet, &deviceInfoData); if (s.isEmpty() || s.contains(QLatin1String("LPT"))) continue; serialPortInfo.d_ptr->portName = s; serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(s); serialPortInfo.d_ptr->description = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC).toString(); serialPortInfo.d_ptr->manufacturer = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_MFG).toString(); s = deviceInstanceIdentifier(deviceInfoSet, &deviceInfoData).toUpper(); int index = s.indexOf(usbVendorIdentifierPrefix); if (index != -1) { serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + usbVendorIdentifierPrefix.size(), vendorIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); } else { index = s.indexOf(pciVendorIdentifierPrefix); if (index != -1) serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + pciVendorIdentifierPrefix.size(), vendorIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); } index = s.indexOf(usbProductIdentifierPrefix); if (index != -1) { serialPortInfo.d_ptr->productIdentifier = s.mid(index + usbProductIdentifierPrefix.size(), productIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); } else { index = s.indexOf(pciDeviceIdentifierPrefix); if (index != -1) serialPortInfo.d_ptr->productIdentifier = s.mid(index + pciDeviceIdentifierPrefix.size(), productIdentifierSize) .toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); } serialPortInfoList.append(serialPortInfo); } ::SetupDiDestroyDeviceInfoList(deviceInfoSet); } return serialPortInfoList; }