38QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const wchar_t *subKey,
39 REGSAM permissions, REGSAM access,
43 if (RegOpenKeyExW(parentHandle, subKey,
44 0, permissions | access, &m_key) != ERROR_SUCCESS) {
49QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const QString &subKey,
50 REGSAM permissions, REGSAM access, QObject *parent)
51 : QWinRegistryKey(parentHandle, nullTerminate(subKey), permissions, access, parent)
68QString QWinRegistryKey::name()
const
74 constexpr int kKeyNameInformation = 3;
75 struct KeyNameInformation { ULONG length = 0; WCHAR name[1] = {}; };
80 DWORD keyInformationSize = 0;
81 for (
int i = 0; i < 5; ++i) {
82 QByteArray buffer(keyInformationSize, 0u);
83 auto *keyNameInformation =
reinterpret_cast<KeyNameInformation *>(buffer.data());
84 switch (NtQueryKey(m_key, kKeyNameInformation, keyNameInformation,
85 keyInformationSize, &keyInformationSize)) {
86 case STATUS_BUFFER_TOO_SMALL:
87 case STATUS_BUFFER_OVERFLOW:
89 case STATUS_SUCCESS: {
90 return QString::fromWCharArray(keyNameInformation->name,
91 keyNameInformation->length /
sizeof(
wchar_t));
101QVariant QWinRegistryKey::value(
const wchar_t *subKey)
const
110 DWORD dataType = REG_NONE;
112 LONG ret = RegQueryValueExW(m_key, subKey,
nullptr, &dataType,
nullptr, &dataSize);
113 if (ret != ERROR_SUCCESS)
117 if (dataType == REG_SZ || dataType == REG_EXPAND_SZ)
119 else if (dataType == REG_MULTI_SZ)
123 QVarLengthArray<
unsigned char> data(dataSize);
124 std::fill(data.data(), data.data() + dataSize, 0u);
126 ret = RegQueryValueExW(m_key, subKey,
nullptr,
nullptr, data.data(), &dataSize);
127 if (ret != ERROR_SUCCESS)
132 case REG_EXPAND_SZ: {
134 return QString::fromWCharArray(
135 reinterpret_cast<
const wchar_t *>(data.constData()));
142 QStringList list = {};
145 const QString str = QString::fromWCharArray(
146 reinterpret_cast<
const wchar_t *>(data.constData()) + i);
147 i += str.length() + 1;
154 return QStringList();
160 return QString::fromWCharArray(
161 reinterpret_cast<
const wchar_t *>(data.constData()), data.size() / 2);
167 return qFromLittleEndian<quint32>(data.constData());
169 case REG_DWORD_BIG_ENDIAN:
170 return qFromBigEndian<quint32>(data.constData());
173 return qFromLittleEndian<quint64>(data.constData());
201void QWinRegistryKey::connectNotify(
const QMetaMethod &signal)
203 if (signal != QMetaMethod::fromSignal(&QWinRegistryKey::valueChanged))
209 if (m_keyChangedEvent)
212 m_keyChangedEvent.reset(CreateEvent(
nullptr,
false,
false,
nullptr));
213 auto *notifier =
new QWinEventNotifier(m_keyChangedEvent.get(),
this);
215 auto registerForNotification = [
this] {
216 constexpr auto changeFilter =
217 REG_NOTIFY_CHANGE_NAME
218 | REG_NOTIFY_CHANGE_ATTRIBUTES
219 | REG_NOTIFY_CHANGE_LAST_SET
220 | REG_NOTIFY_CHANGE_SECURITY;
222 if (
auto status = RegNotifyChangeKeyValue(m_key,
true, changeFilter,
223 m_keyChangedEvent.get(),
true); status != ERROR_SUCCESS) {
224 qWarning() <<
"Failed to register notification for registry key"
225 <<
this <<
"due to" << QSystemError::windowsString(status);
229 QObject::connect(notifier, &QWinEventNotifier::activated,
this,
230 [
this, registerForNotification] {
232 registerForNotification();
235 registerForNotification();
237 return QObject::connectNotify(signal);