QSysInfo: add a function that returns a somewhat permanent unique ID
We can use the D-Bus / systemd machine-id file (which is a UUID without the dashes) on systems with D-Bus. On Windows, there's a value in the registry that is filled when Windows is installed, like on Linux. For BSD systems, the kernel has a UUID we can use too, so extract that. Task-number: QTBUG-63425 Change-Id: I27eaacb532114dd188c4ffff13d32f2e3c1d74bb Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
dfbf5a7779
commit
16fba4a28f
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
** Copyright (C) 2016 Intel Corporation.
|
** Copyright (C) 2017 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
@ -73,6 +73,10 @@
|
|||||||
#include <Ws2tcpip.h>
|
#include <Ws2tcpip.h>
|
||||||
#endif // Q_OS_WINRT
|
#endif // Q_OS_WINRT
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
# include <qt_windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL)
|
#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL)
|
||||||
# include <envLib.h>
|
# include <envLib.h>
|
||||||
#endif
|
#endif
|
||||||
@ -2818,10 +2822,11 @@ QString QSysInfo::prettyProductName()
|
|||||||
|
|
||||||
This function returns the same as QHostInfo::localHostName().
|
This function returns the same as QHostInfo::localHostName().
|
||||||
|
|
||||||
\sa QHostInfo::localDomainName
|
\sa QHostInfo::localDomainName, machineUniqueId()
|
||||||
*/
|
*/
|
||||||
QString QSysInfo::machineHostName()
|
QString QSysInfo::machineHostName()
|
||||||
{
|
{
|
||||||
|
// the hostname can change, so we can't cache it
|
||||||
#if defined(Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
// gethostname(3) on Linux just calls uname(2), so do it ourselves
|
// gethostname(3) on Linux just calls uname(2), so do it ourselves
|
||||||
// and avoid a memcpy
|
// and avoid a memcpy
|
||||||
@ -2844,6 +2849,87 @@ QString QSysInfo::machineHostName()
|
|||||||
}
|
}
|
||||||
#endif // QT_BOOTSTRAPPED
|
#endif // QT_BOOTSTRAPPED
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UuidStringLen = sizeof("00000000-0000-0000-0000-000000000000") - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.10
|
||||||
|
|
||||||
|
Returns a unique ID for this machine, if one can be determined. If no
|
||||||
|
unique ID could be determined, this function returns an empty byte array.
|
||||||
|
Unlike machineHostName(), the value returned by this function is likely
|
||||||
|
globally unique.
|
||||||
|
|
||||||
|
A unique ID is useful in network operations to identify this machine for an
|
||||||
|
extended period of time, when the IP address could change or if this
|
||||||
|
machine could have more than one IP address. For example, the ID could be
|
||||||
|
used when communicating with a server or when storing device-specific data
|
||||||
|
in shared network storage.
|
||||||
|
|
||||||
|
Note that on some systems, this value will persist across reboots and on
|
||||||
|
some it will not. Applications should not blindly depend on this fact
|
||||||
|
without verifying the OS capabilities. In particular, on Linux systems,
|
||||||
|
this ID is usually permanent and it matches the D-Bus machine ID, except
|
||||||
|
for nodes without their own storage (replicated nodes).
|
||||||
|
|
||||||
|
\sa machineHostName()
|
||||||
|
*/
|
||||||
|
QByteArray QSysInfo::machineUniqueId()
|
||||||
|
{
|
||||||
|
// the machine unique ID cannot change
|
||||||
|
static const QByteArray cache = []() {
|
||||||
|
#ifdef Q_OS_BSD4
|
||||||
|
char uuid[UuidStringLen];
|
||||||
|
size_t uuidlen = sizeof(uuid);
|
||||||
|
# ifdef KERN_HOSTUUID
|
||||||
|
int name[] = { CTL_KERN, KERN_HOSTUUID };
|
||||||
|
if (sysctl(name, sizeof name / sizeof name[0], &uuid, &uuidlen, nullptr, 0) == 0
|
||||||
|
&& uuidlen == sizeof(uuid))
|
||||||
|
return QByteArray(uuid, uuidlen);
|
||||||
|
|
||||||
|
# else
|
||||||
|
// Darwin: no fixed value, we need to search by name
|
||||||
|
if (sysctlbyname("kern.uuid", uuid, &uuidlen, nullptr, 0) == 0 && uuidlen == sizeof(uuid))
|
||||||
|
return QByteArray(uuid, uuidlen);
|
||||||
|
# endif
|
||||||
|
#elif defined(Q_OS_UNIX)
|
||||||
|
// the modern name on Linux is /etc/machine-id, but that path is
|
||||||
|
// unlikely to exist on non-Linux (non-systemd) systems. The old
|
||||||
|
// path is more than enough.
|
||||||
|
static const char fullfilename[] = "/usr/local/var/lib/dbus/machine-id";
|
||||||
|
const char *firstfilename = fullfilename + sizeof("/usr/local") - 1;
|
||||||
|
int fd = qt_safe_open(firstfilename, O_RDONLY);
|
||||||
|
if (fd == -1 && errno == ENOENT)
|
||||||
|
fd = qt_safe_open(fullfilename, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd != -1) {
|
||||||
|
char buffer[32]; // 128 bits, hex-encoded
|
||||||
|
qint64 len = qt_safe_read(fd, buffer, sizeof(buffer));
|
||||||
|
qt_safe_close(fd);
|
||||||
|
|
||||||
|
if (len != -1)
|
||||||
|
return QByteArray(buffer, len);
|
||||||
|
}
|
||||||
|
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||||
|
// Let's poke at the registry
|
||||||
|
HKEY key = NULL;
|
||||||
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &key)
|
||||||
|
== ERROR_SUCCESS) {
|
||||||
|
wchar_t buffer[UuidStringLen + 1];
|
||||||
|
DWORD size = sizeof(buffer);
|
||||||
|
bool ok = (RegQueryValueEx(key, L"MachineGuid", NULL, NULL, (LPBYTE)buffer, &size) ==
|
||||||
|
ERROR_SUCCESS);
|
||||||
|
RegCloseKey(key);
|
||||||
|
if (ok)
|
||||||
|
return QStringView(buffer, (size - 1) / 2).toLatin1();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return QByteArray();
|
||||||
|
}();
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro void Q_ASSERT(bool test)
|
\macro void Q_ASSERT(bool test)
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
@ -240,6 +240,7 @@ QT_WARNING_POP
|
|||||||
static QString prettyProductName();
|
static QString prettyProductName();
|
||||||
|
|
||||||
static QString machineHostName();
|
static QString machineHostName();
|
||||||
|
static QByteArray machineUniqueId();
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef QT_SYSINFO_DEPRECATED_X
|
#undef QT_SYSINFO_DEPRECATED_X
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 Intel Corporation.
|
** Copyright (C) 2017 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
@ -133,6 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
printf("QSysInfo::productVersion() = %s\n", qPrintable(QSysInfo::productVersion()));
|
printf("QSysInfo::productVersion() = %s\n", qPrintable(QSysInfo::productVersion()));
|
||||||
printf("QSysInfo::prettyProductName() = %s\n", qPrintable(QSysInfo::prettyProductName()));
|
printf("QSysInfo::prettyProductName() = %s\n", qPrintable(QSysInfo::prettyProductName()));
|
||||||
printf("QSysInfo::machineHostName() = %s\n", qPrintable(QSysInfo::machineHostName()));
|
printf("QSysInfo::machineHostName() = %s\n", qPrintable(QSysInfo::machineHostName()));
|
||||||
|
printf("QSysInfo::machineUniqueId() = %s\n", QSysInfo::machineUniqueId().constData());
|
||||||
|
|
||||||
const auto osv = QOperatingSystemVersion::current();
|
const auto osv = QOperatingSystemVersion::current();
|
||||||
printf("QOperatingSystemVersion::current() = %s %d.%d.%d\n",
|
printf("QOperatingSystemVersion::current() = %s %d.%d.%d\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user