Index: chrome_elf/nt_registry/nt_registry.cc |
diff --git a/chrome_elf/nt_registry/nt_registry.cc b/chrome_elf/nt_registry/nt_registry.cc |
index 4c65af8daff7c76ea5a9e4a0255da0225aeb58a4..58b0e9cd6fab5ad2035b10d736ebde2f93127251 100644 |
--- a/chrome_elf/nt_registry/nt_registry.cc |
+++ b/chrome_elf/nt_registry/nt_registry.cc |
@@ -565,19 +565,43 @@ NTSTATUS CreateKeyWrapper(const std::wstring& key_path, |
namespace nt { |
+ScopedHANDLE::ScopedHANDLE() : handle_(nullptr) {} |
+ |
+ScopedHANDLE::ScopedHANDLE(HANDLE handle) : handle_(handle) {} |
+ |
+ScopedHANDLE::~ScopedHANDLE() { |
+ if (!g_initialized) |
+ InitNativeRegApi(); |
+ if (is_valid()) |
+ g_nt_close(handle_); |
+} |
+ |
+bool ScopedHANDLE::is_valid() const { |
+ // This class should only be used for HANDLEs that have an invalid value of |
+ // nullptr. |
+ assert(handle_ != INVALID_HANDLE_VALUE); |
+ |
+ return handle_ != nullptr; |
+} |
+ |
+HANDLE ScopedHANDLE::release() { |
+ HANDLE result = handle_; |
+ handle_ = nullptr; |
+ return result; |
+} |
+ |
//------------------------------------------------------------------------------ |
// Create, open, delete, close functions |
//------------------------------------------------------------------------------ |
-bool CreateRegKey(ROOT_KEY root, |
- const wchar_t* key_path, |
- ACCESS_MASK access, |
- HANDLE* out_handle OPTIONAL) { |
+ScopedHANDLE CreateRegKey(ROOT_KEY root, |
+ const wchar_t* key_path, |
+ ACCESS_MASK access) { |
// |key_path| can be null or empty, but it can't be longer than |
// |g_kRegMaxPathLen| at this point. |
if (key_path != nullptr && |
::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
- return false; |
+ return ScopedHANDLE(); |
if (!g_initialized) |
InitNativeRegApi(); |
@@ -596,14 +620,14 @@ bool CreateRegKey(ROOT_KEY root, |
std::vector<std::wstring> subkeys; |
if (!ParseFullRegPath(ConvertRootKey(root), redirected_key_path, |
¤t_path, &subkeys)) |
- return false; |
+ return ScopedHANDLE(); |
// Open the base hive first. It should always exist already. |
- HANDLE last_handle = INVALID_HANDLE_VALUE; |
+ HANDLE last_handle = nullptr; |
NTSTATUS status = |
CreateKeyWrapper(current_path, access, &last_handle, nullptr); |
if (!NT_SUCCESS(status)) |
- return false; |
+ return ScopedHANDLE(); |
size_t subkeys_size = subkeys.size(); |
if (subkeys_size != 0) |
@@ -618,7 +642,7 @@ bool CreateRegKey(ROOT_KEY root, |
// Process the latest subkey. |
ULONG created = 0; |
- HANDLE key_handle = INVALID_HANDLE_VALUE; |
+ HANDLE key_handle = nullptr; |
status = |
CreateKeyWrapper(current_path.c_str(), access, &key_handle, &created); |
if (!NT_SUCCESS(status)) { |
@@ -648,35 +672,29 @@ bool CreateRegKey(ROOT_KEY root, |
g_nt_close(handle); |
} |
if (!success) |
- return false; |
- |
- // See if caller wants the handle left open. |
- if (out_handle) |
- *out_handle = last_handle; |
- else |
- g_nt_close(last_handle); |
+ return ScopedHANDLE(); |
- return true; |
+ return ScopedHANDLE(last_handle); |
} |
-bool OpenRegKey(ROOT_KEY root, |
- const wchar_t* key_path, |
- ACCESS_MASK access, |
- HANDLE* out_handle, |
- NTSTATUS* error_code OPTIONAL) { |
+ScopedHANDLE OpenRegKey(ROOT_KEY root, |
+ const wchar_t* key_path, |
+ ACCESS_MASK access, |
+ NTSTATUS* error_code OPTIONAL) { |
+ if (error_code) |
+ *error_code = STATUS_UNSUCCESSFUL; |
+ |
// |key_path| can be null or empty, but it can't be longer than |
// |g_kRegMaxPathLen| at this point. |
if (key_path != nullptr && |
::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
- return false; |
+ return ScopedHANDLE(); |
if (!g_initialized) |
InitNativeRegApi(); |
- NTSTATUS status = STATUS_UNSUCCESSFUL; |
UNICODE_STRING key_path_uni = {}; |
OBJECT_ATTRIBUTES obj = {}; |
- *out_handle = INVALID_HANDLE_VALUE; |
if (root == nt::AUTO) |
root = g_system_install ? nt::HKLM : nt::HKCU; |
@@ -693,53 +711,36 @@ bool OpenRegKey(ROOT_KEY root, |
InitializeObjectAttributes(&obj, &key_path_uni, OBJ_CASE_INSENSITIVE, NULL, |
NULL); |
- status = g_nt_open_key_ex(out_handle, access, &obj, 0); |
- // See if caller wants the NTSTATUS. |
- if (error_code) |
- *error_code = status; |
+ HANDLE result_handle = nullptr; |
+ NTSTATUS status = g_nt_open_key_ex(&result_handle, access, &obj, 0); |
- if (NT_SUCCESS(status)) |
- return true; |
+ if (!NT_SUCCESS(status)) { |
+ // See if caller wants the NTSTATUS. |
+ if (error_code) |
+ *error_code = status; |
+ return ScopedHANDLE(); |
+ } |
- return false; |
+ return ScopedHANDLE(result_handle); |
} |
bool DeleteRegKey(HANDLE key) { |
if (!g_initialized) |
InitNativeRegApi(); |
- NTSTATUS status = STATUS_UNSUCCESSFUL; |
- |
- status = g_nt_delete_key(key); |
- |
- if (NT_SUCCESS(status)) |
- return true; |
- |
- return false; |
+ return NT_SUCCESS(g_nt_delete_key(key)); |
} |
// wrapper function |
bool DeleteRegKey(ROOT_KEY root, |
WOW64_OVERRIDE wow64_override, |
const wchar_t* key_path) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, DELETE | wow64_override, &key, nullptr)) |
- return false; |
- |
- if (!DeleteRegKey(key)) { |
- CloseRegKey(key); |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, DELETE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- } |
- CloseRegKey(key); |
- return true; |
-} |
- |
-void CloseRegKey(HANDLE key) { |
- if (!g_initialized) |
- InitNativeRegApi(); |
- g_nt_close(key); |
+ return DeleteRegKey(key.get()); |
} |
//------------------------------------------------------------------------------ |
@@ -810,18 +811,12 @@ bool QueryRegValueDWORD(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
DWORD* out_dword) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!QueryRegValueDWORD(key, value_name, out_dword)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- CloseRegKey(key); |
- return true; |
+ return QueryRegValueDWORD(key.get(), value_name, out_dword); |
} |
// wrapper function |
@@ -833,8 +828,9 @@ bool QueryRegValueSZ(HANDLE key, |
ULONG type = REG_NONE; |
if (!QueryRegKeyValue(key, value_name, &type, &value_bytes, &ret_size) || |
- type != REG_SZ) |
+ type != REG_SZ) { |
return false; |
+ } |
*out_sz = reinterpret_cast<wchar_t*>(value_bytes); |
@@ -848,18 +844,12 @@ bool QueryRegValueSZ(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
std::wstring* out_sz) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!QueryRegValueSZ(key, value_name, out_sz)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- CloseRegKey(key); |
- return true; |
+ return QueryRegValueSZ(key.get(), value_name, out_sz); |
} |
// wrapper function |
@@ -902,18 +892,12 @@ bool QueryRegValueMULTISZ(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
std::vector<std::wstring>* out_multi_sz) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!QueryRegValueMULTISZ(key, value_name, out_multi_sz)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- CloseRegKey(key); |
- return true; |
+ return QueryRegValueMULTISZ(key.get(), value_name, out_multi_sz); |
} |
//------------------------------------------------------------------------------ |
@@ -954,17 +938,12 @@ bool SetRegValueDWORD(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
DWORD value) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!SetRegValueDWORD(key, value_name, value)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- return true; |
+ return SetRegValueDWORD(key.get(), value_name, value); |
} |
// wrapper function |
@@ -987,17 +966,12 @@ bool SetRegValueSZ(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
const std::wstring& value) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!SetRegValueSZ(key, value_name, value)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- return true; |
+ return SetRegValueSZ(key.get(), value_name, value); |
} |
// wrapper function |
@@ -1037,17 +1011,12 @@ bool SetRegValueMULTISZ(ROOT_KEY root, |
const wchar_t* key_path, |
const wchar_t* value_name, |
const std::vector<std::wstring>& values) { |
- HANDLE key = INVALID_HANDLE_VALUE; |
- |
- if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) |
+ ScopedHANDLE key = |
+ OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
+ if (!key.is_valid()) |
return false; |
- if (!SetRegValueMULTISZ(key, value_name, values)) { |
- CloseRegKey(key); |
- return false; |
- } |
- |
- return true; |
+ return SetRegValueMULTISZ(key.get(), value_name, values); |
} |
//------------------------------------------------------------------------------ |