From 636e61c4842671ae20a320cf2f53d9eddd353d0e Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sat, 2 May 2015 18:52:35 +0200 Subject: [PATCH] Added the Registry class + added ShellNotification function. --- MUtilities_VS2013.vcxproj | 3 +- MUtilities_VS2013.vcxproj.filters | 9 +- include/MUtils/OSSupport.h | 3 + include/MUtils/Registry.h | 76 ++++++++++++++ src/OSSupport_Win32.cpp | 12 ++- src/Registry_Win32.cpp | 214 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 include/MUtils/Registry.h create mode 100644 src/Registry_Win32.cpp diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj index 4098ef8..edd0cde 100644 --- a/MUtilities_VS2013.vcxproj +++ b/MUtilities_VS2013.vcxproj @@ -31,6 +31,7 @@ + @@ -50,6 +51,7 @@ + @@ -60,7 +62,6 @@ - "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" MOC "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp" diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters index 91b0a68..1bcd39b 100644 --- a/MUtilities_VS2013.vcxproj.filters +++ b/MUtilities_VS2013.vcxproj.filters @@ -96,6 +96,9 @@ Source Files\3rd Party + + Source Files + @@ -131,9 +134,6 @@ Public Headers - - Header Files - Header Files\3rd Party @@ -167,6 +167,9 @@ Header Files\3rd Party + + Public Headers + diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h index 5845c15..359af2b 100644 --- a/include/MUtils/OSSupport.h +++ b/include/MUtils/OSSupport.h @@ -167,6 +167,9 @@ namespace MUtils //Keyboard support MUTILS_API bool check_key_state_esc(void); + //Shell notification + MUTILS_API void shell_change_notification(void); + //WOW64 redirection MUTILS_API bool wow64fsredir_disable(void *oldValue); MUTILS_API bool wow64fsredir_revert (void *oldValue); diff --git a/include/MUtils/Registry.h b/include/MUtils/Registry.h new file mode 100644 index 0000000..cf1d5ee --- /dev/null +++ b/include/MUtils/Registry.h @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////////// +// MuldeR's Utilities for Qt +// Copyright (C) 2004-2015 LoRd_MuldeR +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// http://www.gnu.org/licenses/lgpl-2.1.txt +////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//MUtils +#include + +/////////////////////////////////////////////////////////////////////////////// + +namespace MUtils +{ + namespace Registry + { + //Regsitry root + typedef enum + { + root_classes = 0, + root_user = 1, + root_machine = 2, + } + reg_root_t; + + //Forward declaration + namespace Internal + { + class RegistryKeyPrivate; + } + + //Registry key class + class MUTILS_API RegistryKey + { + public: + RegistryKey(const int &rootKey, const QString &keyName, const bool &readOnly); + ~RegistryKey(void); + + inline bool isOpen(void); + + bool value_write(const QString &valueName, const quint32 &value); + bool value_write(const QString &valueName, const QString &value); + + bool value_read(const QString &valueName, quint32 &value) const; + bool value_read(const QString &valueName, QString &value) const; + + private: + Internal::RegistryKeyPrivate *const p; + }; + + //Regsitry functions + MUTILS_API bool reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const quint32 &value); + MUTILS_API bool reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const QString &value); + MUTILS_API bool reg_value_read (const int &rootKey, const QString &keyName, const QString &valueName, quint32 &value); + MUTILS_API bool reg_value_read (const int &rootKey, const QString &keyName, const QString &valueName, QString &value); + MUTILS_API bool reg_key_delete (const int &rootKey, const QString &keyName); + } +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index c8a07aa..9046edb 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -22,12 +22,12 @@ //Win32 API #define WIN32_LEAN_AND_MEAN 1 #include -#include #include #include #include #include #include +#include //Internal #include @@ -440,7 +440,6 @@ static QReadWriteLock g_known_folders_lock; const QString &MUtils::OS::known_folder(known_folder_t folder_id) { - static const int CSIDL_FLAG_CREATE = 0x8000; typedef enum { KF_FLAG_CREATE = 0x00008000 } kf_flags_t; struct @@ -1073,6 +1072,15 @@ bool MUtils::OS::check_key_state_esc(void) } /////////////////////////////////////////////////////////////////////////////// +// SHELL CHANGE NOTIFICATION +/////////////////////////////////////////////////////////////////////////////// + +void MUtils::OS::shell_change_notification(void) +{ + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); +} + +/////////////////////////////////////////////////////////////////////////////// // WOW64 REDIRECTION /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Registry_Win32.cpp b/src/Registry_Win32.cpp new file mode 100644 index 0000000..b1b67d4 --- /dev/null +++ b/src/Registry_Win32.cpp @@ -0,0 +1,214 @@ +/////////////////////////////////////////////////////////////////////////////// +// MuldeR's Utilities for Qt +// Copyright (C) 2004-2015 LoRd_MuldeR +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// http://www.gnu.org/licenses/lgpl-2.1.txt +////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//MUtils +#include +#include + +//Win32 +#define WIN32_LEAN_AND_MEAN +#include +#include + +/////////////////////////////////////////////////////////////////////////////// + +static HKEY registry_root(const int &rootKey) +{ + switch(rootKey) + { + case MUtils::Registry::root_classes: return HKEY_CLASSES_ROOT; break; + case MUtils::Registry::root_user: return HKEY_CURRENT_USER; break; + case MUtils::Registry::root_machine: return HKEY_LOCAL_MACHINE; break; + default: MUTILS_THROW("Unknown root reg value was specified!"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// RegistryKeyPrivate Key Class +/////////////////////////////////////////////////////////////////////////////// + +namespace MUtils +{ + namespace Registry + { + namespace Internal + { + class RegistryKeyPrivate + { + friend class MUtils::Registry::RegistryKey; + + private: + HKEY m_hKey; + bool m_readOnly; + bool m_isOpen; + }; + } + } +} + +#define CHECK_STATUS(X) do \ +{ \ + if(!p->m_isOpen) \ + { \ + MUTILS_THROW("Cannot read from or write to a key is not currently open!"); \ + } \ + if(p->m_readOnly != (X)) \ + { \ + MUTILS_THROW("Cannot write to read-only key or read from write-only key!"); \ + } \ +} \ +while(0) + +/////////////////////////////////////////////////////////////////////////////// +// Registry Key Class +/////////////////////////////////////////////////////////////////////////////// + +MUtils::Registry::RegistryKey::RegistryKey(const int &rootKey, const QString &keyName, const bool &readOnly) +: + p(new Internal::RegistryKeyPrivate()) +{ + p->m_hKey = NULL; + p->m_readOnly = readOnly; + p->m_isOpen = false; + + p->m_isOpen = (RegCreateKeyEx(registry_root(rootKey), MUTILS_WCHR(keyName), 0, NULL, 0, p->m_readOnly ? KEY_READ : KEY_WRITE, NULL, &p->m_hKey, NULL) == ERROR_SUCCESS); + if(!p->m_isOpen) + { + qWarning("Failed to open registry key!"); + } +} + +MUtils::Registry::RegistryKey::~RegistryKey(void) +{ + if(p->m_isOpen) + { + CloseHandle(p->m_hKey); + p->m_hKey = NULL; + p->m_isOpen = false; + } +} + +inline bool MUtils::Registry::RegistryKey::isOpen(void) +{ + return p->m_isOpen; +} + +bool MUtils::Registry::RegistryKey::value_write(const QString &valueName, const quint32 &value) +{ + CHECK_STATUS(false); + return (RegSetValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, REG_DWORD, reinterpret_cast(&value), sizeof(quint32)) == ERROR_SUCCESS); +} + +bool MUtils::Registry::RegistryKey::value_write(const QString &valueName, const QString &value) +{ + CHECK_STATUS(false); + return (RegSetValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, REG_SZ, reinterpret_cast(value.utf16()), (value.length() + 1) * sizeof(wchar_t)) == ERROR_SUCCESS); +} + +bool MUtils::Registry::RegistryKey::value_read(const QString &valueName, quint32 &value) const +{ + DWORD size = sizeof(quint32), type = -1; + CHECK_STATUS(false); + return (RegQueryValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, &type, reinterpret_cast(&value), &size) == ERROR_SUCCESS) && (type == REG_DWORD); +} + +bool MUtils::Registry::RegistryKey::value_read(const QString &valueName, QString &value) const +{ + wchar_t buffer[2048]; + DWORD size = sizeof(wchar_t) * 2048, type = -1; + CHECK_STATUS(false); + if((RegQueryValueEx(p->m_hKey, valueName.isEmpty() ? NULL : MUTILS_WCHR(valueName), 0, &type, reinterpret_cast(&value), &size) == ERROR_SUCCESS) && ((type == REG_SZ) || (type == REG_EXPAND_SZ))) + { + value = QString::fromUtf16(reinterpret_cast(buffer)); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// HELPER FUNCTIONS +/////////////////////////////////////////////////////////////////////////////// + +/* + * Write registry value + */ +bool MUtils::Registry::reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const quint32 &value) +{ + bool success = false; + RegistryKey regKey(rootKey, keyName, false); + if(regKey.isOpen()) + { + success = regKey.value_write(valueName, value); + } + return success; +} + +/* + * Write registry value + */ +bool MUtils::Registry::reg_value_write(const int &rootKey, const QString &keyName, const QString &valueName, const QString &value) +{ + bool success = false; + RegistryKey regKey(rootKey, keyName, false); + if(regKey.isOpen()) + { + success = regKey.value_write(valueName, value); + } + return success; +} + +/* + * Read registry value + */ +bool MUtils::Registry::reg_value_read(const int &rootKey, const QString &keyName, const QString &valueName, quint32 &value) +{ + bool success = false; + RegistryKey regKey(rootKey, keyName, true); + if(regKey.isOpen()) + { + success = regKey.value_read(valueName, value); + } + return success; +} + +/* + * Read registry value + */ +bool MUtils::Registry::reg_value_read(const int &rootKey, const QString &keyName, const QString &valueName, QString &value) +{ + bool success = false; + RegistryKey regKey(rootKey, keyName, true); + if(regKey.isOpen()) + { + success = regKey.value_read(valueName, value); + } + return success; +} + +/* + * Delete registry key + */ +bool MUtils::Registry::reg_key_delete(const int &rootKey, const QString &keyName) +{ + return (SHDeleteKey(registry_root(rootKey), MUTILS_WCHR(keyName)) == ERROR_SUCCESS); +} -- 2.11.4.GIT