From a83588f18dc90d2a317d7d43d933a8fbc757d815 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 3 Nov 2024 15:16:36 +0100 Subject: [PATCH] Cleanup hive parser --- src/windows-emulator/registry/hive_parser.cpp | 71 ++++++------------- .../registry/registry_manager.cpp | 9 ++- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/windows-emulator/registry/hive_parser.cpp b/src/windows-emulator/registry/hive_parser.cpp index bd88b492..425d1415 100644 --- a/src/windows-emulator/registry/hive_parser.cpp +++ b/src/windows-emulator/registry/hive_parser.cpp @@ -51,7 +51,7 @@ namespace char name[255]; }; - bool read_file_data(std::ifstream& file, const uint64_t offset, void* buffer, const size_t size) + bool read_file_data_safe(std::ifstream& file, const uint64_t offset, void* buffer, const size_t size) { if (file.bad()) { @@ -77,17 +77,21 @@ namespace return file.good(); } + void read_file_data(std::ifstream& file, const uint64_t offset, void* buffer, const size_t size) + { + if (!read_file_data_safe(file, offset, buffer, size)) + { + throw std::runtime_error("Failed to read file data"); + } + } + std::vector read_file_data(std::ifstream& file, const uint64_t offset, const size_t size) { std::vector result{}; result.resize(size); - if (read_file_data(file, offset, result.data(), size)) - { - return result; - } - - return {}; + read_file_data(file, offset, result.data(), size); + return result; } std::string read_file_data_string(std::ifstream& file, const uint64_t offset, const size_t size) @@ -95,38 +99,17 @@ namespace std::string result{}; result.resize(size); - if (read_file_data(file, offset, result.data(), size)) - { - return result; - } - - return {}; + read_file_data(file, offset, result.data(), size); + return result; } template requires(std::is_trivially_copyable_v) - std::optional read_file_object(std::ifstream& file, const uint64_t offset, const size_t array_index = 0) + T read_file_object(std::ifstream& file, const uint64_t offset, const size_t array_index = 0) { T obj{}; - if (read_file_data(file, offset + (array_index * sizeof(T)), &obj, sizeof(T))) - { - return {std::move(obj)}; - } - - return std::nullopt; - } - - template - requires(std::is_trivially_copyable_v) - T read_file_object_or_throw(std::ifstream& file, const uint64_t offset, const size_t array_index = 0) - { - auto result = read_file_object(file, offset, array_index); - if (!result) - { - throw std::runtime_error("Failed to read file object"); - } - - return std::move(*result); + read_file_data(file, offset + (array_index * sizeof(T)), &obj, sizeof(T)); + return obj; } hive_key parse_root_block(std::ifstream& file, const std::filesystem::path& file_path) @@ -136,7 +119,7 @@ namespace throw std::runtime_error("Bad hive file: " + file_path.string()); } - const auto key_block = read_file_object_or_throw(file, MAIN_KEY_BLOCK_OFFSET); + const auto key_block = read_file_object(file, MAIN_KEY_BLOCK_OFFSET); return {key_block.subkeys, key_block.value_count, key_block.offsets}; } @@ -145,16 +128,6 @@ namespace { return static_cast(std::tolower(static_cast(val))); } - - bool ichar_equals(const char a, const char b) - { - return char_to_lower(a) == char_to_lower(b); - } - - bool iequals(std::string_view lhs, std::string_view rhs) - { - return std::ranges::equal(lhs, rhs, ichar_equals); - } } const hive_value* hive_key::get_value(std::ifstream& file, const std::string_view name) @@ -191,8 +164,8 @@ void hive_key::parse(std::ifstream& file) for (auto i = 0; i < this->value_count_; i++) { - const auto offset = read_file_object_or_throw(file, MAIN_ROOT_OFFSET + this->value_offsets_ + 4, i); - const auto value = read_file_object_or_throw(file, MAIN_ROOT_OFFSET + offset); + const auto offset = read_file_object(file, MAIN_ROOT_OFFSET + this->value_offsets_ + 4, i); + const auto value = read_file_object(file, MAIN_ROOT_OFFSET + offset); std::string value_name(value.name, std::min(value.name_len, static_cast(sizeof(value.name)))); @@ -214,7 +187,7 @@ void hive_key::parse(std::ifstream& file) // Subkeys - const auto item = read_file_object_or_throw(file, MAIN_ROOT_OFFSET + this->subkey_block_offset_); + const auto item = read_file_object(file, MAIN_ROOT_OFFSET + this->subkey_block_offset_); if (item.block_type[1] != 'f' && item.block_type[1] != 'h') { @@ -225,10 +198,10 @@ void hive_key::parse(std::ifstream& file) for (short i = 0; i < item.count; ++i) { - const auto offset_entry = read_file_object_or_throw(file, MAIN_ROOT_OFFSET + entry_offsets, i); + const auto offset_entry = read_file_object(file, MAIN_ROOT_OFFSET + entry_offsets, i); const auto subkey_block_offset = MAIN_ROOT_OFFSET + offset_entry.offset; - const auto subkey = read_file_object_or_throw(file, subkey_block_offset); + const auto subkey = read_file_object(file, subkey_block_offset); std::string subkey_name(subkey.name, std::min(subkey.len, static_cast(sizeof(subkey.name)))); std::ranges::transform(subkey_name, subkey_name.begin(), char_to_lower); diff --git a/src/windows-emulator/registry/registry_manager.cpp b/src/windows-emulator/registry/registry_manager.cpp index 8ff8a610..a5440b97 100644 --- a/src/windows-emulator/registry/registry_manager.cpp +++ b/src/windows-emulator/registry/registry_manager.cpp @@ -33,7 +33,14 @@ namespace void register_hive(registry_manager::hive_map& hives, const std::filesystem::path& key, const std::filesystem::path& file) { - hives[canonicalize_path(key)] = std::make_unique(file); + try + { + hives[canonicalize_path(key)] = std::make_unique(file); + } + catch (const std::exception& e) + { + + } } }