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

Unified Diff: src/shared/Registry.cpp

Issue 5171515343503360: Issue #41 - Bring method of determining IE version up to date (Closed)
Patch Set: reformatted Created July 26, 2014, 3:52 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/shared/Registry.h ('k') | test/RegistryTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/shared/Registry.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/shared/Registry.cpp
@@ -0,0 +1,90 @@
+#include "Registry.h"
+#include <memory>
+
+using namespace AdblockPlus;
+
+static HKEY predefined_hkeys[5] =
+{
+ HKEY_CLASSES_ROOT,
+ HKEY_CURRENT_CONFIG,
+ HKEY_CURRENT_USER,
+ HKEY_LOCAL_MACHINE,
+ HKEY_USERS
+};
+
+Registry_Key::Registry_Key(Predefined root, std::wstring key_name)
+ : is_predefined(key_name.empty())
+{
+ auto predefined_key(predefined_hkeys[(unsigned int) root ]);
+ if (is_predefined)
+ {
+ key = predefined_key;
+ return;
+ }
+ HRESULT hr = RegOpenKeyExW(predefined_key, key_name.c_str(), 0, KEY_QUERY_VALUE, &key);
+ if (hr != ERROR_SUCCESS || !key)
+ {
+ throw std::runtime_error("Failure in RegOpenKeyExW");
+ }
+}
+
+Registry_Key::Registry_Key(Predefined root)
+ : key(predefined_hkeys[(unsigned int) root ]), is_predefined(true)
+{
+}
+
+Registry_Key::~Registry_Key()
+{
+ if (!is_predefined)
+ {
+ RegCloseKey(key);
+ }
+}
+
+std::wstring Registry_Key::value_wstring(std::wstring name) const
+{
+ /*
+ * Step one is to determine the presence of the value, along with its type and byte size.
+ */
+ DWORD type;
+ DWORD size = 0;
+ HRESULT hr = ::RegQueryValueExW(static_cast<HKEY>(key), name.c_str(), 0, &type, 0, &size);
+ if (hr != ERROR_SUCCESS)
+ {
+ throw std::runtime_error("Failure in RegQueryValueEx to query name");
+ }
+ if (type != REG_SZ)
+ {
+ throw std::runtime_error("Value is not string type");
+ }
+
+ /*
+ * Step two is to allocate a buffer for the string and query for its value.
+ * Note that 'size' is the size in bytes, which we need for the system call,
+ * but that 'psize' is the size in words, which we need to manipulate the wchar_t array 'p'.
+ */
+ // Round the byte size up to the nearest multiple of two.
+ size = (size + 1) & ~ DWORD(1);
+ size_t psize = size >> 1;
+ // 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.
+ std::unique_ptr< wchar_t[] > p(new wchar_t[ psize ]);
+ hr = RegQueryValueExW(key, name.c_str(), 0, 0, reinterpret_cast<BYTE*>(p.get()), &size);
+ if (hr != ERROR_SUCCESS)
+ {
+ throw std::runtime_error("Failure in RegQueryValueExW to retrieve value");
+ }
+
+ /*
+ * Step three is to construct a return string.
+ *
+ * There's the possibility of an extra terminating null character in the return value of the query.
+ * If so, we have to decrement the length of the return value to eliminate it.
+ * If it persists, it will interfere with later string operations such as concatenation.
+ */
+ if (p[ psize - 1 ] == L'\0')
+ {
+ --psize;
+ }
+ return std::wstring(p.get(), psize);
+}
+
« no previous file with comments | « src/shared/Registry.h ('k') | test/RegistryTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld