diff --git a/src/blackmisc/blackmisc.pro b/src/blackmisc/blackmisc.pro index fc312c982..d3c2857e5 100644 --- a/src/blackmisc/blackmisc.pro +++ b/src/blackmisc/blackmisc.pro @@ -69,6 +69,8 @@ SOURCES += *.cpp \ win32 { LIBS *= -lShell32 -lDbghelp -lversion + # Remove the one below once the Reg functions are removed again from CIdentifier + LIBS *= -lAdvapi32 } win32-g++ { LIBS *= -lpsapi diff --git a/src/blackmisc/identifier.cpp b/src/blackmisc/identifier.cpp index 200c96bc9..50da7124c 100644 --- a/src/blackmisc/identifier.cpp +++ b/src/blackmisc/identifier.cpp @@ -10,10 +10,18 @@ #include "blackmisc/identifier.h" #include -#include #include +#include #include +#ifdef Q_OS_WIN +#include +#endif + +#ifdef Q_OS_MAC +#include +#endif + //! \private const QString &cachedLocalHostName() { @@ -21,12 +29,53 @@ const QString &cachedLocalHostName() return hostName; } +enum { + UuidStringLen = sizeof("00000000-0000-0000-0000-000000000000") +}; + +QByteArray getMachineUniqueIdImpl() +{ + // TODO RR: Remove the workaround branches as soon as the following two changes are published in 5.12.2 (TBC) + // https://codereview.qt-project.org/#/c/249256 + // https://codereview.qt-project.org/#/c/249399 + + QByteArray machineUniqueId; + #ifdef Q_OS_MAC + char uuid[UuidStringLen]; + size_t uuidlen = sizeof(uuid); + int ret = sysctlbyname("kern.uuid", uuid, &uuidlen, nullptr, 0); + if (ret == 0 && uuidlen == sizeof(uuid)) + { + machineUniqueId = QByteArray(uuid, uuidlen - 1); + } + #elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + HKEY key = nullptr; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS) + { + wchar_t buffer[UuidStringLen]; + DWORD size = sizeof(buffer); + bool ok = (RegQueryValueEx(key, L"MachineGuid", nullptr, nullptr, reinterpret_cast(buffer), &size) == ERROR_SUCCESS); + RegCloseKey(key); + if (ok) { machineUniqueId = QStringView(buffer, (size - 1) / 2).toLatin1(); } + } + #else + machineUniqueId = QSysInfo::machineUniqueId(); + #endif + return machineUniqueId; +} + +QByteArray cachedMachineUniqueId() +{ + static const QByteArray machineUniqueId = getMachineUniqueIdImpl(); + return machineUniqueId; +} + namespace BlackMisc { CIdentifier::CIdentifier(const QString &name) : ITimestampBased(QDateTime::currentMSecsSinceEpoch()), m_name(name.trimmed()), - m_machineIdBase64(QDBusConnection::localMachineId().toBase64()), + m_machineIdBase64(cachedMachineUniqueId().toBase64()), m_machineName(cachedLocalHostName()), m_processName(QCoreApplication::applicationName()), m_processId(QCoreApplication::applicationPid()) @@ -115,7 +164,7 @@ namespace BlackMisc bool CIdentifier::isFromLocalMachine() const { - return QDBusConnection::localMachineId() == getMachineId(); + return cachedMachineUniqueId() == getMachineId(); } bool CIdentifier::hasApplicationProcessId() const @@ -175,4 +224,5 @@ namespace BlackMisc { CValueObject::setPropertyByIndex(index, variant); } + } // ns diff --git a/tests/blackmisc/testidentifier/testidentifier.cpp b/tests/blackmisc/testidentifier/testidentifier.cpp index 4f41b4ac4..cfdfddc3d 100644 --- a/tests/blackmisc/testidentifier/testidentifier.cpp +++ b/tests/blackmisc/testidentifier/testidentifier.cpp @@ -32,6 +32,9 @@ namespace BlackMiscTest private slots: //! Identifier tests void identifierBasics(); + + //! Machine unique id tests + void machineUniqueId(); }; //! Test identifiable object @@ -59,6 +62,12 @@ namespace BlackMiscTest QVERIFY2(oa.identifier().getName() == q.objectName(), "Names shall be equal"); } + void CTestIdentifier::machineUniqueId() + { + CIdentifier o; + QVERIFY2(!o.getMachineId().isEmpty(), "Machine id shall never be empty! If this test failed on a supported platform, get a fallback solution!"); + } + CTestIdentifiable::CTestIdentifiable(QObject *nameObject) : CIdentifiable(nameObject) { }