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 = deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID).toStringList().first().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(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() { CFMutableDictionaryRef serialPortDictionary = ::IOServiceMatching(kIOSerialBSDServiceValue); if (!serialPortDictionary) return QList<QSerialPortInfo>(); ::CFDictionaryAddValue(serialPortDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); io_iterator_t serialPortIterator = 0; if (::IOServiceGetMatchingServices(kIOMasterPortDefault, serialPortDictionary, &serialPortIterator) != KERN_SUCCESS) { return QList<QSerialPortInfo>(); } QList<QSerialPortInfo> serialPortInfoList; forever { io_registry_entry_t serialPortService = ::IOIteratorNext(serialPortIterator); if (!serialPortService) break; QSerialPortInfoPrivate priv; forever { if (priv.portName.isEmpty()) priv.portName = devicePortName(serialPortService); if (priv.device.isEmpty()) priv.device = deviceSystemLocation(serialPortService); if (priv.description.isEmpty()) priv.description = deviceDescription(serialPortService); if (priv.manufacturer.isEmpty()) priv.manufacturer = deviceManufacturer(serialPortService); if (priv.serialNumber.isEmpty()) priv.serialNumber = deviceSerialNumber(serialPortService); if (!priv.hasVendorIdentifier) { priv.vendorIdentifier = deviceVendorIdentifier(serialPortService, priv.hasVendorIdentifier); } if (!priv.hasProductIdentifier) { priv.productIdentifier = deviceProductIdentifier(serialPortService, priv.hasProductIdentifier); } if (isCompleteInfo(priv)) { ::IOObjectRelease(serialPortService); break; } serialPortService = parentSerialPortService(serialPortService); if (!serialPortService) break; } serialPortInfoList.append(priv); } ::IOObjectRelease(serialPortIterator); return serialPortInfoList; }