From 12ad8fb8d9dfeb16393405ab9949e4076b088835 Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 18:01:04 +0300 Subject: [PATCH 1/9] add hwid --- include/global/DataStore.hpp | 1 + include/ui/setting/dialog_basic_settings.ui | 7 ++ src/global/Configs.cpp | 1 + src/global/HTTPRequestHelper.cpp | 100 ++++++++++++++++++++ src/ui/setting/dialog_basic_settings.cpp | 2 + 5 files changed, 111 insertions(+) diff --git a/include/global/DataStore.hpp b/include/global/DataStore.hpp index 3d0cd31..a72d962 100644 --- a/include/global/DataStore.hpp +++ b/include/global/DataStore.hpp @@ -95,6 +95,7 @@ namespace Configs { bool sub_clear = false; bool sub_insecure = false; int sub_auto_update = -30; + bool sub_send_hwid = false; // Security bool skip_cert = false; diff --git a/include/ui/setting/dialog_basic_settings.ui b/include/ui/setting/dialog_basic_settings.ui index bb06225..e71e833 100644 --- a/include/ui/setting/dialog_basic_settings.ui +++ b/include/ui/setting/dialog_basic_settings.ui @@ -551,6 +551,13 @@ + + + + Includes sending HWID, model, and OS version + + + diff --git a/src/global/Configs.cpp b/src/global/Configs.cpp index ad509ce..1a41674 100644 --- a/src/global/Configs.cpp +++ b/src/global/Configs.cpp @@ -279,6 +279,7 @@ namespace Configs { _add(new configItem("sub_clear", &sub_clear, itemType::boolean)); _add(new configItem("sub_insecure", &sub_insecure, itemType::boolean)); _add(new configItem("sub_auto_update", &sub_auto_update, itemType::integer)); + _add(new configItem("sub_send_hwid", &sub_send_hwid, itemType::boolean)); _add(new configItem("start_minimal", &start_minimal, itemType::boolean)); _add(new configItem("max_log_line", &max_log_line, itemType::integer)); _add(new configItem("splitter_state", &splitter_state, itemType::string)); diff --git a/src/global/HTTPRequestHelper.cpp b/src/global/HTTPRequestHelper.cpp index 1f7ff81..dd01bda 100644 --- a/src/global/HTTPRequestHelper.cpp +++ b/src/global/HTTPRequestHelper.cpp @@ -1,3 +1,9 @@ +#include +#ifdef Q_OS_WIN + #include +#endif +#undef boolean + #include "include/global/HTTPRequestHelper.hpp" #include @@ -13,6 +19,91 @@ namespace Configs_network { + namespace { + struct DeviceDetails { + QString hwid; + QString os; + QString osVersion; + QString model; + }; + +#ifdef Q_OS_WIN + static QString readRegistryStringValue(const QString &keyPath, const QString &valueName) { + HKEY hKey = nullptr; + std::wstring keyPathW = keyPath.toStdWString(); + LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyPathW.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + if (res != ERROR_SUCCESS) return QString(); + DWORD type = 0; + DWORD cbData = 0; + res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, &type, nullptr, &cbData); + if (res != ERROR_SUCCESS || type != REG_SZ) { + RegCloseKey(hKey); + return QString(); + } + std::vector buffer(cbData/sizeof(wchar_t) + 1); + res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, nullptr, reinterpret_cast(buffer.data()), &cbData); + if (res != ERROR_SUCCESS) { + RegCloseKey(hKey); + return QString(); + } + RegCloseKey(hKey); + return QString::fromWCharArray(buffer.data()); + } +#endif + + static DeviceDetails GetDeviceDetails() { + DeviceDetails details; + +#ifdef Q_OS_WIN + const QString regPath = QString::fromUtf8("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SoftwareProtectionPlatform\\Plugins\\Objects\\msft:rm/algorithm/hwid/4.0"); + const QString valueName = QString::fromUtf8("ModuleId"); + details.hwid = readRegistryStringValue(regPath, valueName); + + if (details.hwid.isEmpty()) { + auto productId = QSysInfo::machineUniqueId(); + if (productId.isEmpty()) productId = QSysInfo::productType().toUtf8(); + details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productId)); + } + + details.os = QStringLiteral("Windows"); + + VersionInfo info; + WinVersion::GetVersion(info); + details.osVersion = QString("%1.%2.%3").arg(info.Major).arg(info.Minor).arg(info.BuildNum); + + details.model = QSysInfo::prettyProductName(); +#elif defined(Q_OS_LINUX) + QString mid; + QFile f1("/etc/machine-id"); + if (f1.exists() && f1.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f1.readAll()).trimmed(); + f1.close(); + } else { + QFile f2("/var/lib/dbus/machine-id"); + if (f2.exists() && f2.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f2.readAll()).trimmed(); + f2.close(); + } + } + details.hwid = mid; + details.os = QStringLiteral("Linux"); + details.osVersion = QSysInfo::kernelVersion(); + details.model = QSysInfo::prettyProductName(); +#elif defined(Q_OS_MACOS) + details.hwid = QSysInfo::machineUniqueId(); + details.os = QStringLiteral("macOS"); + details.osVersion = QSysInfo::productVersion(); + details.model = QSysInfo::prettyProductName(); +#else + details.hwid = QSysInfo::machineUniqueId(); + details.os = QSysInfo::productType(); + details.osVersion = QSysInfo::productVersion(); + details.model = QSysInfo::prettyProductName(); +#endif + return details; + } +} + HTTPResponse NetworkRequestHelper::HttpGet(const QString &url) { QNetworkRequest request; QNetworkAccessManager accessManager; @@ -35,6 +126,15 @@ namespace Configs_network { c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone); request.setSslConfiguration(c); } + //Attach HWID and device info headers if enabled in settings + if (Configs::dataStore->sub_send_hwid && !request.url().toString().contains("/throneproj/")) { + auto details = GetDeviceDetails(); + + if (!details.hwid.isEmpty()) request.setRawHeader("x-hwid", details.hwid.toUtf8()); + if (!details.os.isEmpty()) request.setRawHeader("x-device-os", details.os.toUtf8()); + if (!details.osVersion.isEmpty()) request.setRawHeader("x-ver-os", details.osVersion.toUtf8()); + if (!details.model.isEmpty()) request.setRawHeader("x-device-model", details.model.toUtf8()); + } // auto _reply = accessManager.get(request); connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList &errors) { diff --git a/src/ui/setting/dialog_basic_settings.cpp b/src/ui/setting/dialog_basic_settings.cpp index 76c2d6c..34fe948 100644 --- a/src/ui/setting/dialog_basic_settings.cpp +++ b/src/ui/setting/dialog_basic_settings.cpp @@ -116,6 +116,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) D_LOAD_BOOL(sub_use_proxy) D_LOAD_BOOL(sub_clear) D_LOAD_BOOL(sub_insecure) + D_LOAD_BOOL(sub_send_hwid) D_LOAD_INT_ENABLE(sub_auto_update, sub_auto_update_enable) // Core @@ -200,6 +201,7 @@ void DialogBasicSettings::accept() { D_SAVE_BOOL(sub_use_proxy) D_SAVE_BOOL(sub_clear) D_SAVE_BOOL(sub_insecure) + D_SAVE_BOOL(sub_send_hwid) D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable) // Core From 1ec5509c154a03282cbfaf10a2f1320a01b274e2 Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:42:46 +0300 Subject: [PATCH 2/9] refactoring hwid --- include/global/DeviceDetailsHelper.hpp | 12 ++ include/ui/setting/dialog_basic_settings.ui | 2 +- res/translations/ru_RU.ts | 4 + src/global/DeviceDetailsHelper.cpp | 200 ++++++++++++++++++++ src/global/HTTPRequestHelper.cpp | 92 +-------- 5 files changed, 218 insertions(+), 92 deletions(-) create mode 100644 include/global/DeviceDetailsHelper.hpp create mode 100644 src/global/DeviceDetailsHelper.cpp diff --git a/include/global/DeviceDetailsHelper.hpp b/include/global/DeviceDetailsHelper.hpp new file mode 100644 index 0000000..0cfe289 --- /dev/null +++ b/include/global/DeviceDetailsHelper.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct DeviceDetails { + QString hwid; + QString os; + QString osVersion; + QString model; +}; + +DeviceDetails GetDeviceDetails(); \ No newline at end of file diff --git a/include/ui/setting/dialog_basic_settings.ui b/include/ui/setting/dialog_basic_settings.ui index e71e833..d75caad 100644 --- a/include/ui/setting/dialog_basic_settings.ui +++ b/include/ui/setting/dialog_basic_settings.ui @@ -554,7 +554,7 @@ - Includes sending HWID, model, and OS version + Enable sending HWID, device model, and OS version when updating subscription diff --git a/res/translations/ru_RU.ts b/res/translations/ru_RU.ts index a17db29..4b5a747 100644 --- a/res/translations/ru_RU.ts +++ b/res/translations/ru_RU.ts @@ -90,6 +90,10 @@ Clear servers before updating subscription Очищать список серверов перед обновлением подписки + + + Enable sending HWID, device model, and OS version when updating subscription + Включить отправку HWID, модели устройства и версии ОС при обновлении подписки Core diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp new file mode 100644 index 0000000..8b8618e --- /dev/null +++ b/src/global/DeviceDetailsHelper.cpp @@ -0,0 +1,200 @@ +#include "include/global/DeviceDetailsHelper.hpp" + +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN +#include +#include "include/sys/windows/WinVersion.h" +#include +#include +#include +#pragma comment(lib, "wbemuuid.lib") +#endif + + +#ifdef Q_OS_WIN +static QString readRegistryStringValue(const QString& keyPath, const QString& valueName) { + HKEY hKey = nullptr; + std::wstring keyPathW = keyPath.toStdWString(); + LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyPathW.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + if (res != ERROR_SUCCESS) return QString(); + DWORD type = 0; + DWORD cbData = 0; + res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, &type, nullptr, &cbData); + if (res != ERROR_SUCCESS || type != REG_SZ) { + RegCloseKey(hKey); + return QString(); + } + std::vector buffer(cbData / sizeof(wchar_t) + 1); + res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, nullptr, reinterpret_cast(buffer.data()), &cbData); + if (res != ERROR_SUCCESS) { + RegCloseKey(hKey); + return QString(); + } + RegCloseKey(hKey); + return QString::fromWCharArray(buffer.data()); +} + +static QString queryWmiProperty(const QString& wmiClass, const QString& property) { + HRESULT hres; + + hres = CoInitializeEx(0, COINIT_MULTITHREADED); + if (FAILED(hres)) return QString(); + + hres = CoInitializeSecurity( + NULL, -1, NULL, NULL, + RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, EOAC_NONE, NULL + ); + if (FAILED(hres) && hres != RPC_E_TOO_LATE) { + CoUninitialize(); + return QString(); + } + + IWbemLocator* pLoc = NULL; + hres = CoCreateInstance( + CLSID_WbemLocator, 0, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID*)&pLoc + ); + if (FAILED(hres)) { + CoUninitialize(); + return QString(); + } + + IWbemServices* pSvc = NULL; + hres = pLoc->ConnectServer( + _bstr_t(L"ROOT\\CIMV2"), + NULL, NULL, 0, NULL, 0, 0, &pSvc + ); + if (FAILED(hres)) { + pLoc->Release(); + CoUninitialize(); + return QString(); + } + + hres = CoSetProxyBlanket( + pSvc, + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + NULL, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, + EOAC_NONE + ); + if (FAILED(hres)) { + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return QString(); + } + + IEnumWbemClassObject* pEnumerator = NULL; + QString query = QString("SELECT %1 FROM %2").arg(property, wmiClass); + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t(query.toStdWString().c_str()), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator + ); + if (FAILED(hres)) { + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return QString(); + } + + IWbemClassObject* pclsObj = NULL; + ULONG uReturn = 0; + QString result; + + if (pEnumerator) { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (uReturn) { + VARIANT vtProp; + VariantInit(&vtProp); + hr = pclsObj->Get(property.toStdWString().c_str(), 0, &vtProp, 0, 0); + if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR) { + result = QString::fromWCharArray(vtProp.bstrVal); + } + VariantClear(&vtProp); + pclsObj->Release(); + } + pEnumerator->Release(); + } + + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + + return result; +} + +static QString winBaseBoard() { + return queryWmiProperty("Win32_BaseBoard", "Product"); +} + +static QString winModel() { + return queryWmiProperty("Win32_ComputerSystem", "Model"); +} +#endif + +DeviceDetails GetDeviceDetails() { + DeviceDetails details; + +#ifdef Q_OS_WIN + const QString regPath = QStringLiteral("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SoftwareProtectionPlatform\\Plugins\\Objects\\msft:rm/algorithm/hwid/4.0"); + const QString valueName = QStringLiteral("ModuleId"); + details.hwid = readRegistryStringValue(regPath, valueName); + + if (details.hwid.isEmpty()) { + auto productId = QSysInfo::machineUniqueId(); + if (productId.isEmpty()) productId = QSysInfo::productType().toUtf8(); + details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productId)); + } + + details.os = QStringLiteral("Windows"); + VersionInfo info; + WinVersion::GetVersion(info); + details.osVersion = QString("%1.%2.%3").arg(info.Major).arg(info.Minor).arg(info.BuildNum); + auto wm = winModel(); + auto wbb = winBaseBoard(); + details.model = (wm == wbb) ? wm : wm + "/" + wbb; +#elif defined(Q_OS_LINUX) + QString mid; + QFile f1("/etc/machine-id"); + if (f1.exists() && f1.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f1.readAll()).trimmed(); + f1.close(); + } + else { + QFile f2("/var/lib/dbus/machine-id"); + if (f2.exists() && f2.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f2.readAll()).trimmed(); + f2.close(); + } + } + details.hwid = mid; + details.os = QStringLiteral("Linux"); + details.osVersion = QSysInfo::kernelVersion(); + details.model = QSysInfo::prettyProductName(); +#elif defined(Q_OS_MACOS) + details.hwid = QSysInfo::machineUniqueId(); + details.os = QStringLiteral("macOS"); + details.osVersion = QSysInfo::productVersion(); + details.model = QSysInfo::prettyProductName(); +#else + details.hwid = QSysInfo::machineUniqueId(); + details.os = QSysInfo::productType(); + details.osVersion = QSysInfo::productVersion(); + details.model = QSysInfo::prettyProductName(); +#endif + return details; +} \ No newline at end of file diff --git a/src/global/HTTPRequestHelper.cpp b/src/global/HTTPRequestHelper.cpp index dd01bda..01fd208 100644 --- a/src/global/HTTPRequestHelper.cpp +++ b/src/global/HTTPRequestHelper.cpp @@ -1,9 +1,3 @@ -#include -#ifdef Q_OS_WIN - #include -#endif -#undef boolean - #include "include/global/HTTPRequestHelper.hpp" #include @@ -16,94 +10,10 @@ #include "include/global/Configs.hpp" #include "include/ui/mainwindow.h" +#include "include/global/DeviceDetailsHelper.hpp" namespace Configs_network { - namespace { - struct DeviceDetails { - QString hwid; - QString os; - QString osVersion; - QString model; - }; - -#ifdef Q_OS_WIN - static QString readRegistryStringValue(const QString &keyPath, const QString &valueName) { - HKEY hKey = nullptr; - std::wstring keyPathW = keyPath.toStdWString(); - LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyPathW.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); - if (res != ERROR_SUCCESS) return QString(); - DWORD type = 0; - DWORD cbData = 0; - res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, &type, nullptr, &cbData); - if (res != ERROR_SUCCESS || type != REG_SZ) { - RegCloseKey(hKey); - return QString(); - } - std::vector buffer(cbData/sizeof(wchar_t) + 1); - res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, nullptr, reinterpret_cast(buffer.data()), &cbData); - if (res != ERROR_SUCCESS) { - RegCloseKey(hKey); - return QString(); - } - RegCloseKey(hKey); - return QString::fromWCharArray(buffer.data()); - } -#endif - - static DeviceDetails GetDeviceDetails() { - DeviceDetails details; - -#ifdef Q_OS_WIN - const QString regPath = QString::fromUtf8("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SoftwareProtectionPlatform\\Plugins\\Objects\\msft:rm/algorithm/hwid/4.0"); - const QString valueName = QString::fromUtf8("ModuleId"); - details.hwid = readRegistryStringValue(regPath, valueName); - - if (details.hwid.isEmpty()) { - auto productId = QSysInfo::machineUniqueId(); - if (productId.isEmpty()) productId = QSysInfo::productType().toUtf8(); - details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productId)); - } - - details.os = QStringLiteral("Windows"); - - VersionInfo info; - WinVersion::GetVersion(info); - details.osVersion = QString("%1.%2.%3").arg(info.Major).arg(info.Minor).arg(info.BuildNum); - - details.model = QSysInfo::prettyProductName(); -#elif defined(Q_OS_LINUX) - QString mid; - QFile f1("/etc/machine-id"); - if (f1.exists() && f1.open(QIODevice::ReadOnly | QIODevice::Text)) { - mid = QString::fromUtf8(f1.readAll()).trimmed(); - f1.close(); - } else { - QFile f2("/var/lib/dbus/machine-id"); - if (f2.exists() && f2.open(QIODevice::ReadOnly | QIODevice::Text)) { - mid = QString::fromUtf8(f2.readAll()).trimmed(); - f2.close(); - } - } - details.hwid = mid; - details.os = QStringLiteral("Linux"); - details.osVersion = QSysInfo::kernelVersion(); - details.model = QSysInfo::prettyProductName(); -#elif defined(Q_OS_MACOS) - details.hwid = QSysInfo::machineUniqueId(); - details.os = QStringLiteral("macOS"); - details.osVersion = QSysInfo::productVersion(); - details.model = QSysInfo::prettyProductName(); -#else - details.hwid = QSysInfo::machineUniqueId(); - details.os = QSysInfo::productType(); - details.osVersion = QSysInfo::productVersion(); - details.model = QSysInfo::prettyProductName(); -#endif - return details; - } -} - HTTPResponse NetworkRequestHelper::HttpGet(const QString &url) { QNetworkRequest request; QNetworkAccessManager accessManager; From abe928d87ca114a04095bbcf5bd353830c52317d Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:49:53 +0300 Subject: [PATCH 3/9] update CMakeLists.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f9993c..ddf13ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ set(PROJECT_SOURCES src/global/Configs.cpp src/global/Utils.cpp src/global/HTTPRequestHelper.cpp + src/global/DeviceDetailsHelper.cpp 3rdparty/base64.cpp 3rdparty/qrcodegen.cpp From 076a138925d902625aa1c9208ada263ceec4f7e1 Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:11:20 +0300 Subject: [PATCH 4/9] update DeviceDetailsHelper.cpp --- src/global/DeviceDetailsHelper.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index 8b8618e..9434c74 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -68,10 +68,12 @@ static QString queryWmiProperty(const QString& wmiClass, const QString& property } IWbemServices* pSvc = NULL; + BSTR bstrNamespace = SysAllocString(L"ROOT\\CIMV2"); hres = pLoc->ConnectServer( - _bstr_t(L"ROOT\\CIMV2"), - NULL, NULL, 0, NULL, 0, 0, &pSvc + bstrNamespace, + NULL, NULL, NULL, 0, NULL, 0, &pSvc ); + SysFreeString(bstrNamespace); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); From 008d0c2ef2ab7679ed8dccbfb0e1abcc486523bc Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:11:20 +0300 Subject: [PATCH 5/9] update DeviceDetailsHelper.cpp --- src/global/DeviceDetailsHelper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index 9434c74..9795948 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -10,7 +10,6 @@ #include #include "include/sys/windows/WinVersion.h" #include -#include #include #pragma comment(lib, "wbemuuid.lib") #endif From 466fbd9fa6367e7246623337a948de9dfa15fafb Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:11:20 +0300 Subject: [PATCH 6/9] update DeviceDetailsHelper.cpp --- src/global/DeviceDetailsHelper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index 9795948..51eee1b 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -98,13 +98,17 @@ static QString queryWmiProperty(const QString& wmiClass, const QString& property IEnumWbemClassObject* pEnumerator = NULL; QString query = QString("SELECT %1 FROM %2").arg(property, wmiClass); + BSTR bstrWQL = SysAllocString(L"WQL"); + BSTR bstrQuery = SysAllocString(query.toStdWString().c_str()); hres = pSvc->ExecQuery( - bstr_t("WQL"), - bstr_t(query.toStdWString().c_str()), + bstrWQL, + bstrQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); + SysFreeString(bstrWQL); + SysFreeString(bstrQuery); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); From 8111b7fe72327b2e963afd8b69fdc333fdba144c Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sun, 21 Sep 2025 01:00:20 +0300 Subject: [PATCH 7/9] fix HWID --- src/global/DeviceDetailsHelper.cpp | 32 +++--------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index 51eee1b..b60eecf 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -16,28 +16,6 @@ #ifdef Q_OS_WIN -static QString readRegistryStringValue(const QString& keyPath, const QString& valueName) { - HKEY hKey = nullptr; - std::wstring keyPathW = keyPath.toStdWString(); - LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyPathW.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); - if (res != ERROR_SUCCESS) return QString(); - DWORD type = 0; - DWORD cbData = 0; - res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, &type, nullptr, &cbData); - if (res != ERROR_SUCCESS || type != REG_SZ) { - RegCloseKey(hKey); - return QString(); - } - std::vector buffer(cbData / sizeof(wchar_t) + 1); - res = RegQueryValueExW(hKey, (LPCWSTR)valueName.utf16(), nullptr, nullptr, reinterpret_cast(buffer.data()), &cbData); - if (res != ERROR_SUCCESS) { - RegCloseKey(hKey); - return QString(); - } - RegCloseKey(hKey); - return QString::fromWCharArray(buffer.data()); -} - static QString queryWmiProperty(const QString& wmiClass, const QString& property) { HRESULT hres; @@ -155,14 +133,10 @@ DeviceDetails GetDeviceDetails() { DeviceDetails details; #ifdef Q_OS_WIN - const QString regPath = QStringLiteral("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SoftwareProtectionPlatform\\Plugins\\Objects\\msft:rm/algorithm/hwid/4.0"); - const QString valueName = QStringLiteral("ModuleId"); - details.hwid = readRegistryStringValue(regPath, valueName); - + details.hwid = QSysInfo::machineUniqueId(); if (details.hwid.isEmpty()) { - auto productId = QSysInfo::machineUniqueId(); - if (productId.isEmpty()) productId = QSysInfo::productType().toUtf8(); - details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productId)); + auto productType = QSysInfo::productType().toUtf8(); + details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productType)); } details.os = QStringLiteral("Windows"); From 6f8f817a746fc53d04e316ab0cf6caa78e9e44b1 Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Sun, 21 Sep 2025 18:07:33 +0300 Subject: [PATCH 8/9] refactoring, add tooltip for HWID checkbox --- include/ui/setting/dialog_basic_settings.ui | 3 + res/translations/ru_RU.ts | 4 + src/global/DeviceDetailsHelper.cpp | 94 +++++++++++---------- src/ui/mainwindow.cpp | 4 + src/ui/setting/dialog_basic_settings.cpp | 8 ++ 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/include/ui/setting/dialog_basic_settings.ui b/include/ui/setting/dialog_basic_settings.ui index d75caad..c1e2be3 100644 --- a/include/ui/setting/dialog_basic_settings.ui +++ b/include/ui/setting/dialog_basic_settings.ui @@ -553,6 +553,9 @@ + + <html><head/><body><p>HWID=%1</p><p>OS=%2</p><p>OS Version=%3</p><p>Model=%4</p></body></html> + Enable sending HWID, device model, and OS version when updating subscription diff --git a/res/translations/ru_RU.ts b/res/translations/ru_RU.ts index 4b5a747..03e7aee 100644 --- a/res/translations/ru_RU.ts +++ b/res/translations/ru_RU.ts @@ -94,6 +94,10 @@ Enable sending HWID, device model, and OS version when updating subscription Включить отправку HWID, модели устройства и версии ОС при обновлении подписки + + + <html><head/><body><p>HWID=%1</p><p>OS=%2</p><p>OS Version=%3</p><p>Model=%4</p></body></html> + <html><head/><body><p>HWID=%1</p><p>ОС=%2</p><p>Версия ОС=%3</p><p>Модель=%4</p></body></html> Core diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index b60eecf..3850323 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -14,7 +14,6 @@ #pragma comment(lib, "wbemuuid.lib") #endif - #ifdef Q_OS_WIN static QString queryWmiProperty(const QString& wmiClass, const QString& property) { HRESULT hres; @@ -116,7 +115,6 @@ static QString queryWmiProperty(const QString& wmiClass, const QString& property pSvc->Release(); pLoc->Release(); CoUninitialize(); - return result; } @@ -130,50 +128,56 @@ static QString winModel() { #endif DeviceDetails GetDeviceDetails() { - DeviceDetails details; + static const DeviceDetails details = []() { + DeviceDetails d; -#ifdef Q_OS_WIN - details.hwid = QSysInfo::machineUniqueId(); - if (details.hwid.isEmpty()) { - auto productType = QSysInfo::productType().toUtf8(); - details.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productType)); - } - - details.os = QStringLiteral("Windows"); - VersionInfo info; - WinVersion::GetVersion(info); - details.osVersion = QString("%1.%2.%3").arg(info.Major).arg(info.Minor).arg(info.BuildNum); - auto wm = winModel(); - auto wbb = winBaseBoard(); - details.model = (wm == wbb) ? wm : wm + "/" + wbb; -#elif defined(Q_OS_LINUX) - QString mid; - QFile f1("/etc/machine-id"); - if (f1.exists() && f1.open(QIODevice::ReadOnly | QIODevice::Text)) { - mid = QString::fromUtf8(f1.readAll()).trimmed(); - f1.close(); - } - else { - QFile f2("/var/lib/dbus/machine-id"); - if (f2.exists() && f2.open(QIODevice::ReadOnly | QIODevice::Text)) { - mid = QString::fromUtf8(f2.readAll()).trimmed(); - f2.close(); + #ifdef Q_OS_WIN + d.hwid = QSysInfo::machineUniqueId(); + if (d.hwid.isEmpty()) { + auto productType = QSysInfo::productType().toUtf8(); + d.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productType)); } - } - details.hwid = mid; - details.os = QStringLiteral("Linux"); - details.osVersion = QSysInfo::kernelVersion(); - details.model = QSysInfo::prettyProductName(); -#elif defined(Q_OS_MACOS) - details.hwid = QSysInfo::machineUniqueId(); - details.os = QStringLiteral("macOS"); - details.osVersion = QSysInfo::productVersion(); - details.model = QSysInfo::prettyProductName(); -#else - details.hwid = QSysInfo::machineUniqueId(); - details.os = QSysInfo::productType(); - details.osVersion = QSysInfo::productVersion(); - details.model = QSysInfo::prettyProductName(); -#endif + + d.os = QStringLiteral("Windows ") + QSysInfo::productVersion(); + + VersionInfo info; + WinVersion::GetVersion(info); + d.osVersion = QString("%1.%2.%3").arg(info.Major).arg(info.Minor).arg(info.BuildNum); + + auto wm = winModel(); + auto wbb = winBaseBoard(); + d.model = (wm == wbb) ? wm : wm + "/" + wbb; + if (d.hwid.isEmpty()) d.model = QSysInfo::prettyProductName(); + #elif defined(Q_OS_LINUX) + QString mid; + QFile f1("/etc/machine-id"); + if (f1.exists() && f1.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f1.readAll()).trimmed(); + f1.close(); + } + else { + QFile f2("/var/lib/dbus/machine-id"); + if (f2.exists() && f2.open(QIODevice::ReadOnly | QIODevice::Text)) { + mid = QString::fromUtf8(f2.readAll()).trimmed(); + f2.close(); + } + } + d.hwid = mid; + d.os = QStringLiteral("Linux"); + d.osVersion = QSysInfo::kernelVersion(); + d.model = QSysInfo::prettyProductName(); + #elif defined(Q_OS_MACOS) + d.hwid = QSysInfo::machineUniqueId(); + d.os = QStringLiteral("macOS"); + d.osVersion = QSysInfo::productVersion(); + d.model = QSysInfo::prettyProductName(); + #else + d.hwid = QSysInfo::machineUniqueId(); + d.os = QSysInfo::productType(); + d.osVersion = QSysInfo::productVersion(); + d.model = QSysInfo::prettyProductName(); + #endif + return d; + }(); return details; } \ No newline at end of file diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index fdca3cc..61828af 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -54,6 +54,7 @@ #include <3rdparty/QHotkey/qhotkey.h> #include <3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp> #include +#include "include/global/DeviceDetailsHelper.hpp" #include "include/sys/macos/MacOS.h" @@ -133,6 +134,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi Configs::dataStore->inbound_socks_port = MkPort(); } + //init HWID data + runOnNewThread([=, this] {GetDeviceDetails(); }); + // Prepare core Configs::dataStore->core_port = MkPort(); if (Configs::dataStore->core_port <= 0) Configs::dataStore->core_port = 19810; diff --git a/src/ui/setting/dialog_basic_settings.cpp b/src/ui/setting/dialog_basic_settings.cpp index 34fe948..a6dd412 100644 --- a/src/ui/setting/dialog_basic_settings.cpp +++ b/src/ui/setting/dialog_basic_settings.cpp @@ -7,6 +7,7 @@ #include "include/global/GuiUtils.hpp" #include "include/global/Configs.hpp" #include "include/global/HTTPRequestHelper.hpp" +#include "include/global/DeviceDetailsHelper.hpp" #include #include @@ -118,6 +119,13 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) D_LOAD_BOOL(sub_insecure) D_LOAD_BOOL(sub_send_hwid) D_LOAD_INT_ENABLE(sub_auto_update, sub_auto_update_enable) + auto details = GetDeviceDetails(); + ui->sub_send_hwid->setToolTip( + ui->sub_send_hwid->toolTip() + .arg(details.hwid.isEmpty() ? "N/A" : details.hwid, + details.os.isEmpty() ? "N/A" : details.os, + details.osVersion.isEmpty() ? "N/A" : details.osVersion, + details.model.isEmpty() ? "N/A" : details.model)); // Core ui->groupBox_core->setTitle(software_core_name); From eb29cfc6d1ac612d2720313e22fe73d1e599dafb Mon Sep 17 00:00:00 2001 From: 0-Kutya-0 <85317162+0-Kutya-0@users.noreply.github.com> Date: Mon, 22 Sep 2025 02:19:05 +0300 Subject: [PATCH 9/9] small fix --- src/global/DeviceDetailsHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global/DeviceDetailsHelper.cpp b/src/global/DeviceDetailsHelper.cpp index 3850323..cf66ffb 100644 --- a/src/global/DeviceDetailsHelper.cpp +++ b/src/global/DeviceDetailsHelper.cpp @@ -138,7 +138,7 @@ DeviceDetails GetDeviceDetails() { d.hwid = QString("%1-%2").arg(QSysInfo::machineHostName(), QString::fromUtf8(productType)); } - d.os = QStringLiteral("Windows ") + QSysInfo::productVersion(); + d.os = QStringLiteral("Windows"); VersionInfo info; WinVersion::GetVersion(info);