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);