| LEFT | RIGHT | 
|---|
| 1 #include "Registry.h" | 1 #include "Registry.h" | 
| 2 #include <memory> | 2 #include <memory> | 
| 3 | 3 | 
| 4 using namespace AdblockPlus; | 4 using namespace AdblockPlus; | 
| 5 | 5 | 
| 6 Registry_Key::Registry_Key(HKEY parent, const std::wstring& key_name) | 6 RegistryKey::RegistryKey(HKEY parent, const std::wstring& key_name) | 
| 7 { | 7 { | 
| 8   if (key_name.empty()) | 8   if (key_name.empty()) | 
| 9   { | 9   { | 
| 10     throw std::runtime_error("key_name may not be empty"); | 10     throw std::runtime_error("key_name may not be empty"); | 
| 11   } | 11   } | 
| 12   HRESULT hr = RegOpenKeyExW(parent, key_name.c_str(), 0, KEY_QUERY_VALUE, &key)
    ; | 12   HRESULT hr = RegOpenKeyExW(parent, key_name.c_str(), 0, KEY_QUERY_VALUE, &key)
    ; | 
| 13   if (hr != ERROR_SUCCESS || !key) | 13   if (hr != ERROR_SUCCESS || !key) | 
| 14   { | 14   { | 
| 15     throw std::runtime_error("Failure in RegOpenKeyExW"); | 15     throw std::runtime_error("Failure in RegOpenKeyExW"); | 
| 16   } | 16   } | 
| 17 } | 17 } | 
| 18 | 18 | 
| 19 Registry_Key::~Registry_Key() | 19 RegistryKey::~RegistryKey() | 
| 20 { | 20 { | 
| 21   RegCloseKey(key); | 21   RegCloseKey(key); | 
| 22 } | 22 } | 
| 23 | 23 | 
| 24 std::wstring Registry_Key::value_wstring(const std::wstring& name) const | 24 std::wstring RegistryKey::value_wstring(const std::wstring& name) const | 
| 25 { | 25 { | 
| 26   /* | 26   /* | 
| 27    * Step one is to determine the presence of the value, along with its type and
     byte size. | 27    * Step one is to determine the presence of the value, along with its type and
     byte size. | 
| 28    */ | 28    */ | 
| 29   DWORD type; | 29   DWORD type; | 
| 30   DWORD size = 0; | 30   DWORD size = 0; | 
| 31   HRESULT hr = ::RegQueryValueExW(static_cast<HKEY>(key), name.c_str(), 0, &type
    , 0, &size); | 31   HRESULT hr = ::RegQueryValueExW(static_cast<HKEY>(key), name.c_str(), 0, &type
    , 0, &size); | 
| 32   if (hr != ERROR_SUCCESS) | 32   if (hr != ERROR_SUCCESS) | 
| 33   { | 33   { | 
| 34     throw std::runtime_error("Failure in RegQueryValueEx to query name"); | 34     throw std::runtime_error("Failure in RegQueryValueEx to query name"); | 
| 35   } | 35   } | 
| 36   if (type != REG_SZ) | 36   if (type != REG_SZ) | 
| 37   { | 37   { | 
| 38     throw std::runtime_error("Value is not string type"); | 38     throw std::runtime_error("Value is not string type"); | 
| 39   } | 39   } | 
| 40 | 40 | 
| 41   /* | 41   /* | 
| 42    * Step two is to allocate a buffer for the string and query for its value. | 42    * Step two is to allocate a buffer for the string and query for its value. | 
| 43    * Note that 'size' is the size in bytes, which we need for the system call, | 43    * Note that 'size' is the size in bytes, which we need for the system call, | 
| 44    *   but that 'psize' is the size in words, which we need to manipulate the wc
    har_t array 'p'. | 44    *   but that 'psize' is the size in words, which we need to manipulate the wc
    har_t array 'p'. | 
| 45    */ | 45    */ | 
|  | 46   size_t psize = (size + 1)/2; | 
| 46   // Round the byte size up to the nearest multiple of two. | 47   // Round the byte size up to the nearest multiple of two. | 
| 47   size = (size + 1) & ~ DWORD(1); | 48   size = 2 * psize; | 
| 48   size_t psize = size >> 1; |  | 
| 49   // 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. | 49   // 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. | 
| 50   std::unique_ptr< wchar_t[] > p(new wchar_t[psize]); | 50   std::unique_ptr<wchar_t[]> p(new wchar_t[psize]); | 
| 51   hr = RegQueryValueExW(key, name.c_str(), 0, 0, reinterpret_cast<BYTE*>(p.get()
    ), &size); | 51   hr = RegQueryValueExW(key, name.c_str(), 0, 0, reinterpret_cast<BYTE*>(p.get()
    ), &size); | 
| 52   if (hr != ERROR_SUCCESS) | 52   if (hr != ERROR_SUCCESS) | 
| 53   { | 53   { | 
| 54     throw std::runtime_error("Failure in RegQueryValueExW to retrieve value"); | 54     throw std::runtime_error("Failure in RegQueryValueExW to retrieve value"); | 
| 55   } | 55   } | 
| 56 | 56 | 
| 57   /* | 57   /* | 
| 58    * Step three is to construct a return string. | 58    * Step three is to construct a return string. | 
| 59    * | 59    * | 
| 60    * There's the possibility of an extra terminating null character in the retur
    n value of the query. | 60    * There's the possibility of an extra terminating null character in the retur
    n value of the query. | 
| 61    * If so, we have to decrement the length of the return value to eliminate it. | 61    * If so, we have to decrement the length of the return value to eliminate it. | 
| 62    * If it persists, it will interfere with later string operations such as conc
    atenation. | 62    * If it persists, it will interfere with later string operations such as conc
    atenation. | 
| 63    */ | 63    */ | 
| 64   if (p[psize - 1] == L'\0') | 64   if (p[psize - 1] == L'\0') | 
| 65   { | 65   { | 
| 66     --psize; | 66     --psize; | 
| 67   } | 67   } | 
| 68   return std::wstring(p.get(), psize); | 68   return std::wstring(p.get(), psize); | 
| 69 } | 69 } | 
| 70 | 70 | 
| LEFT | RIGHT | 
|---|