summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2014-01-30 19:52:48 +0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-07 11:31:39 +0100
commit78b8866c4d3e846f3dd142bc4bac38385298dc40 (patch)
treecc2aec9b5c755317a85b3d601763f0ee669f711a
parent3660b4d0ca3dae1c69a3f4e817561844a37d334e (diff)
downloadqtserialport-78b8866c4d3e846f3dd142bc4bac38385298dc40.tar.gz
Add enumeration through the SERIALCOMM registry entry
When using some software that provide an virtual serial ports functionality is impossible to use the Win32 SetupAPI feature to enumerate these serial ports. For example, such software is "Virtual Serial Ports Emulator" from Eterlogic: http://www.eterlogic.com/Products.VSPE.html The only possible simple way to detect these serial ports it to read the registry key HARDWARE\\DEVICEMAP\\SERIALCOMM: http://msdn.microsoft.com/en-us/library/windows/hardware/ff546502%28v=vs.85%29.aspx In this case it is possible to get only a name of the serial port without any additional information. This method is simply addition to the main SetupAPI functionality. Task-number: QTBUG-36526 Change-Id: Ib505aee66b74b6a8ebe16cf88c3060c8267397a0 Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialportinfo_win.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index 54ea786..9fceb31 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -75,6 +75,35 @@ static inline const QList<GuidFlagsPair>& guidFlagsPairs()
return guidFlagsPairList;
}
+static QStringList portNamesFromHardwareDeviceMap()
+{
+ HKEY hKey = 0;
+ if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+ return QStringList();
+
+ QStringList result;
+ DWORD index = 0;
+ static const DWORD maximumValueNameInChars = 16383;
+ QByteArray outputValueName(maximumValueNameInChars * sizeof(wchar_t), 0);
+ QByteArray outputBuffer;
+ DWORD requiredDataBytes = 0;
+ forever {
+ DWORD requiredValueNameChars = maximumValueNameInChars;
+ const LONG ret = ::RegEnumValue(hKey, index, reinterpret_cast<wchar_t *>(outputValueName.data()), &requiredValueNameChars,
+ NULL, NULL, reinterpret_cast<unsigned char *>(outputBuffer.data()), &requiredDataBytes);
+ if (ret == ERROR_MORE_DATA) {
+ outputBuffer.resize(requiredDataBytes);
+ } else if (ret == ERROR_SUCCESS) {
+ result.append(QString::fromWCharArray(reinterpret_cast<const wchar_t *>(outputBuffer.constData())));
+ ++index;
+ } else {
+ break;
+ }
+ }
+ ::RegCloseKey(hKey);
+ return result;
+}
+
static QVariant deviceRegistryProperty(HDEVINFO deviceInfoSet,
PSP_DEVINFO_DATA deviceInfoData,
DWORD property)
@@ -256,6 +285,17 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
}
::SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
+
+ foreach (const QString &portName, portNamesFromHardwareDeviceMap()) {
+ if (std::find_if(serialPortInfoList.begin(), serialPortInfoList.end(),
+ SerialPortNameEqualFunctor(portName)) == serialPortInfoList.end()) {
+ QSerialPortInfo serialPortInfo;
+ serialPortInfo.d_ptr->portName = portName;
+ serialPortInfo.d_ptr->device = QSerialPortPrivate::portNameToSystemLocation(portName);
+ serialPortInfoList.append(serialPortInfo);
+ }
+ }
+
return serialPortInfoList;
}