summaryrefslogtreecommitdiff
path: root/src/serialport/qserialportinfo_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialport/qserialportinfo_win.cpp')
-rw-r--r--src/serialport/qserialportinfo_win.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp
index 8e449c4..dd6a907 100644
--- a/src/serialport/qserialportinfo_win.cpp
+++ b/src/serialport/qserialportinfo_win.cpp
@@ -51,6 +51,7 @@
#include <initguid.h>
#include <setupapi.h>
+#include <cfgmgr32.h>
QT_BEGIN_NAMESPACE
@@ -122,21 +123,33 @@ static QString deviceRegistryProperty(HDEVINFO deviceInfoSet,
return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(devicePropertyByteArray.constData()));
}
-static QString deviceInstanceIdentifier(HDEVINFO deviceInfoSet,
- PSP_DEVINFO_DATA deviceInfoData)
+static QString deviceInstanceIdentifier(DEVINST deviceInstanceNumber)
{
- DWORD requiredSize = 0;
- if (::SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData, NULL, 0, &requiredSize))
+ ULONG numberOfChars = 0;
+ if (::CM_Get_Device_ID_Size(&numberOfChars, deviceInstanceNumber, 0) != CR_SUCCESS)
return QString();
-
- QByteArray data(requiredSize * sizeof(wchar_t), 0);
- if (!::SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData,
- reinterpret_cast<wchar_t *>(data.data()), data.size(), NULL)) {
- // TODO: error handling with GetLastError
+ // The size does not include the terminating null character.
+ ++numberOfChars;
+ QByteArray outputBuffer(numberOfChars * sizeof(wchar_t), 0);
+ if (::CM_Get_Device_ID(deviceInstanceNumber, reinterpret_cast<wchar_t *>(outputBuffer.data()),
+ outputBuffer.size(), 0) != CR_SUCCESS) {
return QString();
}
+ return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(outputBuffer.constData()));
+}
- return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()));
+static DEVINST parentDeviceInstanceNumber(DEVINST childDeviceInstanceNumber)
+{
+ ULONG nodeStatus = 0;
+ ULONG problemNumber = 0;
+ if (::CM_Get_DevNode_Status(&nodeStatus, &problemNumber,
+ childDeviceInstanceNumber, 0) != CR_SUCCESS) {
+ return 0;
+ }
+ DEVINST parentInstanceNumber = 0;
+ if (::CM_Get_Parent(&parentInstanceNumber, childDeviceInstanceNumber, 0) != CR_SUCCESS)
+ return 0;
+ return parentInstanceNumber;
}
static QString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData)
@@ -254,9 +267,14 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
serialPortInfo.d_ptr->manufacturer =
deviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_MFG);
- s = deviceInstanceIdentifier(deviceInfoSet, &deviceInfoData).toUpper();
-
- serialPortInfo.d_ptr->serialNumber = deviceSerialNumber(s);
+ s = deviceInstanceIdentifier(deviceInfoData.DevInst).toUpper();
+ QString serialNumber = deviceSerialNumber(s);
+ if (serialNumber.isEmpty()) {
+ const DEVINST parentDevNumber = parentDeviceInstanceNumber(deviceInfoData.DevInst);
+ const QString parentDevIdentifier = deviceInstanceIdentifier(parentDevNumber).toUpper();
+ serialNumber = deviceSerialNumber(parentDevIdentifier);
+ }
+ serialPortInfo.d_ptr->serialNumber = serialNumber;
int index = s.indexOf(usbVendorIdentifierPrefix);
if (index != -1) {