39QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const wchar_t *subKey,
40 REGSAM permissions, REGSAM access,
44 if (RegOpenKeyExW(parentHandle, subKey,
45 0, permissions | access, &m_key) != ERROR_SUCCESS) {
50QWinRegistryKey::QWinRegistryKey(HKEY parentHandle,
const QString &subKey,
51 REGSAM permissions, REGSAM access, QObject *parent)
52 : QWinRegistryKey(parentHandle, nullTerminate(subKey), permissions, access, parent)
69QString QWinRegistryKey::name()
const
75 constexpr int kKeyNameInformation = 3;
76 struct KeyNameInformation { ULONG length = 0; WCHAR name[1] = {}; };
81 DWORD keyInformationSize = 0;
82 for (
int i = 0; i < 5; ++i) {
83 QByteArray buffer(keyInformationSize, 0u);
84 auto *keyNameInformation =
reinterpret_cast<KeyNameInformation *>(buffer.data());
85 switch (NtQueryKey(m_key, kKeyNameInformation, keyNameInformation,
86 keyInformationSize, &keyInformationSize)) {
87 case STATUS_BUFFER_TOO_SMALL:
88 case STATUS_BUFFER_OVERFLOW:
90 case STATUS_SUCCESS: {
91 return QString::fromWCharArray(keyNameInformation->name,
92 keyNameInformation->length /
sizeof(
wchar_t));
102QVariant QWinRegistryKey::value(
const wchar_t *subKey)
const
111 DWORD dataType = REG_NONE;
113 LONG ret = RegQueryValueExW(m_key, subKey,
nullptr, &dataType,
nullptr, &dataSize);
114 if (ret != ERROR_SUCCESS)
118 if (dataType == REG_SZ || dataType == REG_EXPAND_SZ)
120 else if (dataType == REG_MULTI_SZ)
124 QVarLengthArray<
unsigned char> data(dataSize);
125 std::fill(data.data(), data.data() + dataSize, 0u);
127 ret = RegQueryValueExW(m_key, subKey,
nullptr,
nullptr, data.data(), &dataSize);
128 if (ret != ERROR_SUCCESS)
133 case REG_EXPAND_SZ: {
135 return QString::fromWCharArray(
136 reinterpret_cast<
const wchar_t *>(data.constData()));
143 QStringList list = {};
146 const QString str = QString::fromWCharArray(
147 reinterpret_cast<
const wchar_t *>(data.constData()) + i);
148 i += str.length() + 1;
155 return QStringList();
161 return QString::fromWCharArray(
162 reinterpret_cast<
const wchar_t *>(data.constData()), data.size() / 2);
168 return qFromLittleEndian<quint32>(data.constData());
170 case REG_DWORD_BIG_ENDIAN:
171 return qFromBigEndian<quint32>(data.constData());
174 return qFromLittleEndian<quint64>(data.constData());
204void QWinRegistryKey::connectNotify(
const QMetaMethod &signal)
206 if (signal != QMetaMethod::fromSignal(&QWinRegistryKey::valueChanged))
212 if (m_keyChangedEvent)
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,
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();
240 return QObject::connectNotify(signal);