OLD | NEW |
(Empty) | |
| 1 #include "Registry.h" |
| 2 #include <memory> |
| 3 |
| 4 using namespace AdblockPlus; |
| 5 |
| 6 static HKEY predefined_hkeys[5] = |
| 7 { |
| 8 HKEY_CLASSES_ROOT, |
| 9 HKEY_CURRENT_CONFIG, |
| 10 HKEY_CURRENT_USER, |
| 11 HKEY_LOCAL_MACHINE, |
| 12 HKEY_USERS |
| 13 }; |
| 14 |
| 15 Registry_Key::Registry_Key( Predefined root, std::wstring key_name ) |
| 16 : is_predefined( key_name.empty() ) |
| 17 { |
| 18 auto predefined_key( predefined_hkeys[ (unsigned int) root ] ); |
| 19 if ( is_predefined ) |
| 20 { |
| 21 key = predefined_key; |
| 22 return; |
| 23 } |
| 24 HRESULT hr = RegOpenKeyExW( predefined_key, key_name.c_str(), 0, KEY_QUERY_VAL
UE, &key ); |
| 25 if ( hr != ERROR_SUCCESS || !key ) |
| 26 { |
| 27 throw std::runtime_error( "Failure in RegOpenKeyExW" ); |
| 28 } |
| 29 } |
| 30 |
| 31 Registry_Key::Registry_Key( Predefined root ) |
| 32 : key( predefined_hkeys[ (unsigned int) root ] ), is_predefined( true ) |
| 33 { |
| 34 } |
| 35 |
| 36 Registry_Key::~Registry_Key() |
| 37 { |
| 38 if ( !is_predefined ) |
| 39 { |
| 40 RegCloseKey( key ); |
| 41 } |
| 42 } |
| 43 |
| 44 std::wstring Registry_Key::value_wstring( std::wstring name ) const |
| 45 { |
| 46 /* |
| 47 * Step one is to determine the presence of the value, along with its type and
byte size. |
| 48 */ |
| 49 DWORD type; |
| 50 DWORD size = 0; |
| 51 HRESULT hr = ::RegQueryValueExW( static_cast<HKEY>( key ), name.c_str(), 0, &t
ype, 0, &size ); |
| 52 if ( hr != ERROR_SUCCESS ) |
| 53 { |
| 54 throw std::runtime_error( "Failure in RegQueryValueEx to query name" ); |
| 55 } |
| 56 if ( type != REG_SZ ) |
| 57 { |
| 58 throw std::runtime_error( "Value is not string type" ); |
| 59 } |
| 60 |
| 61 /* |
| 62 * Step two is to allocate a buffer for the string and query for its value. |
| 63 * Note that 'size' is the size in bytes, which we need for the system call, |
| 64 * but that 'psize' is the size in words, which we need to manipulate the wc
har_t array 'p'. |
| 65 */ |
| 66 // Round the byte size up to the nearest multiple of two. |
| 67 size = ( size + 1 ) & ~ DWORD(1); |
| 68 size_t psize = size >> 1; |
| 69 // We need to allocate a temporary buffer to receive the value, because there'
s no interface to write directly into the buffer of std::basic_string. |
| 70 std::unique_ptr< wchar_t[] > p( new wchar_t[ psize ] ); |
| 71 hr = RegQueryValueExW( key, name.c_str(), 0, 0, reinterpret_cast<BYTE *>( p.ge
t() ), &size ); |
| 72 if ( hr != ERROR_SUCCESS ) |
| 73 { |
| 74 throw std::runtime_error( "Failure in RegQueryValueExW to retrieve value" ); |
| 75 } |
| 76 |
| 77 /* |
| 78 * Step three is to construct a return string. |
| 79 * |
| 80 * There's the possibility of an extra terminating null character in the retur
n value of the query. |
| 81 * If so, we have to decrement the length of the return value to eliminate it. |
| 82 * If it persists, it will interfere with later string operations such as conc
atenation. |
| 83 */ |
| 84 if ( p[ psize - 1 ] == L'\0' ) |
| 85 { |
| 86 --psize; |
| 87 } |
| 88 return std::wstring( p.get(), psize ); |
| 89 } |
| 90 |
| 91 |
OLD | NEW |