Logo Search packages:      
Sourcecode: poco version File versions  Download package

WinRegistryKey.cpp

//
// 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);
}


00067 WinRegistryKey::WinRegistryKey(HKEY hRootKey, const std::string& subKey):
      _hRootKey(hRootKey),
      _subKey(subKey),
      _hKey(0)
{
}


00075 WinRegistryKey::~WinRegistryKey()
{
      close();
}


00081 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
}


00098 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();
}


00137 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
}


00154 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();
}


00202 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
}

      
00218 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;
}


00237 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
}


00252 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
}


00267 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
}


00281 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;
}


00303 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
}


00316 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));
}


00404 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
}


00444 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

Generated by  Doxygen 1.6.0   Back to index