- fixed SF# 2012050: Configuration key created on read access; - Poco::Util::WinRegistryKey now has a read-only mode; - Poco::Util::WinRegistryKey::deleteKey() can now recursively delete registry keys

This commit is contained in:
Guenter Obiltschnig 2008-09-18 09:04:17 +00:00
parent 707381faca
commit 14a4c61355
6 changed files with 137 additions and 44 deletions

View File

@ -1,7 +1,7 @@
//
// WinRegistryKey.h
//
// $Id: //poco/svn/Util/include/Poco/Util/WinRegistryKey.h#1 $
// $Id: //poco/1.3/Util/include/Poco/Util/WinRegistryKey.h#2 $
//
// Library: Util
// Package: Windows
@ -67,14 +67,22 @@ public:
REGT_DWORD = 4
};
WinRegistryKey(const std::string& key);
WinRegistryKey(const std::string& key, bool readOnly = false);
/// Creates the WinRegistryKey.
///
/// The key must start with one of the root key names
/// like HKEY_CLASSES_ROOT, e.g. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services.
///
/// If readOnly is true, then only read access to the registry
/// is available and any attempt to write to the registry will
/// result in an exception.
WinRegistryKey(HKEY hRootKey, const std::string& subKey);
WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly = false);
/// Creates the WinRegistryKey.
///
/// If readOnly is true, then only read access to the registry
/// is available and any attempt to write to the registry will
/// result in an exception.
~WinRegistryKey();
/// Destroys the WinRegistryKey.
@ -117,7 +125,7 @@ public:
/// Throws a NotFoundException if the value does not exist.
void deleteKey();
/// Deletes the key. The key must not have subkeys.
/// Recursively deletes the key and all subkeys.
bool exists();
/// Returns true iff the key exists.
@ -133,6 +141,9 @@ public:
void values(Values& vals);
/// Appends all value names to vals;
bool isReadOnly() const;
/// Returns true iff the key has been opened for read-only access only.
protected:
void open();
@ -150,9 +161,19 @@ private:
HKEY _hRootKey;
std::string _subKey;
HKEY _hKey;
bool _readOnly;
};
//
// inlines
//
inline bool WinRegistryKey::isReadOnly() const
{
return _readOnly;
}
} } // namespace Poco::Util

View File

