Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsettings_win.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsettings.h"
5
6#include "qsettings_p.h"
7#include "qlist.h"
8#include "qmap.h"
9#include "qdebug.h"
10#include "qscopeguard.h"
11#include <qt_windows.h>
12
13// See "Accessing an Alternate Registry View" at:
14// http://msdn.microsoft.com/en-us/library/aa384129%28VS.85%29.aspx
15#ifndef KEY_WOW64_64KEY
16 // Access a 32-bit key from either a 32-bit or 64-bit application.
17# define KEY_WOW64_64KEY 0x0100
18#endif
19
20#ifndef KEY_WOW64_32KEY
21 // Access a 64-bit key from either a 32-bit or 64-bit application.
22# define KEY_WOW64_32KEY 0x0200
23#endif
24
26
27using namespace Qt::StringLiterals;
28
29/* Keys are stored in QStrings. If the variable name starts with 'u', this is a "user"
30 key, ie. "foo/bar/alpha/beta". If the variable name starts with 'r', this is a "registry"
31 key, ie. "\foo\bar\alpha\beta". */
32
33/*******************************************************************************
34** Some convenience functions
35*/
36
37/*
38 We don't use KEY_ALL_ACCESS because it gives more rights than what we
39 need. See task 199061.
40 */
41static const REGSAM registryPermissions = KEY_READ | KEY_WRITE;
42
43static QString keyPath(const QString &rKey)
44{
45 int idx = rKey.lastIndexOf(u'\\');
46 if (idx == -1)
47 return QString();
48 return rKey.left(idx + 1);
49}
50
51static QString keyName(const QString &rKey)
52{
53 int idx = rKey.lastIndexOf(u'\\');
54
56 if (idx == -1)
57 res = rKey;
58 else
59 res = rKey.mid(idx + 1);
60
61 if (res == "Default"_L1 || res == "."_L1)
62 res = ""_L1;
63
64 return res;
65}
66
68{
69 QChar *data = uKey.data();
70 int l = uKey.length();
71 for (int i = 0; i < l; ++i) {
72 auto &ucs = data[i].unicode();
73 if (ucs == '\\')
74 ucs = '/';
75 else if (ucs == '/')
76 ucs = '\\';
77 }
78 return uKey;
79}
80
82{
83 return escapedKey(rKey);
84}
85
86typedef QMap<QString, QString> NameSet;
87
88static void mergeKeySets(NameSet *dest, const NameSet &src)
89{
90 NameSet::const_iterator it = src.constBegin();
91 for (; it != src.constEnd(); ++it)
92 dest->insert(unescapedKey(it.key()), QString());
93}
94
95static void mergeKeySets(NameSet *dest, const QStringList &src)
96{
97 QStringList::const_iterator it = src.constBegin();
98 for (; it != src.constEnd(); ++it)
99 dest->insert(unescapedKey(*it), QString());
100}
101
102/*******************************************************************************
103** Wrappers for the insane windows registry API
104*/
105
106// ### Qt 6: Use new helpers from qwinregistry.cpp (once bootstrap builds are obsolete)
107
108// Open a key with the specified "perms".
109// "access" is to explicitly use the 32- or 64-bit branch.
110static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access = 0)
111{
112 HKEY resultHandle = 0;
113 LONG res = RegOpenKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()),
114 0, perms | access, &resultHandle);
115
116 if (res == ERROR_SUCCESS)
117 return resultHandle;
118
119 return 0;
120}
121
122// Open a key with the specified "perms", create it if it does not exist.
123// "access" is to explicitly use the 32- or 64-bit branch.
124static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access = 0)
125{
126 // try to open it
127 HKEY resultHandle = openKey(parentHandle, perms, rSubKey, access);
128 if (resultHandle != 0)
129 return resultHandle;
130
131 // try to create it
132 LONG res = RegCreateKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()), 0, 0,
133 REG_OPTION_NON_VOLATILE, perms | access, 0, &resultHandle, 0);
134
135 if (res == ERROR_SUCCESS)
136 return resultHandle;
137
138 //qErrnoWarning(int(res), "QSettings: Failed to create subkey \"%ls\"",
139 // qUtf16Printable(rSubKey));
140
141 return 0;
142}
143
144// Open or create a key in read-write mode if possible, otherwise read-only.
145// "access" is to explicitly use the 32- or 64-bit branch.
146static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *readOnly, REGSAM access = 0)
147{
148 // try to open or create it read/write
149 HKEY resultHandle = createOrOpenKey(parentHandle, registryPermissions, rSubKey, access);
150 if (resultHandle != 0) {
151 if (readOnly != 0)
152 *readOnly = false;
153 return resultHandle;
154 }
155
156 // try to open or create it read/only
157 resultHandle = createOrOpenKey(parentHandle, KEY_READ, rSubKey, access);
158 if (resultHandle != 0) {
159 if (readOnly != 0)
160 *readOnly = true;
161 return resultHandle;
162 }
163 return 0;
164}
165
167{
169 DWORD numKeys;
170 DWORD maxKeySize;
171 DWORD numSubgroups;
172 DWORD maxSubgroupSize;
173
174 // Find the number of keys and subgroups, as well as the max of their lengths.
175 LONG res = RegQueryInfoKey(parentHandle, 0, 0, 0, &numSubgroups, &maxSubgroupSize, 0,
176 &numKeys, &maxKeySize, 0, 0, 0);
177
178 if (res != ERROR_SUCCESS) {
179 qErrnoWarning(int(res), "QSettings: RegQueryInfoKey() failed");
180 return result;
181 }
182
183 ++maxSubgroupSize;
184 ++maxKeySize;
185
186 int n;
187 int m;
188 if (spec == QSettingsPrivate::ChildKeys) {
189 n = numKeys;
190 m = maxKeySize;
191 } else {
192 n = numSubgroups;
193 m = maxSubgroupSize;
194 }
195
196 /* The size does not include the terminating null character. */
197 ++m;
198
199 // Get the list
200 QByteArray buff(m * sizeof(wchar_t), 0);
201 for (int i = 0; i < n; ++i) {
203 DWORD l = DWORD(buff.size()) / DWORD(sizeof(wchar_t));
204 if (spec == QSettingsPrivate::ChildKeys) {
205 res = RegEnumValue(parentHandle, i, reinterpret_cast<wchar_t *>(buff.data()), &l, 0, 0, 0, 0);
206 } else {
207 res = RegEnumKeyEx(parentHandle, i, reinterpret_cast<wchar_t *>(buff.data()), &l, 0, 0, 0, 0);
208 }
209 if (res == ERROR_SUCCESS)
210 item = QString::fromWCharArray((const wchar_t *)buff.constData(), l);
211
212 if (res != ERROR_SUCCESS) {
213 qErrnoWarning(int(res), "QSettings: RegEnumValue failed");
214 continue;
215 }
216 if (item.isEmpty())
217 item = "."_L1;
218 result.append(item);
219 }
220 return result;
221}
222
223static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result, REGSAM access = 0)
224{
225 HKEY handle = openKey(parentHandle, KEY_READ, rSubKey, access);
226 if (handle == 0)
227 return;
228
231 RegCloseKey(handle);
232
233 for (int i = 0; i < childKeys.size(); ++i) {
234 QString s = rSubKey;
235 if (!s.isEmpty())
236 s += u'\\';
237 s += childKeys.at(i);
238 result->insert(s, QString());
239 }
240
241 for (int i = 0; i < childGroups.size(); ++i) {
242 QString s = rSubKey;
243 if (!s.isEmpty())
244 s += u'\\';
245 s += childGroups.at(i);
246 allKeys(parentHandle, s, result, access);
247 }
248}
249
250static void deleteChildGroups(HKEY parentHandle, REGSAM access = 0)
251{
253
254 for (int i = 0; i < childGroups.size(); ++i) {
255 QString group = childGroups.at(i);
256
257 // delete subgroups in group
258 HKEY childGroupHandle = openKey(parentHandle, registryPermissions, group, access);
259 if (childGroupHandle == 0)
260 continue;
261 deleteChildGroups(childGroupHandle, access);
262 RegCloseKey(childGroupHandle);
263
264 // delete group itself
265 LONG res = RegDeleteKey(parentHandle, reinterpret_cast<const wchar_t *>(group.utf16()));
266 if (res != ERROR_SUCCESS) {
267 qErrnoWarning(int(res), "QSettings: RegDeleteKey failed on subkey \"%ls\"",
269 return;
270 }
271 }
272}
273
274/*******************************************************************************
275** class RegistryKey
276*/
277
279{
280public:
281 RegistryKey(HKEY parent_handle = 0, const QString &key = QString(), bool read_only = true, REGSAM access = 0);
282 QString key() const;
283 HKEY handle() const;
284 HKEY parentHandle() const;
285 bool readOnly() const;
286 void close();
287private:
288 HKEY m_parent_handle;
289 mutable HKEY m_handle;
290 QString m_key;
291 mutable bool m_read_only;
292 REGSAM m_access;
293};
294
295RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only, REGSAM access)
296 : m_parent_handle(parent_handle),
297 m_handle(0),
298 m_key(key),
299 m_read_only(read_only),
300 m_access(access)
301{
302}
303
305{
306 return m_key;
307}
308
310{
311 if (m_handle != 0)
312 return m_handle;
313
314 if (m_read_only)
315 m_handle = openKey(m_parent_handle, KEY_READ, m_key, m_access);
316 else
317 m_handle = createOrOpenKey(m_parent_handle, m_key, &m_read_only, m_access);
318
319 return m_handle;
320}
321
323{
324 return m_parent_handle;
325}
326
328{
329 return m_read_only;
330}
331
333{
334 if (m_handle != 0)
335 RegCloseKey(m_handle);
336 m_handle = 0;
337}
338
339typedef QList<RegistryKey> RegistryKeyList;
340
341/*******************************************************************************
342** class QWinSettingsPrivate
343*/
344
346{
347 Q_DISABLE_COPY(QWinSettingsPrivate)
348public:
350 const QString &application, REGSAM access = 0);
351 QWinSettingsPrivate(QString rKey, REGSAM access = 0);
352 ~QWinSettingsPrivate() override;
353
354 void remove(const QString &uKey) override;
355 void set(const QString &uKey, const QVariant &value) override;
356 std::optional<QVariant> get(const QString &uKey) const override;
357 QStringList children(const QString &uKey, ChildSpec spec) const override;
358 void clear() override;
359 void sync() override;
360 void flush() override;
361 bool isWritable() const override;
362 HKEY writeHandle() const;
363 std::optional<QVariant> readKey(HKEY parentHandle, const QString &rSubKey) const;
364 QString fileName() const override;
365
366private:
367 RegistryKeyList regList; // list of registry locations to search for keys
368 bool deleteWriteHandleOnExit;
369 REGSAM access;
370};
371
373 const QString &application, REGSAM access)
374 : QSettingsPrivate(QSettings::NativeFormat, scope, organization, application),
376{
377 deleteWriteHandleOnExit = false;
378
379 if (!organization.isEmpty()) {
380 QString prefix = "Software\\"_L1 + organization;
381 QString orgPrefix = prefix + "\\OrganizationDefaults"_L1;
382 QString appPrefix = prefix + u'\\' + application;
383
385 if (!application.isEmpty())
386 regList.append(RegistryKey(HKEY_CURRENT_USER, appPrefix, !regList.isEmpty(), access));
387
388 regList.append(RegistryKey(HKEY_CURRENT_USER, orgPrefix, !regList.isEmpty(), access));
389 }
390
391 if (!application.isEmpty())
392 regList.append(RegistryKey(HKEY_LOCAL_MACHINE, appPrefix, !regList.isEmpty(), access));
393
394 regList.append(RegistryKey(HKEY_LOCAL_MACHINE, orgPrefix, !regList.isEmpty(), access));
395 }
396
397 if (regList.isEmpty())
399}
400
402 : QSettingsPrivate(QSettings::NativeFormat),
404{
405 deleteWriteHandleOnExit = false;
406
407 if (rPath.startsWith(u'\\'))
408 rPath.remove(0, 1);
409
410 int keyLength;
411 HKEY keyName;
412
413 if (rPath.startsWith("HKEY_CURRENT_USER"_L1)) {
414 keyLength = 17;
415 keyName = HKEY_CURRENT_USER;
416 } else if (rPath.startsWith("HKCU"_L1)) {
417 keyLength = 4;
418 keyName = HKEY_CURRENT_USER;
419 } else if (rPath.startsWith("HKEY_LOCAL_MACHINE"_L1)) {
420 keyLength = 18;
421 keyName = HKEY_LOCAL_MACHINE;
422 } else if (rPath.startsWith("HKLM"_L1)) {
423 keyLength = 4;
424 keyName = HKEY_LOCAL_MACHINE;
425 } else if (rPath.startsWith("HKEY_CLASSES_ROOT"_L1)) {
426 keyLength = 17;
427 keyName = HKEY_CLASSES_ROOT;
428 } else if (rPath.startsWith("HKCR"_L1)) {
429 keyLength = 4;
430 keyName = HKEY_CLASSES_ROOT;
431 } else if (rPath.startsWith("HKEY_USERS"_L1)) {
432 keyLength = 10;
433 keyName = HKEY_USERS;
434 } else if (rPath.startsWith("HKU"_L1)) {
435 keyLength = 3;
436 keyName = HKEY_USERS;
437 } else {
438 return;
439 }
440
441 if (rPath.length() == keyLength)
442 regList.append(RegistryKey(keyName, QString(), false, access));
443 else if (rPath[keyLength] == u'\\')
444 regList.append(RegistryKey(keyName, rPath.mid(keyLength+1), false, access));
445}
446
447std::optional<QVariant> QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey) const
448{
449 QString rSubkeyName = keyName(rSubKey);
450 QString rSubkeyPath = keyPath(rSubKey);
451
452 // open a handle on the subkey
453 HKEY handle = openKey(parentHandle, KEY_READ, rSubkeyPath, access);
454 if (handle == 0)
455 return std::nullopt;
456
457 const auto closeKey = qScopeGuard([handle] { RegCloseKey(handle); });
458
459 // get the size and type of the value
460 DWORD dataType;
461 DWORD dataSize;
462 LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, &dataType, 0, &dataSize);
463 if (res != ERROR_SUCCESS)
464 return std::nullopt;
465
466 // workaround for rare cases where trailing '\0' are missing in registry
467 if (dataType == REG_SZ || dataType == REG_EXPAND_SZ)
468 dataSize += 2;
469 else if (dataType == REG_MULTI_SZ)
470 dataSize += 4;
471
472 // get the value
474 res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubkeyName.utf16()), 0, 0,
475 reinterpret_cast<unsigned char*>(data.data()), &dataSize);
476 if (res != ERROR_SUCCESS)
477 return std::nullopt;
478
479 switch (dataType) {
480 case REG_EXPAND_SZ:
481 case REG_SZ: {
482 QString s;
483 if (dataSize) {
484 s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()));
485 }
486 return stringToVariant(s);
487 }
488
489 case REG_MULTI_SZ: {
490 QStringList l;
491 if (dataSize) {
492 int i = 0;
493 for (;;) {
494 QString s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()) + i);
495 i += s.length() + 1;
496
497 if (s.isEmpty())
498 break;
499 l.append(s);
500 }
501 }
502 return stringListToVariantList(l);
503 }
504
505 case REG_NONE:
506 case REG_BINARY: {
507 QString s;
508 if (dataSize) {
509 s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()), data.size() / 2);
510 }
511 return stringToVariant(s);
512 }
513
514 case REG_DWORD_BIG_ENDIAN:
515 case REG_DWORD: {
516 Q_ASSERT(data.size() == sizeof(int));
517 int i;
518 memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(int));
519 return i;
520 }
521
522 case REG_QWORD: {
523 Q_ASSERT(data.size() == sizeof(qint64));
524 qint64 i;
525 memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(qint64));
526 return i;
527 }
528
529 default:
530 qWarning("QSettings: Unknown data %d type in Windows registry", static_cast<int>(dataType));
531 break;
532 }
533
534 return std::nullopt;
535}
536
538{
539 if (regList.isEmpty())
540 return 0;
541 const RegistryKey &key = regList.at(0);
542 if (key.handle() == 0 || key.readOnly())
543 return 0;
544 return key.handle();
545}
546
548{
549 if (deleteWriteHandleOnExit && writeHandle() != 0) {
550 QString emptyKey;
551 DWORD res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(emptyKey.utf16()));
552 if (res != ERROR_SUCCESS) {
553 qErrnoWarning(int(res), "QSettings: Failed to delete key \"%ls\"",
554 qUtf16Printable(regList.constFirst().key()));
555 }
556 }
557
558 for (int i = 0; i < regList.size(); ++i)
559 regList[i].close();
560}
561
563{
564 if (writeHandle() == 0) {
566 return;
567 }
568
569 QString rKey = escapedKey(uKey);
570
571 // try to delete value bar in key foo
572 LONG res;
574 if (handle != 0) {
575 res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()));
576 RegCloseKey(handle);
577 }
578
579 // try to delete key foo/bar and all subkeys
581 if (handle != 0) {
583
584 if (rKey.isEmpty()) {
586
587 for (const QString &group : childKeys) {
588 LONG res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(group.utf16()));
589 if (res != ERROR_SUCCESS) {
590 qErrnoWarning(int(res), "QSettings: RegDeleteValue failed on subkey \"%ls\"",
592 }
593 }
594 } else {
595 res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(rKey.utf16()));
596
597 if (res != ERROR_SUCCESS) {
598 qErrnoWarning(int(res), "QSettings: RegDeleteKey failed on key \"%ls\"",
599 qUtf16Printable(rKey));
600 }
601 }
602 RegCloseKey(handle);
603 }
604}
605
607{
608 if (writeHandle() == 0) {
610 return;
611 }
612
613 QString rKey = escapedKey(uKey);
614
616 if (handle == 0) {
618 return;
619 }
620
621 DWORD type;
622 QByteArray regValueBuff;
623
624 // Determine the type
625 switch (value.typeId()) {
626 case QMetaType::QVariantList:
627 case QMetaType::QStringList: {
628 // If none of the elements contains '\0', we can use REG_MULTI_SZ, the
629 // native registry string list type. Otherwise we use REG_BINARY.
630 type = REG_MULTI_SZ;
632 QStringList::const_iterator it = l.constBegin();
633 for (; it != l.constEnd(); ++it) {
634 if ((*it).length() == 0 || it->contains(QChar::Null)) {
635 type = REG_BINARY;
636 break;
637 }
638 }
639
640 if (type == REG_BINARY) {
642 regValueBuff = QByteArray(reinterpret_cast<const char *>(s.data()), s.length() * 2);
643 } else {
644 QStringList::const_iterator it = l.constBegin();
645 for (; it != l.constEnd(); ++it) {
646 const QString &s = *it;
647 regValueBuff += QByteArray(reinterpret_cast<const char*>(s.utf16()), (s.length() + 1) * 2);
648 }
649 regValueBuff.append((char)0);
650 regValueBuff.append((char)0);
651 }
652 break;
653 }
654
655 case QMetaType::Int:
656 case QMetaType::UInt: {
657 type = REG_DWORD;
658 qint32 i = value.toInt();
659 regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint32));
660 break;
661 }
662
663 case QMetaType::LongLong:
664 case QMetaType::ULongLong: {
665 type = REG_QWORD;
666 qint64 i = value.toLongLong();
667 regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint64));
668 break;
669 }
670
671 case QMetaType::QByteArray:
673
674 default: {
675 // If the string does not contain '\0', we can use REG_SZ, the native registry
676 // string type. Otherwise we use REG_BINARY.
678 type = s.contains(QChar::Null) ? REG_BINARY : REG_SZ;
679 int length = s.length();
680 if (type == REG_SZ)
681 ++length;
682 regValueBuff = QByteArray(reinterpret_cast<const char *>(s.utf16()),
683 int(sizeof(wchar_t)) * length);
684 break;
685 }
686 }
687
688 // set the value
689 LONG res = RegSetValueEx(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()), 0, type,
690 reinterpret_cast<const unsigned char*>(regValueBuff.constData()),
691 regValueBuff.size());
692
693 if (res == ERROR_SUCCESS) {
694 deleteWriteHandleOnExit = false;
695 } else {
696 qErrnoWarning(int(res), "QSettings: failed to set subkey \"%ls\"",
697 qUtf16Printable(rKey));
699 }
700
701 RegCloseKey(handle);
702}
703
704std::optional<QVariant> QWinSettingsPrivate::get(const QString &uKey) const
705{
706 QString rKey = escapedKey(uKey);
707
708 for (const RegistryKey &r : regList) {
709 HKEY handle = r.handle();
710 if (handle != 0) {
711 if (auto result = readKey(handle, rKey))
712 return result;
713 }
714 if (!fallbacks)
715 return std::nullopt;
716 }
717
718 return std::nullopt;
719}
720
722{
724 QString rKey = escapedKey(uKey);
725
726 for (const RegistryKey &r : regList) {
727 HKEY parent_handle = r.handle();
728 if (parent_handle == 0) {
729 if (fallbacks)
730 continue;
731 break;
732 }
733 HKEY handle = openKey(parent_handle, KEY_READ, rKey, access);
734 if (handle == 0) {
735 if (fallbacks)
736 continue;
737 break;
738 }
739
740 if (spec == AllKeys) {
742 allKeys(handle, ""_L1, &keys, access);
744 } else { // ChildGroups or ChildKeys
747 }
748
749 RegCloseKey(handle);
750
751 if (!fallbacks)
752 return result.keys();
753 }
754
755 return result.keys();
756}
757
759{
760 remove(QString());
761 deleteWriteHandleOnExit = true;
762}
763
765{
766 RegFlushKey(writeHandle());
767}
768
770{
771 // Windows does this for us.
772}
773
775{
776 if (regList.isEmpty())
777 return QString();
778
779 const RegistryKey &key = regList.at(0);
781 if (key.parentHandle() == HKEY_CURRENT_USER)
782 result = "\\HKEY_CURRENT_USER\\"_L1;
783 else
784 result = "\\HKEY_LOCAL_MACHINE\\"_L1;
785
786 return result + regList.at(0).key();
787}
788
790{
791 return writeHandle() != 0;
792}
793
795 const QString &organization, const QString &application)
796{
797 switch (format) {
799 return new QWinSettingsPrivate(scope, organization, application);
800 case QSettings::Registry32Format:
801 return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_32KEY);
802 case QSettings::Registry64Format:
803 return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_64KEY);
804 default:
805 break;
806 }
807 return new QConfFileSettingsPrivate(format, scope, organization, application);
808}
809
811{
812 switch (format) {
814 return new QWinSettingsPrivate(fileName);
815 case QSettings::Registry32Format:
817 case QSettings::Registry64Format:
819 default:
820 break;
821 }
823}
824
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
const T & constFirst() const noexcept
Definition qlist.h:647
void append(parameter_type t)
Definition qlist.h:458
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
QObjectList children
Definition qobject.h:74
const_iterator constBegin() const noexcept
Definition qset.h:139
const_iterator constEnd() const noexcept
Definition qset.h:143
bool contains(const T &value) const
Definition qset.h:71
virtual QString fileName() const =0
static QStringList variantListToStringList(const QVariantList &l)
static QSettingsPrivate * create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application)
void setStatus(QSettings::Status status) const
static QVariant stringListToVariantList(const QStringList &l)
static QVariant stringToVariant(const QString &s)
static QString variantToString(const QVariant &v)
QSettings::Scope scope
\inmodule QtCore
Definition qsettings.h:30
Format
This enum type specifies the storage format used by QSettings.
Definition qsettings.h:48
@ NativeFormat
Definition qsettings.h:49
Scope
This enum specifies whether settings are user-specific or shared by all users of the same system.
Definition qsettings.h:84
@ AccessError
Definition qsettings.h:41
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1309
\inmodule QtCore
Definition qvariant.h:65
void sync() override
~QWinSettingsPrivate() override
void clear() override
bool isWritable() const override
void set(const QString &uKey, const QVariant &value) override
void remove(const QString &uKey) override
QWinSettingsPrivate(QSettings::Scope scope, const QString &organization, const QString &application, REGSAM access=0)
std::optional< QVariant > get(const QString &uKey) const override
std::optional< QVariant > readKey(HKEY parentHandle, const QString &rSubKey) const
void flush() override
QString fileName() const override
HKEY handle() const
bool readOnly() const
HKEY parentHandle() const
RegistryKey(HKEY parent_handle=0, const QString &key=QString(), bool read_only=true, REGSAM access=0)
QString key() const
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
#define Q_FALLTHROUGH()
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
GLuint64 GLenum void * handle
const GLfloat * m
GLuint64 key
GLboolean r
[2]
GLenum GLsizei dataSize
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLenum type
GLboolean GLuint group
GLenum access
GLfloat n
GLint GLsizei GLsizei GLenum format
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
GLuint GLuint * names
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
static void deleteChildGroups(HKEY parentHandle, REGSAM access=0)
QMap< QString, QString > NameSet
static QString escapedKey(QString uKey)
static void mergeKeySets(NameSet *dest, const NameSet &src)
static QString unescapedKey(QString rKey)
static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result, REGSAM access=0)
static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access=0)
static QString keyPath(const QString &rKey)
static QString keyName(const QString &rKey)
#define KEY_WOW64_32KEY
static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildSpec spec)
static const REGSAM registryPermissions
static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access=0)
#define KEY_WOW64_64KEY
QList< RegistryKey > RegistryKeyList
#define qUtf16Printable(string)
Definition qstring.h:1543
int qint32
Definition qtypes.h:49
long long qint64
Definition qtypes.h:60
QFuture< QSet< QChar > > set
[10]
QStringList keys
QGraphicsItem * item