diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2014-01-26 15:19:04 +0400 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-07 08:25:26 +0100 |
commit | e08cc29223aeab7da216963ae80d619f387109b9 (patch) | |
tree | d3f81f394b967849704081b5e38e7f87626ddccb | |
parent | 1335bcd134c012cd00dd6c542bc7b734269b6479 (diff) | |
download | qtserialport-e08cc29223aeab7da216963ae80d619f387109b9.tar.gz |
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 <Sergey.Belyashov@gmail.com>
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r-- | src/serialport/qserialportinfo_win.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp index 51f529e..54ea786 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<unsigned char *>(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<const wchar_t *>(portNameKey.utf16()), NULL, &dataType, + reinterpret_cast<unsigned char *>(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<const wchar_t *>(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 |