@ -1,7 +1,7 @@
//
// WinRegistryConfiguration.cpp
//
// $Id: //poco/svn/Util/src/WinRegistryConfiguration.cpp#1 $
// $Id: //poco/1.3/Util/src/WinRegistryConfiguration.cpp#3 $
//
// Library: Util
// Package: Windows
@ -62,7 +62,7 @@ bool WinRegistryConfiguration::getRaw(const std::string& key, std::string& value
{
std::string keyName;
std::string fullPath = _rootPath + ConvertToRegFormat(key, keyName);
WinRegistryKey aKey(fullPath);
WinRegistryKey aKey(fullPath, true);
bool exists = aKey.exists(keyName);
if (exists)
{
@ -112,7 +112,7 @@ void WinRegistryConfiguration::enumerate(const std::string& key, Keys& range) co
{
std::string keyName;
std::string fullPath = _rootPath+ConvertToRegFormat(key, keyName);
WinRegistryKey aKey(fullPath);
WinRegistryKey aKey(fullPath, true);
aKey.values(range);
aKey.subKeys(range);
}

View File

@ -1,7 +1,7 @@
//
// WinRegistryKey.cpp
//
// $Id: //poco/svn/Util/src/WinRegistryKey.cpp#1 $
// $Id: //poco/1.3/Util/src/WinRegistryKey.cpp#5 $
//
// Library: Util
// Package: Windows
@ -50,8 +50,9 @@ namespace Poco {
namespace Util {
WinRegistryKey::WinRegistryKey(const std::string& key):
_hKey(0)
WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly):
_hKey(0),
_readOnly(readOnly)
{
std::string::size_type pos = key.find('\\');
if (pos != std::string::npos)
@ -64,10 +65,11 @@ WinRegistryKey::WinRegistryKey(const std::string& key):
}
WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey):
WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey, bool readOnly):
_hRootKey(hRootKey),
_subKey(subKey),
_hKey(0)
_hKey(0),
_readOnly(readOnly)
{
}
@ -251,7 +253,17 @@ void WinRegistryKey::deleteValue(const std::string& name)
void WinRegistryKey::deleteKey()
{
Keys keys;
subKeys(keys);
close();
for (Keys::iterator it = keys.begin(); it != keys.end(); ++it)
{
std::string subKey(_subKey);
subKey += "\\";
subKey += *it;
WinRegistryKey subRegKey(_hRootKey, subKey);
subRegKey.deleteKey();
}
#if defined(POCO_WIN32_UTF8)
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
@ -266,15 +278,23 @@ void WinRegistryKey::deleteKey()
bool WinRegistryKey::exists()
{
open();
DWORD size;
HKEY hKey;
#if defined(POCO_WIN32_UTF8)
wchar_t name[256];
return RegEnumValueW(_hKey, 0, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return true;
}
#else
char name[256];
return RegEnumValue(_hKey, 0, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return true;
}
#endif
return false;
}
@ -302,14 +322,26 @@ WinRegistryKey::Type WinRegistryKey::type(const std::string& name)
bool WinRegistryKey::exists(const std::string& name)
{
open();
bool exists = false;
HKEY hKey;
#if defined(POCO_WIN32_UTF8)
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
return RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
std::wstring uname;
Poco::UnicodeConverter::toUTF16(name, uname);
exists = RegQueryValueExW(hKey, uname.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
RegCloseKey(hKey);
}
#else
return RegQueryValueEx(_hKey, name.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
exists = RegQueryValueEx(hKey, name.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
RegCloseKey(hKey);
}
#endif
return exists;
}
@ -320,11 +352,27 @@ void WinRegistryKey::open()
#if defined(POCO_WIN32_UTF8)
std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegCreateKeyExW(_hRootKey, usubKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
throw SystemException("Cannot open registry key: ", key());
if (_readOnly)
{
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ, &_hKey) != ERROR_SUCCESS)
throw NotFoundException("Cannot open registry key: ", key());
}
else
{
if (RegCreateKeyExW(_hRootKey, usubKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
throw SystemException("Cannot open registry key: ", key());
}
#else
if (RegCreateKeyEx(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
throw SystemException("Cannot open registry key: ", key());
if (_readOnly)
{
if (RegOpenKeyEx(_hRootKey, _subKey.c_str(), 0, KEY_READ, &_hKey) != ERROR_SUCCESS)
throw NotFoundException("Cannot open registry key: ", key());
}
else
{
if (RegCreateKeyEx(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &_hKey, NULL) != ERROR_SUCCESS)
throw SystemException("Cannot open registry key: ", key());
}
#endif
}
}

View File

@ -1,7 +1,7 @@
//
// UtilTestSuite.cpp
//
// $Id: //poco/svn/Util/testsuite/src/UtilTestSuite.cpp#1 $
// $Id: //poco/1.3/Util/testsuite/src/UtilTestSuite.cpp#4 $
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
@ -33,7 +33,7 @@
#include "UtilTestSuite.h"
#include "ConfigurationTestSuite.h"
#include "OptionsTestSuite.h"
#if defined(_MFC_VER)
#if defined(_MSC_VER)
#include "WindowsTestSuite.h"
#endif
@ -44,7 +44,7 @@ CppUnit::Test* UtilTestSuite::suite()
pSuite->addTest(ConfigurationTestSuite::suite());
pSuite->addTest(OptionsTestSuite::suite());
#if defined(_MFC_VER)
#if defined(_MSC_VER)
pSuite->addTest(WindowsTestSuite::suite());
#endif

View File

@ -1,7 +1,7 @@
//
// WinConfigurationTest.cpp
//
// $Id: //poco/svn/Util/testsuite/src/WinConfigurationTest.cpp#1 $
// $Id: //poco/1.3/Util/testsuite/src/WinConfigurationTest.cpp#2 $
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
@ -55,18 +55,25 @@ WinConfigurationTest::~WinConfigurationTest()
void WinConfigurationTest::testConfiguration()
{
AutoPtr<WinRegistryConfiguration> reg = new WinRegistryConfiguration("HKEY_CURRENT_USER\\Software\\Applied Informatics\\Test");
reg->setString("name1", "value1");
assert (reg->getString("name1") == "value1");
reg->setInt("name1", 1); // overwrite should also change type
assert (reg->getInt("name1") == 1);
reg->setString("name2", "value2");
assert (reg->getString("name2") == "value2");
assert (reg->hasProperty("name1"));
assert (reg->hasProperty("name2"));
AutoPtr<WinRegistryConfiguration> pReg = new WinRegistryConfiguration("HKEY_CURRENT_USER\\Software\\Applied Informatics\\Test");
pReg->setString("name1", "value1");
assert (pReg->getString("name1") == "value1");
pReg->setInt("name1", 1); // overwrite should also change type
assert (pReg->getInt("name1") == 1);
pReg->setString("name2", "value2");
assert (pReg->getString("name2") == "value2");
assert (pReg->hasProperty("name1"));
assert (pReg->hasProperty("name2"));
std::string dfl = reg->getString("nonexistent", "default");
std::string dfl = pReg->getString("nonexistent", "default");
assert (dfl == "default");
AutoPtr<Poco::Util::AbstractConfiguration> pView = pReg->createView("config");
dfl = pView->getString("sub.foo", "default");
assert (dfl == "default");
pView->setString("sub.foo", "bar");
assert (pView->getString("sub.foo", "default") == "bar");
}

View File

@ -1,7 +1,7 @@
//
// WinRegistryTest.cpp
//
// $Id: //poco/svn/Util/testsuite/src/WinRegistryTest.cpp#1 $
// $Id: //poco/1.3/Util/testsuite/src/WinRegistryTest.cpp#1 $
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
@ -35,6 +35,7 @@
#include "CppUnit/TestSuite.h"
#include "Poco/Util/WinRegistryKey.h"
#include "Poco/Environment.h"
#include "Poco/Exception.h"
using Poco::Util::WinRegistryKey;
@ -54,7 +55,11 @@ WinRegistryTest::~WinRegistryTest()
void WinRegistryTest::testRegistry()
{
WinRegistryKey regKey("HKEY_CURRENT_USER\\Software\\Applied Informatics\\Test");
regKey.deleteKey();
if (regKey.exists())
{
regKey.deleteKey();
}
assert (!regKey.exists());
regKey.setString("name1", "value1");
assert (regKey.getString("name1") == "value1");
regKey.setString("name1", "Value1");
@ -64,7 +69,19 @@ void WinRegistryTest::testRegistry()
assert (regKey.exists("name1"));
assert (regKey.exists("name2"));
assert (regKey.exists());
WinRegistryKey regKeyRO("HKEY_CURRENT_USER\\Software\\Applied Informatics\\Test", true);
assert (regKeyRO.getString("name1") == "Value1");
try
{
regKeyRO.setString("name1", "newValue1");
}
catch (Poco::Exception& exc)
{
std::string msg = exc.displayText();
}
assert (regKey.getString("name1") == "Value1");
WinRegistryKey::Values vals;
regKey.values(vals);
assert (vals.size() == 2);