diff --git a/Util/include/Poco/Util/WinRegistryKey.h b/Util/include/Poco/Util/WinRegistryKey.h index 7e9c66737..d8005fce9 100644 --- a/Util/include/Poco/Util/WinRegistryKey.h +++ b/Util/include/Poco/Util/WinRegistryKey.h @@ -44,6 +44,7 @@ public: REGT_NONE = 0, REGT_STRING = 1, REGT_STRING_EXPAND = 2, + REGT_BINARY = 3, REGT_DWORD = 4, REGT_QWORD = 11 }; @@ -96,6 +97,16 @@ public: /// /// Throws a NotFoundException if the value does not exist. + void setBinary(const std::string& name, const std::vector& value); + /// Sets the string value (REG_BINARY) with the given name. + /// An empty name denotes the default value. + + std::vector getBinary(const std::string& name); + /// Returns the string value (REG_BINARY) with the given name. + /// An empty name denotes the default value. + /// + /// Throws a NotFoundException if the value does not exist. + void setInt(const std::string& name, int value); /// Sets the numeric (REG_DWORD) value with the given name. /// An empty name denotes the default value. @@ -108,6 +119,10 @@ public: #if defined(POCO_HAVE_INT64) + void setInt64(const std::string& name, Poco::Int64 value); + /// Sets the numeric (REG_QWORD) value with the given name. + /// An empty name denotes the default value. + Poco::Int64 getInt64(const std::string& name); /// Returns the numeric value (REG_QWORD) with the given name. /// An empty name denotes the default value. diff --git a/Util/src/WinRegistryConfiguration.cpp b/Util/src/WinRegistryConfiguration.cpp index 11d55f155..25f1d73b3 100644 --- a/Util/src/WinRegistryConfiguration.cpp +++ b/Util/src/WinRegistryConfiguration.cpp @@ -62,6 +62,12 @@ bool WinRegistryConfiguration::getRaw(const std::string& key, std::string& value case WinRegistryKey::REGT_STRING_EXPAND: value = aKey.getStringExpand(keyName); break; + case WinRegistryKey::REGT_BINARY: + { + std::vector tmp = aKey.getBinary(keyName); + value.assign(tmp.begin(), tmp.end()); + } + break; case WinRegistryKey::REGT_DWORD: value = Poco::NumberFormatter::format(aKey.getInt(keyName)); break; diff --git a/Util/src/WinRegistryKey.cpp b/Util/src/WinRegistryKey.cpp index 6eaf31229..4c0639fdf 100644 --- a/Util/src/WinRegistryKey.cpp +++ b/Util/src/WinRegistryKey.cpp @@ -19,6 +19,7 @@ #include "Poco/Util/WinRegistryKey.h" #include "Poco/Exception.h" +#include "Poco/Buffer.h" #if defined(POCO_WIN32_UTF8) #include "Poco/UnicodeConverter.h" #endif @@ -121,11 +122,10 @@ std::string WinRegistryKey::getString(const std::string& name) if (size > 0) { DWORD len = size/2; - wchar_t* buffer = new wchar_t[len + 1]; - RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) buffer, &size); + Poco::Buffer buffer(len + 1); + RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) buffer.begin(), &size); buffer[len] = 0; - std::wstring uresult(buffer); - delete [] buffer; + std::wstring uresult(buffer.begin()); std::string result; Poco::UnicodeConverter::toUTF8(uresult, result); return result; @@ -135,11 +135,10 @@ std::string WinRegistryKey::getString(const std::string& name) throw NotFoundException(key(name)); if (size > 0) { - char* buffer = new char[size + 1]; - RegQueryValueExA(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer, &size); + Poco::Buffer buffer(new char[size + 1]); + RegQueryValueExA(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer.begin(), &size); buffer[size] = 0; std::string result(buffer); - delete [] buffer; return result; } #endif @@ -212,6 +211,52 @@ std::string WinRegistryKey::getStringExpand(const std::string& name) } + +void WinRegistryKey::setBinary( const std::string& name, const std::vector& value ) +{ + open(); +#if defined(POCO_WIN32_UTF8) + std::wstring uname; + Poco::UnicodeConverter::toUTF16(name, uname); + if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_BINARY, (CONST BYTE*) value.data(), (DWORD) value.size()) != ERROR_SUCCESS) + handleSetError(name); +#else + if (RegSetValueExA(_hKey, name.c_str(), 0, REG_BINARY, (CONST BYTE*) value.data(), (DWORD) value.size()) != ERROR_SUCCESS) + handleSetError(name); +#endif +} + + +std::vector WinRegistryKey::getBinary( const std::string& name ) +{ + open(); + DWORD type; + DWORD size; + std::vector result; + +#if defined(POCO_WIN32_UTF8) + std::wstring uname; + Poco::UnicodeConverter::toUTF16(name, uname); + if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_BINARY) + throw NotFoundException(key(name)); + if (size > 0) + { + result.resize(size); + RegQueryValueExW(_hKey, uname.c_str(), NULL, NULL, (BYTE*) result.data(), &size); + } +#else + if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_BINARY) + throw NotFoundException(key(name)); + if (size > 0) + { + result.resize(size); + RegQueryValueExA(_hKey, name.c_str(), NULL, NULL, (BYTE*) result.data(), &size); + } +#endif + return result; +} + + void WinRegistryKey::setInt(const std::string& name, int value) { open(); @@ -248,6 +293,20 @@ int WinRegistryKey::getInt(const std::string& name) #if defined(POCO_HAVE_INT64) +void WinRegistryKey::setInt64(const std::string& name, Poco::Int64 value) +{ + open(); +#if defined(POCO_WIN32_UTF8) + std::wstring uname; + Poco::UnicodeConverter::toUTF16(name, uname); + if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_QWORD, (CONST BYTE*) &value, sizeof(value)) != ERROR_SUCCESS) + handleSetError(name); +#else + if (RegSetValueExA(_hKey, name.c_str(), 0, REG_QWORD, (CONST BYTE*) &value, sizeof(value)) != ERROR_SUCCESS) + handleSetError(name); +#endif +} + Poco::Int64 WinRegistryKey::getInt64(const std::string& name) { open(); @@ -257,10 +316,10 @@ Poco::Int64 WinRegistryKey::getInt64(const std::string& name) #if defined(POCO_WIN32_UTF8) std::wstring uname; Poco::UnicodeConverter::toUTF16(name, uname); - if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_DWORD) + if (RegQueryValueExW(_hKey, uname.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_QWORD) throw NotFoundException(key(name)); #else - if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_DWORD) + if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_QWORD) throw NotFoundException(key(name)); #endif return data; @@ -380,7 +439,7 @@ WinRegistryKey::Type WinRegistryKey::type(const std::string& name) if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS) throw NotFoundException(key(name)); #endif - if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_DWORD) + if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_DWORD && type != REG_QWORD && type != REG_BINARY) throw NotFoundException(key(name)+": type not supported"); Type aType = (Type)type; diff --git a/Util/testsuite/src/WinConfigurationTest.cpp b/Util/testsuite/src/WinConfigurationTest.cpp index 956fb7ff1..adcac8635 100644 --- a/Util/testsuite/src/WinConfigurationTest.cpp +++ b/Util/testsuite/src/WinConfigurationTest.cpp @@ -62,7 +62,22 @@ void WinConfigurationTest::testConfiguration() assert (pReg->getUInt64("name2") == std::numeric_limits::max()); pReg->setInt64("name2", std::numeric_limits::min()); assert (pReg->getInt64("name2") == std::numeric_limits::min()); + + /// write real int64 value type + regKey.setInt64("name3", std::numeric_limits::max()); + assert (pReg->getInt64("name3") == std::numeric_limits::max()); #endif + + /// create fake binary data + const int dataSize = 127; + std::vector data(dataSize); + for (int i = 0; i < dataSize; ++i) + data[i] = rand() % 256; + + regKey.setBinary("name4", data); + assert (pReg->getString("name4") == std::string(data.begin(), data.end())); + + assert (pReg->hasProperty("name1")); assert (pReg->hasProperty("name2")); @@ -82,9 +97,11 @@ void WinConfigurationTest::testConfiguration() Poco::Util::AbstractConfiguration::Keys keys; pReg->keys(keys); - assert (keys.size() == 3); + assert (keys.size() == 5); assert (std::find(keys.begin(), keys.end(), "name1") != keys.end()); assert (std::find(keys.begin(), keys.end(), "name2") != keys.end()); + assert (std::find(keys.begin(), keys.end(), "name3") != keys.end()); + assert (std::find(keys.begin(), keys.end(), "name4") != keys.end()); assert (std::find(keys.begin(), keys.end(), "config") != keys.end()); pReg->keys("config", keys); @@ -105,9 +122,11 @@ void WinConfigurationTest::testConfiguration() assert (std::find(keys.begin(), keys.end(), "HKEY_USERS") != keys.end()); pRootReg->keys("HKEY_CURRENT_USER.Software.Applied Informatics.Test", keys); - assert (keys.size() == 3); + assert (keys.size() == 5); assert (std::find(keys.begin(), keys.end(), "name1") != keys.end()); assert (std::find(keys.begin(), keys.end(), "name2") != keys.end()); + assert (std::find(keys.begin(), keys.end(), "name3") != keys.end()); + assert (std::find(keys.begin(), keys.end(), "name4") != keys.end()); assert (std::find(keys.begin(), keys.end(), "config") != keys.end()); } diff --git a/Util/testsuite/src/WinRegistryTest.cpp b/Util/testsuite/src/WinRegistryTest.cpp index 8fc415cb4..6d1c38243 100644 --- a/Util/testsuite/src/WinRegistryTest.cpp +++ b/Util/testsuite/src/WinRegistryTest.cpp @@ -19,12 +19,19 @@ #include "Poco/Util/WinRegistryKey.h" #include "Poco/Environment.h" #include "Poco/Exception.h" +#undef min +#undef max +#include +#if defined(POCO_HAVE_INT64) +using Poco::Int64; +#endif using Poco::Util::WinRegistryKey; using Poco::Environment; + WinRegistryTest::WinRegistryTest(const std::string& name): CppUnit::TestCase(name) { } @@ -81,6 +88,26 @@ void WinRegistryTest::testRegistry() regKey.deleteValue("name4"); assert (!regKey.exists("name4")); +#if defined(POCO_HAVE_INT64) + regKey.setInt64("name5", std::numeric_limits::max()); + assert (regKey.getInt64("name5") == std::numeric_limits::max()); + + assert (regKey.exists("name5")); + regKey.deleteValue("name5"); + assert (!regKey.exists("name5")); +#endif + + const int dataSize = 127; + std::vector data(dataSize); + for (int i = 0; i < dataSize; ++i) + data[i] = rand() % 256; + regKey.setBinary("binary", data); + assert (regKey.getBinary("binary") == data); + + assert (regKey.exists("binary")); + regKey.deleteValue("binary"); + assert (!regKey.exists("binary")); + regKey.deleteKey(); assert (!regKey.exists()); }