1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
25 #include <MUtils/Registry.h>
26 #include <MUtils/Exception.h>
29 #include <QStringList>
32 #define WIN32_LEAN_AND_MEAN
36 ///////////////////////////////////////////////////////////////////////////////
38 static HKEY registry_root(const int &rootKey)
42 case MUtils::Registry::root_classes: return HKEY_CLASSES_ROOT; break;
43 case MUtils::Registry::root_user: return HKEY_CURRENT_USER; break;
44 case MUtils::Registry::root_machine: return HKEY_LOCAL_MACHINE; break;
45 default: MUTILS_THROW("Unknown root reg value was specified!");
49 static DWORD registry_access(const int &access)
53 case MUtils::Registry::access_readonly: return KEY_READ; break;
54 case MUtils::Registry::access_writeonly: return KEY_WRITE; break;
55 case MUtils::Registry::access_readwrite: return KEY_READ | KEY_WRITE; break;
56 case MUtils::Registry::access_enumerate: return KEY_ENUMERATE_SUB_KEYS; break;
57 default: MUTILS_THROW("Unknown access value was specified!");
61 ///////////////////////////////////////////////////////////////////////////////
62 // RegistryKeyPrivate Key Class
63 ///////////////////////////////////////////////////////////////////////////////
71 class RegistryKeyPrivate
73 friend class MUtils::Registry::RegistryKey;
84 #define CHECK_STATUS(X) do \
88 MUTILS_THROW("Cannot read from or write to a key is not currently open!"); \
90 if(!(p->m_access & (X))) \
92 MUTILS_THROW("This operation is not support with current access rights!"); \
97 ///////////////////////////////////////////////////////////////////////////////
99 ///////////////////////////////////////////////////////////////////////////////
101 MUtils::Registry::RegistryKey::RegistryKey(const int &rootKey, const QString &keyName, const int &access)
103 p(new Internal::RegistryKeyPrivate())
106 p->m_access = registry_access(access);
109 p->m_isOpen = (RegCreateKeyEx(registry_root(rootKey), MUTILS_WCHR(keyName), 0, NULL, 0, p->m_access, NULL, &p->m_hKey, NULL) == ERROR_SUCCESS);
112 qWarning("Failed to open registry key!");
116 MUtils::Registry::RegistryKey::~RegistryKey(void)
120 CloseHandle(p->m_hKey);
127 inline bool MUtils::Registry::RegistryKey::isOpen(void)
132 bool MUtils::Registry::RegistryKey::value_write(const QString &valueName, const quint32 &value)
134 CHECK_STATUS(KEY_WRITE);
135 return (RegSetValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(quint32)) == ERROR_SUCCESS);
138 bool MUtils::Registry::RegistryKey::value_write(const QString &valueName, const QString &value)
140 CHECK_STATUS(KEY_WRITE);
141 return (RegSetValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, REG_SZ, reinterpret_cast<const BYTE*>(value.utf16()), (value.length() + 1) * sizeof(wchar_t)) == ERROR_SUCCESS);
144 bool MUtils::Registry::RegistryKey::value_read(const QString &valueName, quint32 &value) const
147 DWORD size = sizeof(quint32), type = -1;
148 CHECK_STATUS(KEY_READ);
149 return (RegQueryValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, &type, reinterpret_cast<BYTE*>(&value), &size) == ERROR_SUCCESS) && (type == REG_DWORD);
152 bool MUtils::Registry::RegistryKey::value_read(const QString &valueName, QString &value) const
155 wchar_t buffer[2048]; DWORD size = sizeof(wchar_t) * 2048, type = -1;
156 CHECK_STATUS(KEY_READ);
157 if((RegQueryValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, &type, reinterpret_cast<BYTE*>(&(buffer[0])), &size) == ERROR_SUCCESS) && ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
159 value = QString::fromUtf16(reinterpret_cast<const ushort*>(buffer));
165 bool MUtils::Registry::RegistryKey::enum_values(QStringList &list) const
167 wchar_t buffer[2048];
169 CHECK_STATUS(KEY_QUERY_VALUE);
170 for(DWORD i = 0; i < UINT_MAX; i++)
173 const DWORD ret = RegEnumValue(p->m_hKey, i, buffer, &size, NULL, NULL, NULL, NULL);
174 if(ret == ERROR_SUCCESS)
176 list << QString::fromUtf16(reinterpret_cast<const ushort*>(buffer));
179 return (ret == ERROR_NO_MORE_ITEMS);
184 bool MUtils::Registry::RegistryKey::enum_subkeys(QStringList &list) const
186 wchar_t buffer[2048];
188 CHECK_STATUS(KEY_ENUMERATE_SUB_KEYS);
189 for(DWORD i = 0; i < UINT_MAX; i++)
192 const DWORD ret = RegEnumKeyEx(p->m_hKey, i, buffer, &size, NULL, NULL, NULL, NULL);
193 if(ret == ERROR_SUCCESS)
195 list << QString::fromUtf16(reinterpret_cast<const ushort*>(buffer));
198 return (ret == ERROR_NO_MORE_ITEMS);
203 ///////////////////////////////////////////////////////////////////////////////
205 ///////////////////////////////////////////////////////////////////////////////
208 * Write registry value
210 bool MUtils::Registry::reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const quint32 &value)
212 bool success = false;
213 RegistryKey regKey(rootKey, keyName, access_readwrite);
216 success = regKey.value_write(valueName, value);
222 * Write registry value
224 bool MUtils::Registry::reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const QString &value)
226 bool success = false;
227 RegistryKey regKey(rootKey, keyName, access_readwrite);
230 success = regKey.value_write(valueName, value);
236 * Read registry value
238 bool MUtils::Registry::reg_value_read(const int &rootKey, const QString &keyName, const QString &valueName, quint32 &value)
240 bool success = false;
241 RegistryKey regKey(rootKey, keyName, access_readonly);
244 success = regKey.value_read(valueName, value);
254 * Read registry value
256 bool MUtils::Registry::reg_value_read(const int &rootKey, const QString &keyName, const QString &valueName, QString &value)
258 bool success = false;
259 RegistryKey regKey(rootKey, keyName, access_readonly);
262 success = regKey.value_read(valueName, value);
272 * Enumerate value names
274 bool MUtils::Registry::reg_enum_values(const int &rootKey, const QString &keyName, QStringList &values)
276 bool success = false;
277 RegistryKey regKey(rootKey, keyName, access_readonly);
280 success = regKey.enum_values(values);
290 * Enumerate subkey names
292 bool MUtils::Registry::reg_enum_subkeys(const int &rootKey, const QString &keyName, QStringList &subkeys)
294 bool success = false;
295 RegistryKey regKey(rootKey, keyName, access_enumerate);
298 success = regKey.enum_subkeys(subkeys);
308 * Delete registry key
310 bool MUtils::Registry::reg_key_delete(const int &rootKey, const QString &keyName)
312 return (SHDeleteKey(registry_root(rootKey), MUTILS_WCHR(keyName)) == ERROR_SUCCESS);