mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-20 20:56:20 +01:00
484 lines
13 KiB
C++
484 lines
13 KiB
C++
//
|
|
// WinRegistryKey.cpp
|
|
//
|
|
// $Id: //poco/1.2/Util/src/WinRegistryKey.cpp#1 $
|
|
//
|
|
// Library: Util
|
|
// Package: Windows
|
|
// Module: WinRegistryKey
|
|
//
|
|
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person or organization
|
|
// obtaining a copy of the software and accompanying documentation covered by
|
|
// this license (the "Software") to use, reproduce, display, distribute,
|
|
// execute, and transmit the Software, and to prepare derivative works of the
|
|
// Software, and to permit third-parties to whom the Software is furnished to
|
|
// do so, all subject to the following:
|
|
//
|
|
// The copyright notices in the Software and this entire statement, including
|
|
// the above license grant, this restriction and the following disclaimer,
|
|
// must be included in all copies of the Software, in whole or in part, and
|
|
// all derivative works of the Software, unless such copies or derivative
|
|
// works are solely in the form of machine-executable object code generated by
|
|
// a source language processor.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
// DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
|
|
#include "Poco/Util/WinRegistryKey.h"
|
|
#include "Poco/Exception.h"
|
|
#if defined(POCO_WIN32_UTF8)
|
|
#include "Poco/UnicodeConverter.h"
|
|
#endif
|
|
|
|
|
|
using Poco::SystemException;
|
|
using Poco::NotFoundException;
|
|
using Poco::InvalidArgumentException;
|
|
|
|
|
|
namespace Poco {
|
|
namespace Util {
|
|
|
|
|
|
WinRegistryKey::WinRegistryKey(const std::string& key):
|
|
_hKey(0)
|
|
{
|
|
std::string::size_type pos = key.find('\\');
|
|
if (pos != std::string::npos)
|
|
{
|
|
std::string rootKey = key.substr(0, pos);
|
|
_hRootKey = handleFor(rootKey);
|
|
_subKey = key.substr(pos + 1);
|
|
}
|
|
else throw InvalidArgumentException("Not a valid registry key", key);
|
|
}
|
|
|
|
|
|
WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey):
|
|
_hRootKey(hRootKey),
|
|
_subKey(subKey),
|
|
_hKey(0)
|
|
{
|
|
}
|
|
|
|
|
|
WinRegistryKey::~WinRegistryKey()
|
|
{
|
|
close();
|
|
}
|
|
|
|
|
|
void WinRegistryKey::setString(const std::string& name, const std::string& value)
|
|
{
|
|
open();
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring uname;
|
|
Poco::UnicodeConverter::toUTF16(name, uname);
|
|
std::wstring uvalue;
|
|
Poco::UnicodeConverter::toUTF16(value, uvalue);
|
|
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_SZ, (CONST BYTE*) uvalue.c_str(), (DWORD) (uvalue.size() + 1)*sizeof(wchar_t)) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#else
|
|
if (RegSetValueEx(_hKey, name.c_str(), 0, REG_SZ, (CONST BYTE*) value.c_str(), (DWORD) value.size() + 1) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#endif
|
|
}
|
|
|
|
|
|
std::string WinRegistryKey::getString(const std::string& name)
|
|
{
|
|
open();
|
|
DWORD type;
|
|
DWORD size;
|
|
#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_SZ && type != REG_EXPAND_SZ)
|
|
throw NotFoundException(key(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);
|
|
buffer[len] = 0;
|
|
std::wstring uresult(buffer);
|
|
delete [] buffer;
|
|
std::string result;
|
|
Poco::UnicodeConverter::toUTF8(uresult, result);
|
|
return result;
|
|
}
|
|
#else
|
|
if (RegQueryValueEx(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_SZ && type != REG_EXPAND_SZ)
|
|
throw NotFoundException(key(name));
|
|
if (size > 0)
|
|
{
|
|
char* buffer = new char[size + 1];
|
|
RegQueryValueEx(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer, &size);
|
|
buffer[size] = 0;
|
|
std::string result(buffer);
|
|
delete [] buffer;
|
|
return result;
|
|
}
|
|
#endif
|
|
return std::string();
|
|
}
|
|
|
|
|
|
void WinRegistryKey::setStringExpand(const std::string& name, const std::string& value)
|
|
{
|
|
open();
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring uname;
|
|
Poco::UnicodeConverter::toUTF16(name, uname);
|
|
std::wstring uvalue;
|
|
Poco::UnicodeConverter::toUTF16(value, uvalue);
|
|
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_EXPAND_SZ, (CONST BYTE*) uvalue.c_str(), (DWORD) (uvalue.size() + 1)*sizeof(wchar_t)) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#else
|
|
if (RegSetValueEx(_hKey, name.c_str(), 0, REG_EXPAND_SZ, (CONST BYTE*) value.c_str(), (DWORD) value.size() + 1) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#endif
|
|
}
|
|
|
|
|
|
std::string WinRegistryKey::getStringExpand(const std::string& name)
|
|
{
|
|
open();
|
|
DWORD type;
|
|
DWORD size;
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring uname;
|
|
Poco::UnicodeConverter::toUTF16(name, uname);
|
|
if (RegQueryValueEx(_hKey, uname.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_SZ && type != REG_EXPAND_SZ)
|
|
throw NotFoundException(key(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);
|
|
buffer[len] = 0;
|
|
wchar_t temp;
|
|
DWORD expSize = ExpandEnvironmentStrings(buffer, &temp, 1);
|
|
wchar_t* expBuffer = new wchar_t[expSize];
|
|
ExpandEnvironmentStringsW(buffer, expBuffer, expSize);
|
|
std::string result;
|
|
UnicodeConverter::toUTF8(expBuffer, result);
|
|
delete [] buffer;
|
|
delete [] expBuffer;
|
|
return result;
|
|
}
|
|
#else
|
|
if (RegQueryValueEx(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_SZ && type != REG_EXPAND_SZ)
|
|
throw NotFoundException(key(name));
|
|
if (size > 0)
|
|
{
|
|
char* buffer = new char[size + 1];
|
|
RegQueryValueEx(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer, &size);
|
|
buffer[size] = 0;
|
|
char temp;
|
|
DWORD expSize = ExpandEnvironmentStrings(buffer, &temp, 1);
|
|
char* expBuffer = new char[expSize];
|
|
ExpandEnvironmentStrings(buffer, expBuffer, expSize);
|
|
std::string result(expBuffer);
|
|
delete [] buffer;
|
|
delete [] expBuffer;
|
|
return result;
|
|
}
|
|
#endif
|
|
return std::string();
|
|
}
|
|
|
|
|
|
void WinRegistryKey::setInt(const std::string& name, int value)
|
|
{
|
|
open();
|
|
DWORD data = value;
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring uname;
|
|
Poco::UnicodeConverter::toUTF16(name, uname);
|
|
if (RegSetValueExW(_hKey, uname.c_str(), 0, REG_DWORD, (CONST BYTE*) &data, sizeof(data)) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#else
|
|
if (RegSetValueEx(_hKey, name.c_str(), 0, REG_DWORD, (CONST BYTE*) &data, sizeof(data)) != ERROR_SUCCESS)
|
|
handleSetError(name);
|
|
#endif
|
|
}
|
|
|
|
|
|
int WinRegistryKey::getInt(const std::string& name)
|
|
{
|
|
open();
|
|
DWORD type;
|
|
DWORD data;
|
|
DWORD size;
|
|
#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)
|
|
throw NotFoundException(key(name));
|
|
#else
|
|
if (RegQueryValueEx(_hKey, name.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_DWORD)
|
|
throw NotFoundException(key(name));
|
|
#endif
|
|
return data;
|
|
}
|
|
|
|
|
|
void WinRegistryKey::deleteValue(const std::string& name)
|
|
{
|
|
open();
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring uname;
|
|
Poco::UnicodeConverter::toUTF16(name, uname);
|
|
if (RegDeleteValueW(_hKey, uname.c_str()) != ERROR_SUCCESS)
|
|
throw NotFoundException(key(name));
|
|
#else
|
|
if (RegDeleteValue(_hKey, name.c_str()) != ERROR_SUCCESS)
|
|
throw NotFoundException(key(name));
|
|
#endif
|
|
}
|
|
|
|
|
|
void WinRegistryKey::deleteKey()
|
|
{
|
|
close();
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring usubKey;
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
|
|
throw NotFoundException(key());
|
|
#else
|
|
if (RegDeleteKey(_hRootKey, _subKey.c_str()) != ERROR_SUCCESS)
|
|
throw NotFoundException(key());
|
|
#endif
|
|
}
|
|
|
|
|
|
bool WinRegistryKey::exists()
|
|
{
|
|
open();
|
|
DWORD size;
|
|
#if defined(POCO_WIN32_UTF8)
|
|
wchar_t name[256];
|
|
return RegEnumValueW(_hKey, 0, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
|
|
#else
|
|
char name[256];
|
|
return RegEnumValue(_hKey, 0, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
|
|
WinRegistryKey::Type WinRegistryKey::type(const std::string& name)
|
|
{
|
|
open();
|
|
DWORD type = REG_NONE;
|
|
DWORD size;
|
|
#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)
|
|
throw NotFoundException(key(name));
|
|
#else
|
|
if (RegQueryValueEx(_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)
|
|
throw NotFoundException(key(name)+": type not supported");
|
|
|
|
Type aType = (Type)type;
|
|
return aType;
|
|
}
|
|
|
|
|
|
bool WinRegistryKey::exists(const std::string& name)
|
|
{
|
|
open();
|
|
#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;
|
|
#else
|
|
return RegQueryValueEx(_hKey, name.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
|
|
void WinRegistryKey::open()
|
|
{
|
|
if (!_hKey)
|
|
{
|
|
#if defined(POCO_WIN32_UTF8)
|
|
std::wstring usubKey;
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
if (RegCreateKeyEx(_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());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
void WinRegistryKey::close()
|
|
{
|
|
if (_hKey)
|
|
{
|
|
RegCloseKey(_hKey);
|
|
_hKey = 0;
|
|
}
|
|
}
|
|
|
|
|
|
std::string WinRegistryKey::key() const
|
|
{
|
|
std::string result;
|
|
if (_hRootKey == HKEY_CLASSES_ROOT)
|
|
result = "HKEY_CLASSES_ROOT";
|
|
else if (_hRootKey == HKEY_CURRENT_CONFIG)
|
|
result = "HKEY_CURRENT_CONFIG";
|
|
else if (_hRootKey == HKEY_CURRENT_USER)
|
|
result = "HKEY_CURRENT_USER";
|
|
else if (_hRootKey == HKEY_LOCAL_MACHINE)
|
|
result = "HKEY_LOCAL_MACHINE";
|
|
else if (_hRootKey == HKEY_USERS)
|
|
result = "HKEY_USERS";
|
|
else if (_hRootKey == HKEY_PERFORMANCE_DATA)
|
|
result = "HKEY_PERFORMANCE_DATA";
|
|
else
|
|
result = "(UNKNOWN)";
|
|
result += '\\';
|
|
result += _subKey;
|
|
return result;
|
|
}
|
|
|
|
|
|
std::string WinRegistryKey::key(const std::string& valueName) const
|
|
{
|
|
std::string& result = key();
|
|
if (!valueName.empty())
|
|
{
|
|
result += '\\';
|
|
result += valueName;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
HKEY WinRegistryKey::handleFor(const std::string& rootKey)
|
|
{
|
|
if (rootKey == "HKEY_CLASSES_ROOT")
|
|
return HKEY_CLASSES_ROOT;
|
|
else if (rootKey == "HKEY_CURRENT_CONFIG")
|
|
return HKEY_CURRENT_CONFIG;
|
|
else if (rootKey == "HKEY_CURRENT_USER")
|
|
return HKEY_CURRENT_USER;
|
|
else if (rootKey == "HKEY_LOCAL_MACHINE")
|
|
return HKEY_LOCAL_MACHINE;
|
|
else if (rootKey == "HKEY_USERS")
|
|
return HKEY_USERS;
|
|
else if (rootKey == "HKEY_PERFORMANCE_DATA")
|
|
return HKEY_PERFORMANCE_DATA;
|
|
else
|
|
throw InvalidArgumentException("Not a valid root key", rootKey);
|
|
}
|
|
|
|
|
|
void WinRegistryKey::handleSetError(const std::string& name)
|
|
{
|
|
std::string msg = "Failed to set registry value";
|
|
throw SystemException(msg, key(name));
|
|
}
|
|
|
|
|
|
void WinRegistryKey::subKeys(WinRegistryKey::Keys& keys)
|
|
{
|
|
open();
|
|
|
|
DWORD subKeyCount = 0;
|
|
DWORD valueCount = 0;
|
|
|
|
if (RegQueryInfoKey(_hKey, NULL, NULL, NULL, &subKeyCount, NULL, NULL, &valueCount, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
|
return;
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
wchar_t buf[256];
|
|
DWORD bufSize = sizeof(buf)/sizeof(wchar_t);
|
|
for (DWORD i = 0; i< subKeyCount; ++i)
|
|
{
|
|
if (RegEnumKeyExW(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
std::wstring uname(buf);
|
|
std::string name;
|
|
Poco::UnicodeConverter::toUTF8(uname, name);
|
|
keys.push_back(name);
|
|
}
|
|
bufSize = sizeof(buf)/sizeof(wchar_t);
|
|
}
|
|
#else
|
|
char buf[256];
|
|
DWORD bufSize = sizeof(buf);
|
|
for (DWORD i = 0; i< subKeyCount; ++i)
|
|
{
|
|
if (RegEnumKeyEx(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
std::string name(buf);
|
|
keys.push_back(name);
|
|
}
|
|
bufSize = sizeof(buf);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
void WinRegistryKey::values(WinRegistryKey::Values& vals)
|
|
{
|
|
open();
|
|
|
|
DWORD valueCount = 0;
|
|
|
|
if (RegQueryInfoKey(_hKey, NULL, NULL, NULL, NULL, NULL, NULL, &valueCount, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
|
return ;
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
wchar_t buf[256];
|
|
DWORD bufSize = sizeof(buf)/sizeof(wchar_t);
|
|
for (DWORD i = 0; i< valueCount; ++i)
|
|
{
|
|
if (RegEnumValueW(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
std::wstring uname(buf);
|
|
std::string name;
|
|
Poco::UnicodeConverter::toUTF8(uname, name);
|
|
vals.push_back(name);
|
|
}
|
|
bufSize = sizeof(buf)/sizeof(wchar_t);
|
|
}
|
|
#else
|
|
char buf[256];
|
|
DWORD bufSize = sizeof(buf);
|
|
for (DWORD i = 0; i< valueCount; ++i)
|
|
{
|
|
if (RegEnumValue(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
std::string name(buf);
|
|
vals.push_back(name);
|
|
}
|
|
bufSize = sizeof(buf);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
} } // namespace Poco::Util
|