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;
}
Exemple #2
0
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;
}