2012-04-29 20:52:25 +02:00
|
|
|
//
|
|
|
|
// WinRegistryKey.cpp
|
|
|
|
//
|
|
|
|
// $Id: //poco/1.4/Util/src/WinRegistryKey.cpp#6 $
|
|
|
|
//
|
|
|
|
// Library: Util
|
|
|
|
// Package: Windows
|
|
|
|
// Module: WinRegistryKey
|
|
|
|
//
|
|
|
|
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
|
|
|
// and Contributors.
|
|
|
|
//
|
2014-05-04 21:02:42 +02:00
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
2012-04-29 20:52:25 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#if !defined(_WIN32_WCE)
|
|
|
|
|
|
|
|
|
|
|
|
#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 {
|
|
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class AutoHandle
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AutoHandle(HMODULE h):
|
|
|
|
_h(h)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoHandle()
|
|
|
|
{
|
|
|
|
FreeLibrary(_h);
|
|
|
|
}
|
|
|
|
|
|
|
|
HMODULE handle()
|
|
|
|
{
|
|
|
|
return _h;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
HMODULE _h;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly, REGSAM extraSam):
|
|
|
|
_hKey(0),
|
|
|
|
_readOnly(readOnly),
|
|
|
|
_extraSam(extraSam)
|
|
|
|
{
|
|
|
|
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, bool readOnly, REGSAM extraSam):
|
|
|
|
_hRootKey(hRootKey),
|
|
|
|
_subKey(subKey),
|
|
|
|
_hKey(0),
|
|
|
|
_readOnly(readOnly),
|
|
|
|
_extraSam(extraSam)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegSetValueExA(_hKey, name.c_str(), 0, REG_SZ, (CONST BYTE*) value.c_str(), (DWORD) value.size() + 1) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_SZ && type != REG_EXPAND_SZ)
|
2012-04-29 20:52:25 +02:00
|
|
|
throw NotFoundException(key(name));
|
|
|
|
if (size > 0)
|
|
|
|
{
|
|
|
|
char* buffer = new char[size + 1];
|
2012-08-19 03:42:38 +02:00
|
|
|
RegQueryValueExA(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer, &size);
|
2012-04-29 20:52:25 +02:00
|
|
|
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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegSetValueExA(_hKey, name.c_str(), 0, REG_EXPAND_SZ, (CONST BYTE*) value.c_str(), (DWORD) value.size() + 1) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
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 (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;
|
|
|
|
wchar_t temp;
|
|
|
|
DWORD expSize = ExpandEnvironmentStringsW(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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS || type != REG_SZ && type != REG_EXPAND_SZ)
|
2012-04-29 20:52:25 +02:00
|
|
|
throw NotFoundException(key(name));
|
|
|
|
if (size > 0)
|
|
|
|
{
|
|
|
|
char* buffer = new char[size + 1];
|
2012-08-19 03:42:38 +02:00
|
|
|
RegQueryValueExA(_hKey, name.c_str(), NULL, NULL, (BYTE*) buffer, &size);
|
2012-04-29 20:52:25 +02:00
|
|
|
buffer[size] = 0;
|
|
|
|
char temp;
|
|
|
|
DWORD expSize = ExpandEnvironmentStringsA(buffer, &temp, 1);
|
|
|
|
char* expBuffer = new char[expSize];
|
|
|
|
ExpandEnvironmentStringsA(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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegSetValueExA(_hKey, name.c_str(), 0, REG_DWORD, (CONST BYTE*) &data, sizeof(data)) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
handleSetError(name);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-08-21 05:15:38 +02:00
|
|
|
|
2012-04-29 20:52:25 +02:00
|
|
|
int WinRegistryKey::getInt(const std::string& name)
|
|
|
|
{
|
|
|
|
open();
|
|
|
|
DWORD type;
|
|
|
|
DWORD data;
|
|
|
|
DWORD size = sizeof(data);
|
|
|
|
#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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_DWORD)
|
2012-04-29 20:52:25 +02:00
|
|
|
throw NotFoundException(key(name));
|
|
|
|
#endif
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2012-08-21 05:15:38 +02:00
|
|
|
#if defined(POCO_HAVE_INT64)
|
|
|
|
|
|
|
|
Poco::Int64 WinRegistryKey::getInt64(const std::string& name)
|
|
|
|
{
|
|
|
|
open();
|
|
|
|
DWORD type;
|
|
|
|
Poco::Int64 data;
|
|
|
|
DWORD size = sizeof(data);
|
|
|
|
#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 (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, (BYTE*) &data, &size) != ERROR_SUCCESS || type != REG_DWORD)
|
|
|
|
throw NotFoundException(key(name));
|
|
|
|
#endif
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // POCO_HAVE_INT64
|
2012-04-29 20:52:25 +02:00
|
|
|
|
|
|
|
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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegDeleteValueA(_hKey, name.c_str()) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
throw NotFoundException(key(name));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: RegDeleteKeyEx is only available on Windows XP 64-bit SP3, Windows Vista or later.
|
|
|
|
// We cannot call it directly as this would prevent the code running on Windows XP 32-bit.
|
|
|
|
// Therefore, if we need to call RegDeleteKeyEx (_extraSam != 0) we need to check for
|
|
|
|
// its existence in ADVAPI32.DLL and call it indirectly.
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
|
|
std::wstring usubKey;
|
|
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
|
|
|
|
|
|
typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved);
|
|
|
|
if (_extraSam != 0)
|
|
|
|
{
|
|
|
|
AutoHandle advAPI32(LoadLibraryW(L"ADVAPI32.DLL"));
|
|
|
|
if (advAPI32.handle())
|
|
|
|
{
|
|
|
|
RegDeleteKeyExWFunc pRegDeleteKeyExW = reinterpret_cast<RegDeleteKeyExWFunc>(GetProcAddress(advAPI32.handle() , "RegDeleteKeyExW"));
|
|
|
|
if (pRegDeleteKeyExW)
|
|
|
|
{
|
|
|
|
if ((*pRegDeleteKeyExW)(_hRootKey, usubKey.c_str(), _extraSam, 0) != ERROR_SUCCESS)
|
|
|
|
throw NotFoundException(key());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
|
|
|
|
throw NotFoundException(key());
|
|
|
|
#else
|
|
|
|
typedef LONG (WINAPI *RegDeleteKeyExAFunc)(HKEY hKey, const char* lpSubKey, REGSAM samDesired, DWORD Reserved);
|
|
|
|
if (_extraSam != 0)
|
|
|
|
{
|
|
|
|
AutoHandle advAPI32(LoadLibraryA("ADVAPI32.DLL"));
|
|
|
|
if (advAPI32.handle())
|
|
|
|
{
|
|
|
|
RegDeleteKeyExAFunc pRegDeleteKeyExA = reinterpret_cast<RegDeleteKeyExAFunc>(GetProcAddress(advAPI32.handle() , "RegDeleteKeyExA"));
|
|
|
|
if (pRegDeleteKeyExA)
|
|
|
|
{
|
|
|
|
if ((*pRegDeleteKeyExA)(_hRootKey, _subKey.c_str(), _extraSam, 0) != ERROR_SUCCESS)
|
|
|
|
throw NotFoundException(key());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (RegDeleteKey(_hRootKey, _subKey.c_str()) != ERROR_SUCCESS)
|
|
|
|
throw NotFoundException(key());
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool WinRegistryKey::exists()
|
|
|
|
{
|
|
|
|
HKEY hKey;
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
|
|
std::wstring usubKey;
|
|
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
|
|
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#else
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegOpenKeyExA(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
{
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
bool exists = false;
|
|
|
|
HKEY hKey;
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
|
|
std::wstring usubKey;
|
|
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
|
|
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &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
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegOpenKeyExA(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &hKey) == ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
{
|
2012-08-19 03:42:38 +02:00
|
|
|
exists = RegQueryValueExA(hKey, name.c_str(), NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
|
2012-04-29 20:52:25 +02:00
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return exists;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void WinRegistryKey::open()
|
|
|
|
{
|
|
|
|
if (!_hKey)
|
|
|
|
{
|
|
|
|
#if defined(POCO_WIN32_UTF8)
|
|
|
|
std::wstring usubKey;
|
|
|
|
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
|
|
|
if (_readOnly)
|
|
|
|
{
|
|
|
|
if (RegOpenKeyExW(_hRootKey, usubKey.c_str(), 0, KEY_READ | _extraSam, &_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 | _extraSam, NULL, &_hKey, NULL) != ERROR_SUCCESS)
|
|
|
|
throw SystemException("Cannot open registry key: ", key());
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (_readOnly)
|
|
|
|
{
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegOpenKeyExA(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &_hKey) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
throw NotFoundException("Cannot open registry key: ", key());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegCreateKeyExA(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | _extraSam, NULL, &_hKey, NULL) != ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
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)
|
|
|
|
{
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegEnumKeyExA(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2012-08-19 03:42:38 +02:00
|
|
|
if (RegEnumValueA(_hKey, i, buf, &bufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
2012-04-29 20:52:25 +02:00
|
|
|
{
|
|
|
|
std::string name(buf);
|
|
|
|
vals.push_back(name);
|
|
|
|
}
|
|
|
|
bufSize = sizeof(buf);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} } // namespace Poco::Util
|
|
|
|
|
|
|
|
|
|
|
|
#endif // !defined(_WIN32_WCE)
|