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