From e08cc29223aeab7da216963ae80d619f387109b9 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Sun, 26 Jan 2014 15:19:04 +0400 Subject: Add listing of virtual ports from the "AGG Software" The current algorithm takes a name of the serial port from the PortName property which is in the Registry. This value is filled out by the Ports class installer automatically: http://msdn.microsoft.com/en-us/library/windows/hardware/ff546514%28v=vs.85%29.aspx But at using the "AGG Software" software this property is absent. Therefore the algorithm ignores these serial ports. The simplest workaround is use of the PortNumber property which identifies a port number for this software. In this case a port name defines indirectly, by adding a port number to the "COM" suffix. This does not influence other serial ports which are defined through PortName property. Tested on Windows XP and Windows 8 with the cenumerator example. Task-number: QTBUG-32774 Change-Id: I8cda3ed992ff80742511a2952d3fb7e8ac6edc81 Reviewed-by: Sergey Belyashov Reviewed-by: Denis Shienkov --- src/serialport/qserialportinfo_win.cpp | 37 +++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'src/serialport/qserialportinfo_win.cpp') diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp index 51f529e9..54ea7869 100644 --- a/src/serialport/qserialportinfo_win.cpp +++ b/src/serialport/qserialportinfo_win.cpp @@ -137,28 +137,37 @@ static QString deviceInstanceIdentifier(HDEVINFO deviceInfoSet, static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) { - static const wchar_t portKeyName[] = L"PortName"; - const HKEY key = ::SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (key == INVALID_HANDLE_VALUE) return QString(); - DWORD dataSize; - if (::RegQueryValueEx(key, portKeyName, NULL, NULL, NULL, &dataSize) != ERROR_SUCCESS) { - ::RegCloseKey(key); - return QString(); - } - - QByteArray data(dataSize, 0); + static const QStringList portNameRegistryKeyList = QStringList() + << QStringLiteral("PortName") + << QStringLiteral("PortNumber"); - if (::RegQueryValueEx(key, portKeyName, NULL, NULL, - reinterpret_cast(data.data()), &dataSize) != ERROR_SUCCESS) { - ::RegCloseKey(key); - return QString(); + QString portName; + foreach (const QString &portNameKey, portNameRegistryKeyList) { + DWORD bytesRequired = 0; + DWORD dataType = 0; + QByteArray outputBuffer; + forever { + const LONG ret = ::RegQueryValueEx(key, reinterpret_cast(portNameKey.utf16()), NULL, &dataType, + reinterpret_cast(outputBuffer.data()), &bytesRequired); + if (ret == ERROR_MORE_DATA) { + outputBuffer.resize(bytesRequired); + continue; + } else if (ret == ERROR_SUCCESS) { + if (dataType == REG_SZ) + portName = QString::fromWCharArray((reinterpret_cast(outputBuffer.constData()))); + else if (dataType == REG_DWORD) + portName = QStringLiteral("COM%1").arg(*(PDWORD(outputBuffer.constData()))); + } + break; + } } ::RegCloseKey(key); - return QString::fromWCharArray(((const wchar_t *)data.constData())); + return portName; } class SerialPortNameEqualFunctor -- cgit v1.2.3