mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:00:05 +00:00
Get serial bus reported device description
This commit is contained in:
parent
230c96e450
commit
cb14fba3b0
2 changed files with 200 additions and 7 deletions
|
|
@ -608,6 +608,7 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
Boost::timer
|
Boost::timer
|
||||||
QMapLibre::Core
|
QMapLibre::Core
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:opengl32>
|
$<$<CXX_COMPILER_ID:MSVC>:opengl32>
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:SetupAPI>
|
||||||
Fontconfig::Fontconfig
|
Fontconfig::Fontconfig
|
||||||
GeographicLib::GeographicLib
|
GeographicLib::GeographicLib
|
||||||
GEOS::geos
|
GEOS::geos
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,12 @@
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <Windows.h>
|
# include <Windows.h>
|
||||||
# include <cstdlib>
|
# include <SetupAPI.h>
|
||||||
|
# include <initguid.h>
|
||||||
|
# include <devguid.h>
|
||||||
|
# include <devpkey.h>
|
||||||
# include <tchar.h>
|
# include <tchar.h>
|
||||||
|
# include <cstdlib>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
|
|
@ -36,9 +40,17 @@ public:
|
||||||
~Impl() = default;
|
~Impl() = default;
|
||||||
|
|
||||||
void LogSerialPortInfo(const QSerialPortInfo& info);
|
void LogSerialPortInfo(const QSerialPortInfo& info);
|
||||||
|
void ReadComPortProperties();
|
||||||
void ReadComPortSettings();
|
void ReadComPortSettings();
|
||||||
void RefreshSerialDevices();
|
void RefreshSerialDevices();
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static std::string GetDevicePropertyString(HDEVINFO& deviceInfoSet,
|
||||||
|
SP_DEVINFO_DATA& deviceInfoData,
|
||||||
|
DEVPROPKEY propertyKey);
|
||||||
|
static std::string GetRegistryValueDataString(HKEY hKey, LPCTSTR lpValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
SerialPortDialog* self_;
|
SerialPortDialog* self_;
|
||||||
QStandardItemModel* model_;
|
QStandardItemModel* model_;
|
||||||
|
|
||||||
|
|
@ -88,9 +100,70 @@ void SerialPortDialog::Impl::RefreshSerialDevices()
|
||||||
LogSerialPortInfo(port);
|
LogSerialPortInfo(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadComPortProperties();
|
||||||
ReadComPortSettings();
|
ReadComPortSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SerialPortDialog::Impl::ReadComPortProperties()
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
GUID classGuid = GUID_DEVCLASS_PORTS;
|
||||||
|
PCWSTR enumerator = nullptr;
|
||||||
|
HWND hwndParent = nullptr;
|
||||||
|
DWORD flags = DIGCF_PRESENT;
|
||||||
|
HDEVINFO deviceInfoSet;
|
||||||
|
|
||||||
|
// Retrieve COM port devices
|
||||||
|
deviceInfoSet =
|
||||||
|
SetupDiGetClassDevs(&classGuid, enumerator, hwndParent, flags);
|
||||||
|
if (deviceInfoSet == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
logger_->error("Error getting COM port devices");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD memberIndex = 0;
|
||||||
|
SP_DEVINFO_DATA deviceInfoData {};
|
||||||
|
deviceInfoData.cbSize = sizeof(deviceInfoData);
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
// For each COM port device
|
||||||
|
while (SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex++, &deviceInfoData))
|
||||||
|
{
|
||||||
|
DWORD scope = DICS_FLAG_GLOBAL;
|
||||||
|
DWORD hwProfile = 0;
|
||||||
|
DWORD keyType = DIREG_DEV;
|
||||||
|
REGSAM samDesired = KEY_READ;
|
||||||
|
HKEY devRegKey = SetupDiOpenDevRegKey(
|
||||||
|
deviceInfoSet, &deviceInfoData, scope, hwProfile, keyType, samDesired);
|
||||||
|
|
||||||
|
if (devRegKey == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
logger_->error("Unable to open device registry key: {}",
|
||||||
|
GetLastError());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Port Name and Device Description
|
||||||
|
std::string portName =
|
||||||
|
GetRegistryValueDataString(devRegKey, TEXT("PortName"));
|
||||||
|
|
||||||
|
if (portName.empty())
|
||||||
|
{
|
||||||
|
// Ignore device without port name
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string busReportedDeviceDesc = GetDevicePropertyString(
|
||||||
|
deviceInfoSet, deviceInfoData, DEVPKEY_Device_BusReportedDeviceDesc);
|
||||||
|
|
||||||
|
logger_->debug("Port: {} ({})", portName, busReportedDeviceDesc);
|
||||||
|
|
||||||
|
RegCloseKey(devRegKey);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void SerialPortDialog::Impl::ReadComPortSettings()
|
void SerialPortDialog::Impl::ReadComPortSettings()
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
@ -126,12 +199,12 @@ void SerialPortDialog::Impl::ReadComPortSettings()
|
||||||
|
|
||||||
// Enumerate each port value
|
// Enumerate each port value
|
||||||
while ((status = RegEnumValue(hkResult,
|
while ((status = RegEnumValue(hkResult,
|
||||||
dwIndex,
|
dwIndex++,
|
||||||
valueName,
|
valueName,
|
||||||
&valueNameSize,
|
&valueNameSize,
|
||||||
lpReserved,
|
lpReserved,
|
||||||
&type,
|
&type,
|
||||||
(LPBYTE) &valueData,
|
reinterpret_cast<LPBYTE>(&valueData),
|
||||||
&valueDataSize)) == ERROR_SUCCESS ||
|
&valueDataSize)) == ERROR_SUCCESS ||
|
||||||
status == ERROR_MORE_DATA)
|
status == ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
|
|
@ -176,24 +249,143 @@ void SerialPortDialog::Impl::ReadComPortSettings()
|
||||||
|
|
||||||
std::string portData = buffer;
|
std::string portData = buffer;
|
||||||
|
|
||||||
logger_->debug("Port {} has data \"{}\"", portName, portData);
|
logger_->debug("Port Settings: {} ({})", portName, portData);
|
||||||
}
|
}
|
||||||
|
|
||||||
valueNameSize = maxValueNameSize;
|
valueNameSize = maxValueNameSize;
|
||||||
valueDataSize = sizeof(valueData);
|
valueDataSize = sizeof(valueData);
|
||||||
++dwIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hkResult);
|
RegCloseKey(hkResult);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger_->warn("Could not open COM port settings registry key: {}",
|
logger_->error("Could not open COM port settings registry key: {}",
|
||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
std::string
|
||||||
|
SerialPortDialog::Impl::GetDevicePropertyString(HDEVINFO& deviceInfoSet,
|
||||||
|
SP_DEVINFO_DATA& deviceInfoData,
|
||||||
|
DEVPROPKEY propertyKey)
|
||||||
|
{
|
||||||
|
std::string devicePropertyString {};
|
||||||
|
|
||||||
|
DEVPROPTYPE propertyType = 0;
|
||||||
|
std::vector<TCHAR> propertyBuffer {};
|
||||||
|
DWORD requiredSize = 0;
|
||||||
|
DWORD flags = 0;
|
||||||
|
|
||||||
|
BOOL status = SetupDiGetDeviceProperty(deviceInfoSet,
|
||||||
|
&deviceInfoData,
|
||||||
|
&propertyKey,
|
||||||
|
&propertyType,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&requiredSize,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (requiredSize > 0)
|
||||||
|
{
|
||||||
|
propertyBuffer.reserve(requiredSize / sizeof(TCHAR));
|
||||||
|
|
||||||
|
status = SetupDiGetDeviceProperty(
|
||||||
|
deviceInfoSet,
|
||||||
|
&deviceInfoData,
|
||||||
|
&propertyKey,
|
||||||
|
&propertyType,
|
||||||
|
reinterpret_cast<PBYTE>(propertyBuffer.data()),
|
||||||
|
static_cast<DWORD>(propertyBuffer.capacity() * sizeof(TCHAR)),
|
||||||
|
&requiredSize,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status && requiredSize > 0)
|
||||||
|
{
|
||||||
|
errno_t error;
|
||||||
|
std::size_t returnValue;
|
||||||
|
|
||||||
|
devicePropertyString.resize(requiredSize / sizeof(TCHAR));
|
||||||
|
|
||||||
|
if ((error = wcstombs_s(&returnValue,
|
||||||
|
devicePropertyString.data(),
|
||||||
|
devicePropertyString.size(),
|
||||||
|
propertyBuffer.data(),
|
||||||
|
_TRUNCATE)) != 0)
|
||||||
|
{
|
||||||
|
logger_->error("Error converting device property string: {}",
|
||||||
|
returnValue);
|
||||||
|
devicePropertyString.clear();
|
||||||
|
}
|
||||||
|
else if (!devicePropertyString.empty())
|
||||||
|
{
|
||||||
|
// Remove trailing null
|
||||||
|
devicePropertyString.erase(devicePropertyString.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devicePropertyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SerialPortDialog::Impl::GetRegistryValueDataString(HKEY hKey,
|
||||||
|
LPCTSTR lpValue)
|
||||||
|
{
|
||||||
|
std::string dataString {};
|
||||||
|
|
||||||
|
LPCTSTR lpSubKey = nullptr;
|
||||||
|
DWORD dwFlags = RRF_RT_REG_SZ; // Restrict type to REG_SZ
|
||||||
|
DWORD dwType;
|
||||||
|
|
||||||
|
std::vector<TCHAR> dataBuffer {};
|
||||||
|
DWORD dataBufferSize = 0;
|
||||||
|
|
||||||
|
LSTATUS status = RegGetValue(
|
||||||
|
hKey, lpSubKey, lpValue, dwFlags, &dwType, nullptr, &dataBufferSize);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS && dataBufferSize > 0)
|
||||||
|
{
|
||||||
|
dataBuffer.reserve(dataBufferSize / sizeof(TCHAR));
|
||||||
|
|
||||||
|
status = RegGetValue(hKey,
|
||||||
|
lpSubKey,
|
||||||
|
lpValue,
|
||||||
|
dwFlags,
|
||||||
|
&dwType,
|
||||||
|
reinterpret_cast<PVOID>(dataBuffer.data()),
|
||||||
|
&dataBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS && dataBufferSize > 0)
|
||||||
|
{
|
||||||
|
errno_t error;
|
||||||
|
std::size_t returnValue;
|
||||||
|
|
||||||
|
dataString.resize(dataBufferSize / sizeof(TCHAR));
|
||||||
|
|
||||||
|
if ((error = wcstombs_s(&returnValue,
|
||||||
|
dataString.data(),
|
||||||
|
dataString.size(),
|
||||||
|
dataBuffer.data(),
|
||||||
|
_TRUNCATE)) != 0)
|
||||||
|
{
|
||||||
|
logger_->error("Error converting registry value data string: {}",
|
||||||
|
returnValue);
|
||||||
|
dataString.clear();
|
||||||
|
}
|
||||||
|
else if (!dataString.empty())
|
||||||
|
{
|
||||||
|
// Remove trailing null
|
||||||
|
dataString.erase(dataString.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataString;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue