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