summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qsettings_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qsettings_win.cpp')
-rw-r--r--src/corelib/io/qsettings_win.cpp183
1 files changed, 71 insertions, 112 deletions
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index 43593ea25a..e88d738fe4 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsettings.h"
@@ -43,6 +7,7 @@
#include "qlist.h"
#include "qmap.h"
#include "qdebug.h"
+#include "qscopeguard.h"
#include <qt_windows.h>
// See "Accessing an Alternate Registry View" at:
@@ -59,6 +24,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/* Keys are stored in QStrings. If the variable name starts with 'u', this is a "user"
key, ie. "foo/bar/alpha/beta". If the variable name starts with 'r', this is a "registry"
key, ie. "\foo\bar\alpha\beta". */
@@ -75,7 +42,7 @@ static const REGSAM registryPermissions = KEY_READ | KEY_WRITE;
static QString keyPath(const QString &rKey)
{
- int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ int idx = rKey.lastIndexOf(u'\\');
if (idx == -1)
return QString();
return rKey.left(idx + 1);
@@ -83,7 +50,7 @@ static QString keyPath(const QString &rKey)
static QString keyName(const QString &rKey)
{
- int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ int idx = rKey.lastIndexOf(u'\\');
QString res;
if (idx == -1)
@@ -91,8 +58,8 @@ static QString keyName(const QString &rKey)
else
res = rKey.mid(idx + 1);
- if (res == QLatin1String("Default") || res == QLatin1String("."))
- res = QLatin1String("");
+ if (res == "Default"_L1 || res == "."_L1)
+ res = ""_L1;
return res;
}
@@ -247,7 +214,7 @@ static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildS
continue;
}
if (item.isEmpty())
- item = QLatin1String(".");
+ item = "."_L1;
result.append(item);
}
return result;
@@ -266,7 +233,7 @@ static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result,
for (int i = 0; i < childKeys.size(); ++i) {
QString s = rSubKey;
if (!s.isEmpty())
- s += QLatin1Char('\\');
+ s += u'\\';
s += childKeys.at(i);
result->insert(s, QString());
}
@@ -274,7 +241,7 @@ static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result,
for (int i = 0; i < childGroups.size(); ++i) {
QString s = rSubKey;
if (!s.isEmpty())
- s += QLatin1Char('\\');
+ s += u'\\';
s += childGroups.at(i);
allKeys(parentHandle, s, result, access);
}
@@ -386,14 +353,14 @@ public:
void remove(const QString &uKey) override;
void set(const QString &uKey, const QVariant &value) override;
- bool get(const QString &uKey, QVariant *value) const override;
+ std::optional<QVariant> get(const QString &uKey) const override;
QStringList children(const QString &uKey, ChildSpec spec) const override;
void clear() override;
void sync() override;
void flush() override;
bool isWritable() const override;
HKEY writeHandle() const;
- bool readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const;
+ std::optional<QVariant> readKey(HKEY parentHandle, const QString &rSubKey) const;
QString fileName() const override;
private:
@@ -410,9 +377,9 @@ QWinSettingsPrivate::QWinSettingsPrivate(QSettings::Scope scope, const QString &
deleteWriteHandleOnExit = false;
if (!organization.isEmpty()) {
- QString prefix = QLatin1String("Software\\") + organization;
- QString orgPrefix = prefix + QLatin1String("\\OrganizationDefaults");
- QString appPrefix = prefix + QLatin1Char('\\') + application;
+ QString prefix = "Software\\"_L1 + organization;
+ QString orgPrefix = prefix + "\\OrganizationDefaults"_L1;
+ QString appPrefix = prefix + u'\\' + application;
if (scope == QSettings::UserScope) {
if (!application.isEmpty())
@@ -437,34 +404,34 @@ QWinSettingsPrivate::QWinSettingsPrivate(QString rPath, REGSAM access)
{
deleteWriteHandleOnExit = false;
- if (rPath.startsWith(QLatin1Char('\\')))
+ if (rPath.startsWith(u'\\'))
rPath.remove(0, 1);
int keyLength;
HKEY keyName;
- if (rPath.startsWith(QLatin1String("HKEY_CURRENT_USER"))) {
+ if (rPath.startsWith("HKEY_CURRENT_USER"_L1)) {
keyLength = 17;
keyName = HKEY_CURRENT_USER;
- } else if (rPath.startsWith(QLatin1String("HKCU"))) {
+ } else if (rPath.startsWith("HKCU"_L1)) {
keyLength = 4;
keyName = HKEY_CURRENT_USER;
- } else if (rPath.startsWith(QLatin1String("HKEY_LOCAL_MACHINE"))) {
+ } else if (rPath.startsWith("HKEY_LOCAL_MACHINE"_L1)) {
keyLength = 18;
keyName = HKEY_LOCAL_MACHINE;
- } else if (rPath.startsWith(QLatin1String("HKLM"))) {
+ } else if (rPath.startsWith("HKLM"_L1)) {
keyLength = 4;
keyName = HKEY_LOCAL_MACHINE;
- } else if (rPath.startsWith(QLatin1String("HKEY_CLASSES_ROOT"))) {
+ } else if (rPath.startsWith("HKEY_CLASSES_ROOT"_L1)) {
keyLength = 17;
keyName = HKEY_CLASSES_ROOT;
- } else if (rPath.startsWith(QLatin1String("HKCR"))) {
+ } else if (rPath.startsWith("HKCR"_L1)) {
keyLength = 4;
keyName = HKEY_CLASSES_ROOT;
- } else if (rPath.startsWith(QLatin1String("HKEY_USERS"))) {
+ } else if (rPath.startsWith("HKEY_USERS"_L1)) {
keyLength = 10;
keyName = HKEY_USERS;
- } else if (rPath.startsWith(QLatin1String("HKU"))) {
+ } else if (rPath.startsWith("HKU"_L1)) {
keyLength = 3;
keyName = HKEY_USERS;
} else {
@@ -473,11 +440,11 @@ QWinSettingsPrivate::QWinSettingsPrivate(QString rPath, REGSAM access)
if (rPath.length() == keyLength)
regList.append(RegistryKey(keyName, QString(), false, access));
- else if (rPath[keyLength] == QLatin1Char('\\'))
+ else if (rPath[keyLength] == u'\\')
regList.append(RegistryKey(keyName, rPath.mid(keyLength+1), false, access));
}
-bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const
+std::optional<QVariant> QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey) const
{
QString rSubkeyName = keyName(rSubKey);
QString rSubkeyPath = keyPath(rSubKey);
@@ -485,16 +452,16 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
// open a handle on the subkey
HKEY handle = openKey(parentHandle, KEY_READ, rSubkeyPath, access);
if (handle == 0)
- return false;
+ return std::nullopt;
+
+ const auto closeKey = qScopeGuard([handle] { RegCloseKey(handle); });
// get the size and type of the value
DWORD dataType;
DWORD dataSize;
LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, &dataType, 0, &dataSize);
- if (res != ERROR_SUCCESS) {
- RegCloseKey(handle);
- return false;
- }
+ if (res != ERROR_SUCCESS)
+ return std::nullopt;
// workaround for rare cases where trailing '\0' are missing in registry
if (dataType == REG_SZ || dataType == REG_EXPAND_SZ)
@@ -506,10 +473,8 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
QByteArray data(dataSize, 0);
res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, 0,
reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- if (res != ERROR_SUCCESS) {
- RegCloseKey(handle);
- return false;
- }
+ if (res != ERROR_SUCCESS)
+ return std::nullopt;
switch (dataType) {
case REG_EXPAND_SZ:
@@ -518,9 +483,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
if (dataSize) {
s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()));
}
- if (value != 0)
- *value = stringToVariant(s);
- break;
+ return stringToVariant(s);
}
case REG_MULTI_SZ: {
@@ -536,9 +499,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
l.append(s);
}
}
- if (value != 0)
- *value = stringListToVariantList(l);
- break;
+ return stringListToVariantList(l);
}
case REG_NONE:
@@ -547,9 +508,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
if (dataSize) {
s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()), data.size() / 2);
}
- if (value != 0)
- *value = stringToVariant(s);
- break;
+ return stringToVariant(s);
}
case REG_DWORD_BIG_ENDIAN:
@@ -557,29 +516,22 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
Q_ASSERT(data.size() == sizeof(int));
int i;
memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(int));
- if (value != 0)
- *value = i;
- break;
+ return i;
}
case REG_QWORD: {
Q_ASSERT(data.size() == sizeof(qint64));
qint64 i;
memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(qint64));
- if (value != 0)
- *value = i;
- break;
+ return i;
}
default:
qWarning("QSettings: Unknown data %d type in Windows registry", static_cast<int>(dataType));
- if (value != 0)
- *value = QVariant();
break;
}
- RegCloseKey(handle);
- return true;
+ return std::nullopt;
}
HKEY QWinSettingsPrivate::writeHandle() const
@@ -670,9 +622,9 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
QByteArray regValueBuff;
// Determine the type
- switch (value.type()) {
- case QVariant::List:
- case QVariant::StringList: {
+ switch (value.typeId()) {
+ case QMetaType::QVariantList:
+ case QMetaType::QStringList: {
// If none of the elements contains '\0', we can use REG_MULTI_SZ, the
// native registry string list type. Otherwise we use REG_BINARY.
type = REG_MULTI_SZ;
@@ -686,8 +638,8 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
}
if (type == REG_BINARY) {
- QString s = variantToString(value);
- regValueBuff = QByteArray(reinterpret_cast<const char*>(s.utf16()), s.length() * 2);
+ const QString s = variantToString(value);
+ regValueBuff = QByteArray(reinterpret_cast<const char *>(s.data()), s.length() * 2);
} else {
QStringList::const_iterator it = l.constBegin();
for (; it != l.constEnd(); ++it) {
@@ -700,23 +652,23 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
break;
}
- case QVariant::Int:
- case QVariant::UInt: {
+ case QMetaType::Int:
+ case QMetaType::UInt: {
type = REG_DWORD;
qint32 i = value.toInt();
regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint32));
break;
}
- case QVariant::LongLong:
- case QVariant::ULongLong: {
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong: {
type = REG_QWORD;
qint64 i = value.toLongLong();
regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint64));
break;
}
- case QVariant::ByteArray:
+ case QMetaType::QByteArray:
Q_FALLTHROUGH();
default: {
@@ -749,20 +701,21 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
RegCloseKey(handle);
}
-bool QWinSettingsPrivate::get(const QString &uKey, QVariant *value) const
+std::optional<QVariant> QWinSettingsPrivate::get(const QString &uKey) const
{
QString rKey = escapedKey(uKey);
for (const RegistryKey &r : regList) {
HKEY handle = r.handle();
- if (handle != 0 && readKey(handle, rKey, value))
- return true;
-
+ if (handle != 0) {
+ if (auto result = readKey(handle, rKey))
+ return result;
+ }
if (!fallbacks)
- return false;
+ return std::nullopt;
}
- return false;
+ return std::nullopt;
}
QStringList QWinSettingsPrivate::children(const QString &uKey, ChildSpec spec) const
@@ -772,15 +725,21 @@ QStringList QWinSettingsPrivate::children(const QString &uKey, ChildSpec spec) c
for (const RegistryKey &r : regList) {
HKEY parent_handle = r.handle();
- if (parent_handle == 0)
- continue;
+ if (parent_handle == 0) {
+ if (fallbacks)
+ continue;
+ break;
+ }
HKEY handle = openKey(parent_handle, KEY_READ, rKey, access);
- if (handle == 0)
- continue;
+ if (handle == 0) {
+ if (fallbacks)
+ continue;
+ break;
+ }
if (spec == AllKeys) {
NameSet keys;
- allKeys(handle, QLatin1String(""), &keys, access);
+ allKeys(handle, ""_L1, &keys, access);
mergeKeySets(&result, keys);
} else { // ChildGroups or ChildKeys
QStringList names = childKeysOrGroups(handle, spec);
@@ -820,9 +779,9 @@ QString QWinSettingsPrivate::fileName() const
const RegistryKey &key = regList.at(0);
QString result;
if (key.parentHandle() == HKEY_CURRENT_USER)
- result = QLatin1String("\\HKEY_CURRENT_USER\\");
+ result = "\\HKEY_CURRENT_USER\\"_L1;
else
- result = QLatin1String("\\HKEY_LOCAL_MACHINE\\");
+ result = "\\HKEY_LOCAL_MACHINE\\"_L1;
return result + regList.at(0).key();
}