34QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const wchar_t *subKey,
35 REGSAM permissions, REGSAM access)
37 if (RegOpenKeyExW(parentHandle, subKey,
38 0, permissions | access, &m_key) != ERROR_SUCCESS) {
43QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const QString &subKey,
44 REGSAM permissions, REGSAM access)
45 : QWinRegistryKey(parentHandle, nullTerminate(subKey), permissions, access)
62QString QWinRegistryKey::name()
const
68 constexpr int kKeyNameInformation = 3;
69 struct KeyNameInformation { ULONG length = 0; WCHAR name[1] = {}; };
74 DWORD keyInformationSize = 0;
75 for (
int i = 0; i < 5; ++i) {
76 QByteArray buffer(keyInformationSize, 0u);
77 auto *keyNameInformation =
reinterpret_cast<KeyNameInformation *>(buffer.data());
78 switch (NtQueryKey(m_key, kKeyNameInformation, keyNameInformation,
79 keyInformationSize, &keyInformationSize)) {
80 case STATUS_BUFFER_TOO_SMALL:
81 case STATUS_BUFFER_OVERFLOW:
83 case STATUS_SUCCESS: {
84 return QString::fromWCharArray(keyNameInformation->name,
85 keyNameInformation->length /
sizeof(
wchar_t));
95QVariant QWinRegistryKey::value(
const wchar_t *subKey)
const
104 DWORD dataType = REG_NONE;
106 LONG ret = RegQueryValueExW(m_key, subKey,
nullptr, &dataType,
nullptr, &dataSize);
107 if (ret != ERROR_SUCCESS)
111 if (dataType == REG_SZ || dataType == REG_EXPAND_SZ)
113 else if (dataType == REG_MULTI_SZ)
117 QVarLengthArray<
unsigned char> data(dataSize);
118 std::fill(data.data(), data.data() + dataSize, 0u);
120 ret = RegQueryValueExW(m_key, subKey,
nullptr,
nullptr, data.data(), &dataSize);
121 if (ret != ERROR_SUCCESS)
126 case REG_EXPAND_SZ: {
128 return QString::fromWCharArray(
129 reinterpret_cast<
const wchar_t *>(data.constData()));
136 QStringList list = {};
139 const QString str = QString::fromWCharArray(
140 reinterpret_cast<
const wchar_t *>(data.constData()) + i);
141 i += str.length() + 1;
148 return QStringList();
154 return QString::fromWCharArray(
155 reinterpret_cast<
const wchar_t *>(data.constData()), data.size() / 2);
161 return qFromLittleEndian<quint32>(data.constData());
163 case REG_DWORD_BIG_ENDIAN:
164 return qFromBigEndian<quint32>(data.constData());
167 return qFromLittleEndian<quint64>(data.constData());
209QWinRegistryNotifier::QWinRegistryNotifier(QWinRegistryKey &&key, QObject *parent)
210 : QObject(parent), m_key(std::move(key))
212 if (!m_key.isValid())
215 m_keyChangedEvent.reset(CreateEvent(
nullptr,
false,
false,
nullptr));
216 auto *notifier =
new QWinEventNotifier(m_keyChangedEvent.get(),
this);
218 auto registerForNotification = [
this] {
219 constexpr auto changeFilter =
220 REG_NOTIFY_CHANGE_NAME
221 | REG_NOTIFY_CHANGE_ATTRIBUTES
222 | REG_NOTIFY_CHANGE_LAST_SET
223 | REG_NOTIFY_CHANGE_SECURITY;
225 if (
auto status = RegNotifyChangeKeyValue(m_key.handle(),
true, changeFilter,
226 m_keyChangedEvent.get(),
true); status != ERROR_SUCCESS) {
227 qWarning() <<
"Failed to register notification for registry key"
228 <<
this <<
"due to" << QSystemError::windowsString(status);
232 QObject::connect(notifier, &QWinEventNotifier::activated,
this,
233 [
this, registerForNotification] {
235 registerForNotification();
238 registerForNotification();