From 6c2a6ff872e7dc8674ed7cd87f4843cee6bdd8ba Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 13 Jan 2025 07:03:56 +0100 Subject: [PATCH 1/3] Prepare android support --- src/emulator/serialization.hpp | 1 + src/windows-emulator/registry/registry_manager.cpp | 6 +++--- src/windows-emulator/registry/registry_manager.hpp | 4 ++-- src/windows-emulator/std_include.hpp | 2 ++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/emulator/serialization.hpp b/src/emulator/serialization.hpp index e8eee856..7f6adf37 100644 --- a/src/emulator/serialization.hpp +++ b/src/emulator/serialization.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/src/windows-emulator/registry/registry_manager.cpp b/src/windows-emulator/registry/registry_manager.cpp index ad5c7801..963a4f2d 100644 --- a/src/windows-emulator/registry/registry_manager.cpp +++ b/src/windows-emulator/registry/registry_manager.cpp @@ -32,7 +32,7 @@ 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); + hives[canonicalize_path(key).u16string()] = std::make_unique(file); } } @@ -95,7 +95,7 @@ std::filesystem::path registry_manager::normalize_path(const std::filesystem::pa void registry_manager::add_path_mapping(const std::filesystem::path& key, const std::filesystem::path& value) { - this->path_mapping_[canonicalize_path(key)] = canonicalize_path(value); + this->path_mapping_[canonicalize_path(key).u16string()] = canonicalize_path(value); } std::optional registry_manager::get_key(const std::filesystem::path& key) @@ -137,7 +137,7 @@ std::optional registry_manager::get_value(const registry_key& ke { utils::string::to_lower_inplace(name); - const auto iterator = this->hives_.find(key.hive); + const auto iterator = this->hives_.find(key.hive.u16string()); if (iterator == this->hives_.end()) { return std::nullopt; diff --git a/src/windows-emulator/registry/registry_manager.hpp b/src/windows-emulator/registry/registry_manager.hpp index 0c14d79c..a07c8947 100644 --- a/src/windows-emulator/registry/registry_manager.hpp +++ b/src/windows-emulator/registry/registry_manager.hpp @@ -33,7 +33,7 @@ class registry_manager { public: using hive_ptr = std::unique_ptr; - using hive_map = std::unordered_map; + using hive_map = std::unordered_map; registry_manager(); registry_manager(const std::filesystem::path& hive_path); @@ -54,7 +54,7 @@ class registry_manager private: std::filesystem::path hive_path_{}; hive_map hives_{}; - std::unordered_map path_mapping_{}; + std::unordered_map path_mapping_{}; std::filesystem::path normalize_path(const std::filesystem::path& path) const; void add_path_mapping(const std::filesystem::path& key, const std::filesystem::path& value); diff --git a/src/windows-emulator/std_include.hpp b/src/windows-emulator/std_include.hpp index 55d332a4..4a6c82b2 100644 --- a/src/windows-emulator/std_include.hpp +++ b/src/windows-emulator/std_include.hpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ #include #include #include +#include #include #include From fa5cc9c049071202eef705ac31966e7fb7526139 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 13 Jan 2025 07:49:05 +0100 Subject: [PATCH 2/3] Add android build --- .github/workflows/build.yml | 23 +++++++++++++++++++++++ cmake/toolchain/android-ndk.cmake | 6 ++++++ 2 files changed, 29 insertions(+) create mode 100644 cmake/toolchain/android-ndk.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d080f82d..c89248fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,6 +56,8 @@ jobs: - Linux GCC - Linux Clang - macOS + - Android x86_64 + - Android arm64-v8a configuration: - Debug - Release @@ -73,6 +75,12 @@ jobs: clang-version: 18 - platform: macOS runner: macos-latest + - platform: Android x86_64 + runner: ubuntu-24.04 + abi: x86_64 + - platform: Android arm64-v8a + runner: ubuntu-24.04 + abi: arm64-v8a steps: - name: Checkout Source uses: actions/checkout@v4 @@ -100,8 +108,23 @@ jobs: uses: ilammy/msvc-dev-cmd@v1.13.0 if: "${{ matrix.platform == 'Windows' }}" + - uses: nttld/setup-ndk@v1 + id: setup-ndk + if: ${{ startsWith(matrix.platform, 'Android') }} + with: + ndk-version: r26d + add-to-path: false + + - name: CMake Build + run: cmake --preset=${{matrix.preset}} -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/toolchain/android-ndk.cmake && cmake --build --preset=${{matrix.preset}} + if: ${{ startsWith(matrix.platform, 'Android') }} + env: + ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} + ANDROID_ABI: ${{matrix.abi}} + - name: CMake Build run: cmake --workflow --preset=${{matrix.preset}} + if: ${{ !startsWith(matrix.platform, 'Android') }} - name: Upload Artifacts uses: actions/upload-artifact@v4 diff --git a/cmake/toolchain/android-ndk.cmake b/cmake/toolchain/android-ndk.cmake new file mode 100644 index 00000000..fee20245 --- /dev/null +++ b/cmake/toolchain/android-ndk.cmake @@ -0,0 +1,6 @@ +set(CMAKE_SYSTEM_NAME "Android") +set(CMAKE_ANDROID_NDK "$ENV{ANDROID_NDK_ROOT}") + +set(ANDROID_ABI "$ENV{ANDROID_ABI}") +set(CMAKE_ANDROID_ARCH_ABI "${ANDROID_ABI}") +set(CMAKE_ANDROID_API "24") \ No newline at end of file From b76dc7cf244f316874485b96a192cd61efc9961a Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 13 Jan 2025 19:00:01 +0100 Subject: [PATCH 3/3] Introduce path_key util It represents a canonical path that can be used as key for unordered containers --- src/common/utils/path_key.hpp | 61 +++++++++++++++++++ src/emulator/serialization_helper.hpp | 11 ++++ .../registry/registry_manager.cpp | 24 +++----- .../registry/registry_manager.hpp | 6 +- 4 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 src/common/utils/path_key.hpp diff --git a/src/common/utils/path_key.hpp b/src/common/utils/path_key.hpp new file mode 100644 index 00000000..6165393e --- /dev/null +++ b/src/common/utils/path_key.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include "string.hpp" +#include + +namespace utils +{ + class path_key + { + public: + path_key() = default; + path_key(const std::filesystem::path& p) + : path_(canonicalize_path(p)) + { + } + + path_key(const path_key&) = default; + path_key(path_key&&) noexcept = default; + + path_key& operator=(const path_key&) = default; + path_key& operator=(path_key&&) noexcept = default; + + ~path_key() = default; + + const std::filesystem::path& get() const + { + return this->path_; + } + + bool operator==(const path_key& other) const + { + return this->get() == other.get(); + } + + bool operator!=(const path_key& other) const + { + return !this->operator==(other); + } + + static std::filesystem::path canonicalize_path(const std::filesystem::path& key) + { + auto path = key.lexically_normal().wstring(); + return utils::string::to_lower_consume(path); + } + + private: + std::filesystem::path path_{}; + }; +} + +namespace std +{ + template <> + struct hash + { + size_t operator()(const utils::path_key& p) const noexcept + { + return hash()(p.get().native()); + } + }; +} diff --git a/src/emulator/serialization_helper.hpp b/src/emulator/serialization_helper.hpp index 021855ef..2085ace2 100644 --- a/src/emulator/serialization_helper.hpp +++ b/src/emulator/serialization_helper.hpp @@ -4,6 +4,7 @@ #include #include +#include namespace utils { @@ -44,4 +45,14 @@ namespace utils { path = buffer.read_string(); } + + inline void serialize(buffer_serializer& buffer, const path_key& path) + { + buffer.write(path.get()); + } + + inline void deserialize(buffer_deserializer& buffer, path_key& path) + { + path = buffer.read(); + } } diff --git a/src/windows-emulator/registry/registry_manager.cpp b/src/windows-emulator/registry/registry_manager.cpp index 963a4f2d..62adfe1b 100644 --- a/src/windows-emulator/registry/registry_manager.cpp +++ b/src/windows-emulator/registry/registry_manager.cpp @@ -7,12 +7,6 @@ namespace { - std::filesystem::path canonicalize_path(const std::filesystem::path& key) - { - auto path = key.lexically_normal().wstring(); - return utils::string::to_lower_consume(path); - } - bool is_subpath(const std::filesystem::path& root, const std::filesystem::path& p) { auto root_it = root.begin(); @@ -32,7 +26,7 @@ namespace void register_hive(registry_manager::hive_map& hives, const std::filesystem::path& key, const std::filesystem::path& file) { - hives[canonicalize_path(key).u16string()] = std::make_unique(file); + hives[key] = std::make_unique(file); } } @@ -80,22 +74,22 @@ void registry_manager::deserialize(utils::buffer_deserializer& buffer) std::filesystem::path registry_manager::normalize_path(const std::filesystem::path& path) const { - auto canonical_path = canonicalize_path(path); + const utils::path_key canonical_path = path; for (const auto& mapping : this->path_mapping_) { - if (is_subpath(mapping.first, canonical_path)) + if (is_subpath(mapping.first.get(), canonical_path.get())) { - return mapping.second / canonical_path.lexically_relative(mapping.first); + return mapping.second.get() / canonical_path.get().lexically_relative(mapping.first.get()); } } - return canonical_path; + return canonical_path.get(); } void registry_manager::add_path_mapping(const std::filesystem::path& key, const std::filesystem::path& value) { - this->path_mapping_[canonicalize_path(key).u16string()] = canonicalize_path(value); + this->path_mapping_[key] = value; } std::optional registry_manager::get_key(const std::filesystem::path& key) @@ -116,7 +110,7 @@ std::optional registry_manager::get_key(const std::filesystem::pat } registry_key reg_key{}; - reg_key.hive = iterator->first; + reg_key.hive = iterator->first.get(); reg_key.path = normal_key.lexically_relative(reg_key.hive); if (reg_key.path.empty()) @@ -137,7 +131,7 @@ std::optional registry_manager::get_value(const registry_key& ke { utils::string::to_lower_inplace(name); - const auto iterator = this->hives_.find(key.hive.u16string()); + const auto iterator = this->hives_.find(key.hive); if (iterator == this->hives_.end()) { return std::nullopt; @@ -161,7 +155,7 @@ registry_manager::hive_map::iterator registry_manager::find_hive(const std::file { for (auto i = this->hives_.begin(); i != this->hives_.end(); ++i) { - if (is_subpath(i->first, key)) + if (is_subpath(i->first.get(), key)) { return i; } diff --git a/src/windows-emulator/registry/registry_manager.hpp b/src/windows-emulator/registry/registry_manager.hpp index a07c8947..1e598ac6 100644 --- a/src/windows-emulator/registry/registry_manager.hpp +++ b/src/windows-emulator/registry/registry_manager.hpp @@ -1,8 +1,8 @@ #pragma once #include "../std_include.hpp" -#include #include "hive_parser.hpp" +#include "serialization_helper.hpp" struct registry_key { @@ -33,7 +33,7 @@ class registry_manager { public: using hive_ptr = std::unique_ptr; - using hive_map = std::unordered_map; + using hive_map = std::unordered_map; registry_manager(); registry_manager(const std::filesystem::path& hive_path); @@ -54,7 +54,7 @@ class registry_manager private: std::filesystem::path hive_path_{}; hive_map hives_{}; - std::unordered_map path_mapping_{}; + std::unordered_map path_mapping_{}; std::filesystem::path normalize_path(const std::filesystem::path& path) const; void add_path_mapping(const std::filesystem::path& key, const std::filesystem::path& value);