blob: 08d6fd38e3bf4726e6f179f572595ee8ed987844 [file] [log] [blame]
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#pragma once
#ifndef NO_SHLWAPI_REG
#ifndef _INC_SHLWAPI
#include <shlwapi.h>
#endif
#pragma comment(lib, "shlwapi.lib")
#endif
namespace Registry
{
//struct create_t
//{
// const HKEY m_hKey;
// create_t(HKEY h) : m_hKey(h) {}
//private:
// create_t(const create_t& c);
// create_t& operator=(const create_t&);
//};
class Key
{
public:
Key();
//open
template<typename char_t>
Key(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);
//open
template<typename char_t>
Key(HKEY, const std::basic_string<char_t>&, REGSAM = KEY_QUERY_VALUE);
//template<typename char_t>
//Key(const create_t&, const char_t*); //create
//
//template<typename char_t>
//Key(const create_t&, const std::basic_string<char_t>&); //create
~Key();
operator HKEY() const;
template<typename char_t>
LONG open(HKEY, const char_t*, REGSAM = KEY_QUERY_VALUE);
template<typename char_t>
LONG open(
HKEY,
const std::basic_string<char_t>&,
REGSAM = KEY_QUERY_VALUE);
template<typename char_t>
LONG create(
HKEY parent,
const char_t* subkey,
DWORD* disposition = 0);
template<typename char_t>
LONG create(
HKEY parent,
const std::basic_string<char_t>& subkey,
DWORD* disposition = 0);
template<typename char_t>
LONG create(
HKEY parent,
const char_t* subkey,
const char_t* object_type,
DWORD options,
REGSAM samDesired,
const SECURITY_ATTRIBUTES*,
DWORD* disposition = 0); //out
bool is_open() const;
LONG close();
template<typename char_t>
LONG query(const char_t*, DWORD&) const;
template<typename char_t>
inline bool operator()(const char_t* name, DWORD& value) const
{
return (query<char_t>(name, value) == ERROR_SUCCESS);
}
template<typename char_t>
LONG query(
const char_t*,
std::basic_string<char_t>&,
DWORD = REG_SZ) const;
template<typename char_t>
inline bool operator()(
const char_t* val,
std::basic_string<char_t>& buf,
DWORD t = REG_SZ) const
{
return (query<char_t>(val, buf, t) == ERROR_SUCCESS);
}
template<typename char_t>
inline LONG query(
std::basic_string<char_t>& buf,
DWORD t = REG_SZ) const
{
return query<char_t>((const char_t*)0, buf, t);
}
template<typename char_t>
inline bool operator()(
std::basic_string<char_t>& buf,
DWORD t = REG_SZ) const
{
return (query<char_t>(buf, t) == ERROR_SUCCESS);
}
template<typename char_t>
LONG set(
const char_t* name,
DWORD value,
DWORD type = REG_DWORD) const;
template<typename char_t>
LONG set(
const char_t* name,
const char_t* value,
DWORD type = REG_SZ) const;
template<typename char_t>
inline LONG set(const char_t* value) const
{
const char_t* const default_name = 0;
return set<char_t>(default_name, value, REG_SZ);
}
template<typename char_t>
LONG setn(
const char_t* name,
const char_t* value,
DWORD length_including_null,
DWORD type = REG_SZ) const;
template<typename char_t>
inline LONG setn(const char_t* val, DWORD len) const
{
const char_t* const default_name = 0;
return setn<char_t>(default_name, val, len, REG_SZ);
}
template<typename char_t>
LONG set(
const char_t* name,
const std::basic_string<char_t>&,
DWORD type = REG_SZ) const;
//for binary data:
//LONG set(
// const TCHAR* name,
// const void* data,
// DWORD size);
private:
Key(const Key&);
Key& operator=(const Key&);
HKEY m_hKey;
};
template<typename char_t>
LONG DeleteKey(HKEY, const std::basic_string<char_t>&);
template<>
inline LONG DeleteKey(HKEY h, const std::string& k)
{
return ::RegDeleteKeyA(h, k.c_str());
}
template<>
inline LONG DeleteKey(HKEY h, const std::wstring& k)
{
return ::RegDeleteKeyW(h, k.c_str());
}
template<typename char_t>
LONG OpenKey(HKEY, const char_t*, REGSAM, HKEY&);
template<>
inline LONG OpenKey(HKEY h, const char* k, REGSAM sam, HKEY& hh)
{
return RegOpenKeyExA(h, k, 0, sam, &hh);
}
template<>
inline LONG OpenKey(HKEY h, const wchar_t* k, REGSAM sam, HKEY& hh)
{
return RegOpenKeyExW(h, k, 0, sam, &hh);
}
template<typename char_t>
LONG CreateKey(
HKEY,
const char_t*,
char_t*,
DWORD,
REGSAM,
LPSECURITY_ATTRIBUTES,
HKEY&,
DWORD*);
template<>
inline LONG CreateKey(
HKEY h,
const char* k,
char* t,
DWORD opts,
REGSAM sam,
LPSECURITY_ATTRIBUTES p,
HKEY& hh,
DWORD* dw)
{
return RegCreateKeyExA(h, k, 0, t, opts, sam, p, &hh, dw);
}
template<>
inline LONG CreateKey(
HKEY h,
const wchar_t* k,
wchar_t* t,
DWORD opts,
REGSAM sam,
LPSECURITY_ATTRIBUTES p,
HKEY& hh,
DWORD* dw)
{
return RegCreateKeyExW(h, k, 0, t, opts, sam, p, &hh, dw);
}
template<typename char_t>
LONG QueryValue(HKEY, const char_t*, DWORD&, BYTE*, DWORD&);
template<>
inline LONG QueryValue(
HKEY h,
const char* n,
DWORD& t,
BYTE* p,
DWORD& cb)
{
return RegQueryValueExA(h, n, 0, &t, p, &cb);
}
template<>
inline LONG QueryValue(
HKEY h,
const wchar_t* n,
DWORD& t,
BYTE* p,
DWORD& cb)
{
return RegQueryValueExW(h, n, 0, &t, p, &cb);
}
template<typename char_t>
LONG SetValue(HKEY, const char_t*, DWORD, const BYTE*, DWORD);
template<>
inline LONG SetValue(
HKEY h,
const char* n,
DWORD t,
const BYTE* p,
DWORD cb)
{
return RegSetValueExA(h, n, 0, t, p, cb);
}
template<>
inline LONG SetValue(
HKEY h,
const wchar_t* n,
DWORD t,
const BYTE* p,
DWORD cb)
{
return RegSetValueExW(h, n, 0, t, p, cb);
}
template<typename char_t>
LONG DeleteKey(HKEY, const char_t*);
template<>
inline LONG DeleteKey(HKEY h, const char* k)
{
return ::RegDeleteKeyA(h, k);
}
template<>
inline LONG DeleteKey(HKEY h, const wchar_t* k)
{
return ::RegDeleteKeyW(h, k);
}
template<typename char_t>
LONG DeleteKey(HKEY, const std::basic_string<char_t>&);
#ifndef NO_SHLWAPI_REG
//template<typename char_t>
//DWORD DeleteKeyAll(HKEY, const char_t*);
//
//template<>
//inline DWORD DeleteKeyAll(HKEY h, const char* k)
//{
// return ::SHDeleteKeyA(h, k);
//}
//template<>
//inline DWORD DeleteKeyAll(HKEY h, const wchar_t* k)
//{
// return ::SHDeleteKeyW(h, k);
//}
//template<typename char_t>
//DWORD DeleteKeyAll(HKEY, const std::basic_string<char_t>&);
//template<>
//inline DWORD DeleteKeyAll(HKEY h, const std::string& k)
//{
// return ::SHDeleteKeyA(h, k.c_str());
//}
//template<>
//inline DWORD DeleteKeyAll(HKEY h, const std::wstring& k)
//{
// return ::SHDeleteKeyW(h, k.c_str());
//}
inline DWORD SHDeleteKey(HKEY h, const std::string& k)
{
return ::SHDeleteKeyA(h, k.c_str());
}
inline DWORD SHDeleteKey(HKEY h, const std::wstring& k)
{
return ::SHDeleteKeyW(h, k.c_str());
}
#endif // NO_SHLWAPI_REG
}
inline Registry::Key::Key()
: m_hKey(0)
{
}
template<typename char_t>
inline Registry::Key::Key(HKEY hKey, const char_t* subkey, REGSAM sam)
: m_hKey(0)
{
OpenKey<char_t>(hKey, subkey, sam, m_hKey);
}
template<typename char_t>
inline Registry::Key::Key(
HKEY h,
const std::basic_string<char_t>& k,
REGSAM sam)
: m_hKey(0)
{
OpenKey<char_t>(h, k.c_str(), sam, m_hKey);
}
template<typename char_t>
inline LONG Registry::Key::open(
HKEY h,
const char_t* k,
REGSAM sam)
{
close();
return OpenKey<char_t>(h, k, sam, m_hKey);
}
inline Registry::Key::~Key()
{
close();
}
inline LONG Registry::Key::close()
{
if (m_hKey == 0)
return 0;
const LONG status = RegCloseKey(m_hKey);
m_hKey = 0;
return status;
}
inline bool Registry::Key::is_open() const
{
return (m_hKey != 0);
}
inline Registry::Key::operator HKEY() const
{
return m_hKey;
}
template<typename char_t>
inline LONG Registry::Key::create(
HKEY h,
const char_t* k,
DWORD* disposition)
{
close();
return CreateKey<char_t>(
h,
k,
0, //class (object type)
REG_OPTION_NON_VOLATILE, //options
KEY_ALL_ACCESS, //samDesired
0, //security attributes
m_hKey,
disposition);
}
template<typename char_t>
inline LONG Registry::Key::create(
HKEY parent,
const std::basic_string<char_t>& subkey,
DWORD* disposition)
{
return create(parent, subkey.c_str(), disposition);
}
template<typename char_t>
inline LONG Registry::Key::create(
HKEY hKey,
const char_t* subkey,
const char_t* const_object_type,
DWORD options,
REGSAM samDesired,
const SECURITY_ATTRIBUTES* const_security_attributes,
DWORD* disposition)
{
close();
char_t* const object_type = const_cast<char_t*>(const_object_type);
SECURITY_ATTRIBUTES* const security_attributes =
const_cast<SECURITY_ATTRIBUTES*>(const_security_attributes);
return CreateKey<char_t>(
hKey,
subkey,
object_type,
options,
samDesired,
security_attributes,
m_hKey,
disposition);
}
template<typename char_t>
inline LONG Registry::Key::set(
const char_t* name,
const std::basic_string<char_t>& str,
DWORD type) const
{
const char_t* const val = str.c_str();
const std::basic_string<char_t>::size_type len_ = str.length() + 1;
const DWORD len = static_cast<DWORD>(len_);
return setn<char_t>(name, val, len, type);
}
template<typename char_t>
inline LONG Registry::Key::open(
HKEY h,
const std::basic_string<char_t>& k,
REGSAM sam)
{
return open<char_t>(h, k.c_str(), sam);
}
//inline DWORD Registry::DeleteSubkey(
// HKEY hKey,
// const std::string& name)
//{
// return SH
//}
template<typename char_t>
inline LONG Registry::Key::query(const char_t* n, DWORD& data) const
{
DWORD type;
BYTE* const p = reinterpret_cast<BYTE*>(&data);
DWORD cb = sizeof data;
const LONG status = QueryValue<char_t>(m_hKey, n, type, p, cb);
if (status != ERROR_SUCCESS)
return status;
if (type != REG_DWORD)
return ERROR_FILE_NOT_FOUND;
//assert(cb == sizeof data);
return 0;
}
template<typename char_t>
inline LONG Registry::Key::query(
const char_t* name,
std::basic_string<char_t>& str,
DWORD type_) const
{
DWORD cb = 64;
for (;;)
{
//void* const buf_ = _alloca(cb);
//BYTE* const buf = static_cast<BYTE*>(buf_);
BYTE* const buf = new (std::nothrow) BYTE[cb];
if (buf == 0)
return ERROR_NOT_ENOUGH_MEMORY;
DWORD type;
const LONG status = QueryValue<char_t>(
m_hKey,
name,
type,
buf,
cb);
if (status == ERROR_SUCCESS)
{
if (type != type_)
{
delete[] buf;
return ERROR_FILE_NOT_FOUND;
}
if (cb % sizeof(char_t))
{
delete[] buf;
return ERROR_FILE_NOT_FOUND;
}
if (cb == 0)
{
str.clear();
delete[] buf;
return 0;
}
cb /= sizeof(char_t); //convert from bytes to chars
--cb; //convert from buflen to strlen
char_t* const val = (char_t*)buf;
if (val[cb]) //verify terminating null is present
{
delete[] buf;
return ERROR_FILE_NOT_FOUND;
}
str.assign(val, cb);
delete[] buf;
return 0;
}
delete[] buf;
if (status == ERROR_MORE_DATA)
continue;
return status;
}
}
template<typename char_t>
inline LONG Registry::Key::set(
const char_t* name,
DWORD value,
DWORD type) const
{
const BYTE* const p = reinterpret_cast<const BYTE*>(&value);
const DWORD cb = sizeof value;
return SetValue<char_t>(m_hKey, name, type, p, cb);
}
template<>
inline LONG Registry::Key::set(
const char* name,
const char* val,
DWORD type) const
{
const BYTE* const p = reinterpret_cast<const BYTE*>(val);
const size_t cb = val ? strlen(val) + 1 : 0;
return SetValue<char>(m_hKey, name, type, p, DWORD(cb));
}
template<>
inline LONG Registry::Key::set(
const wchar_t* name,
const wchar_t* val,
DWORD type) const
{
const BYTE* const p = reinterpret_cast<const BYTE*>(val);
const size_t len = val ? wcslen(val) + 1 : 0;
const size_t cb = len * sizeof(wchar_t);
return SetValue<wchar_t>(m_hKey, name, type, p, DWORD(cb));
}
template<>
inline LONG Registry::Key::setn(
const char* name,
const char* val,
DWORD cb,
DWORD type) const
{
const BYTE* const p = reinterpret_cast<const BYTE*>(val);
return SetValue<char>(m_hKey, name, type, p, cb);
}
template<>
inline LONG Registry::Key::setn(
const wchar_t* name,
const wchar_t* val,
DWORD length_including_null,
DWORD type) const
{
const BYTE* const p = reinterpret_cast<const BYTE*>(val);
const DWORD cb = length_including_null * sizeof(wchar_t);
return SetValue<wchar_t>(m_hKey, name, type, p, cb);
}