Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: src/shared/Registry.cpp

Issue 5171515343503360: Issue #41 - Bring method of determining IE version up to date (Closed)
Left Patch Set: reformatted Created July 26, 2014, 3:52 p.m.
Right Patch Set: Final (?) 2 Created Jan. 5, 2015, 1:02 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
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 static HKEY predefined_hkeys[5] = 6 RegistryKey::RegistryKey(HKEY parent, const std::wstring& key_name)
7 { 7 {
8 HKEY_CLASSES_ROOT, 8 if (key_name.empty())
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 { 9 {
21 key = predefined_key; 10 throw std::runtime_error("key_name may not be empty");
22 return;
23 } 11 }
24 HRESULT hr = RegOpenKeyExW(predefined_key, key_name.c_str(), 0, KEY_QUERY_VALU E, &key); 12 HRESULT hr = RegOpenKeyExW(parent, key_name.c_str(), 0, KEY_QUERY_VALUE, &key) ;
25 if (hr != ERROR_SUCCESS || !key) 13 if (hr != ERROR_SUCCESS || !key)
26 { 14 {
27 throw std::runtime_error("Failure in RegOpenKeyExW"); 15 throw std::runtime_error("Failure in RegOpenKeyExW");
28 } 16 }
29 } 17 }
30 18
31 Registry_Key::Registry_Key(Predefined root) 19 RegistryKey::~RegistryKey()
32 : key(predefined_hkeys[(unsigned int) root ]), is_predefined(true)
33 { 20 {
21 RegCloseKey(key);
34 } 22 }
35 23
36 Registry_Key::~Registry_Key() 24 std::wstring RegistryKey::value_wstring(const std::wstring& name) const
37 {
38 if (!is_predefined)
39 {
40 RegCloseKey(key);
41 }
42 }
43
44 std::wstring Registry_Key::value_wstring(std::wstring name) const
45 { 25 {
46 /* 26 /*
47 * 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.
48 */ 28 */
49 DWORD type; 29 DWORD type;
50 DWORD size = 0; 30 DWORD size = 0;
51 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);
52 if (hr != ERROR_SUCCESS) 32 if (hr != ERROR_SUCCESS)
53 { 33 {
54 throw std::runtime_error("Failure in RegQueryValueEx to query name"); 34 throw std::runtime_error("Failure in RegQueryValueEx to query name");
55 } 35 }
56 if (type != REG_SZ) 36 if (type != REG_SZ)
57 { 37 {
58 throw std::runtime_error("Value is not string type"); 38 throw std::runtime_error("Value is not string type");
59 } 39 }
60 40
61 /* 41 /*
62 * 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.
63 * 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,
64 * 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'.
65 */ 45 */
46 size_t psize = (size + 1)/2;
66 // Round the byte size up to the nearest multiple of two. 47 // Round the byte size up to the nearest multiple of two.
67 size = (size + 1) & ~ DWORD(1); 48 size = 2 * psize;
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. 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.
70 std::unique_ptr< wchar_t[] > p(new wchar_t[ psize ]); 50 std::unique_ptr<wchar_t[]> p(new wchar_t[psize]);
71 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);
72 if (hr != ERROR_SUCCESS) 52 if (hr != ERROR_SUCCESS)
73 { 53 {
74 throw std::runtime_error("Failure in RegQueryValueExW to retrieve value"); 54 throw std::runtime_error("Failure in RegQueryValueExW to retrieve value");
75 } 55 }
76 56
77 /* 57 /*
78 * Step three is to construct a return string. 58 * Step three is to construct a return string.
79 * 59 *
80 * 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.
81 * 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.
82 * 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.
83 */ 63 */
84 if (p[ psize - 1 ] == L'\0') 64 if (p[psize - 1] == L'\0')
85 { 65 {
86 --psize; 66 --psize;
87 } 67 }
88 return std::wstring(p.get(), psize); 68 return std::wstring(p.get(), psize);
89 } 69 }
90 70
LEFTRIGHT

Powered by Google App Engine
This is Rietveld