From 0e3da22c7609208ff168c73d662a5b18d353a4fe Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 23 May 2023 11:34:30 +0200 Subject: [PATCH] feat: Added support for changing the page size --- .../include/hex/providers/provider.hpp | 7 ++- lib/libimhex/source/providers/provider.cpp | 19 +++++-- main/source/window/win_window.cpp | 12 +++-- plugins/builtin/romfs/lang/en_US.json | 1 + .../source/content/providers/gdb_provider.cpp | 2 +- .../source/content/views/view_hex_editor.cpp | 54 +++++++++++++++++-- plugins/builtin/source/ui/hex_editor.cpp | 3 +- 7 files changed, 84 insertions(+), 14 deletions(-) diff --git a/lib/libimhex/include/hex/providers/provider.hpp b/lib/libimhex/include/hex/providers/provider.hpp index 8a55e7687..70fd6e472 100644 --- a/lib/libimhex/include/hex/providers/provider.hpp +++ b/lib/libimhex/include/hex/providers/provider.hpp @@ -21,7 +21,7 @@ namespace hex::prv { */ class Provider { public: - constexpr static size_t PageSize = 0x1000'0000; + constexpr static size_t MaxPageSize = 0x1000'0000; Provider(); virtual ~Provider(); @@ -82,6 +82,9 @@ namespace hex::prv { void deleteOverlay(Overlay *overlay); [[nodiscard]] const std::list &getOverlays(); + [[nodiscard]] size_t getPageSize() const; + void setPageSize(size_t pageSize); + [[nodiscard]] u32 getPageCount() const; [[nodiscard]] u32 getCurrentPage() const; void setCurrentPage(u32 page); @@ -173,6 +176,8 @@ namespace hex::prv { std::string m_errorMessage; + size_t m_pageSize = MaxPageSize; + private: static u32 s_idCounter; }; diff --git a/lib/libimhex/source/providers/provider.cpp b/lib/libimhex/source/providers/provider.cpp index 3b42221f5..71b3295b2 100644 --- a/lib/libimhex/source/providers/provider.cpp +++ b/lib/libimhex/source/providers/provider.cpp @@ -156,8 +156,19 @@ namespace hex::prv { } + size_t Provider::getPageSize() const { + return this->m_pageSize; + } + + void Provider::setPageSize(size_t pageSize) { + if (pageSize > MaxPageSize) + pageSize = MaxPageSize; + + this->m_pageSize = pageSize; + } + u32 Provider::getPageCount() const { - return (this->getActualSize() / PageSize) + (this->getActualSize() % PageSize != 0 ? 1 : 0); + return (this->getActualSize() / this->getPageSize()) + (this->getActualSize() % this->getPageSize() != 0 ? 1 : 0); } u32 Provider::getCurrentPage() const { @@ -180,15 +191,15 @@ namespace hex::prv { } u64 Provider::getCurrentPageAddress() const { - return PageSize * this->getCurrentPage(); + return this->getPageSize() * this->getCurrentPage(); } size_t Provider::getSize() const { - return std::min(this->getActualSize() - PageSize * this->m_currPage, PageSize); + return std::min(this->getActualSize() - this->getPageSize() * this->m_currPage, this->getPageSize()); } std::optional Provider::getPageOfAddress(u64 address) const { - u32 page = std::floor((address - this->getBaseAddress()) / double(PageSize)); + u32 page = std::floor((address - this->getBaseAddress()) / double(this->getPageSize())); if (page >= this->getPageCount()) return std::nullopt; diff --git a/main/source/window/win_window.cpp b/main/source/window/win_window.cpp index 423793742..0dc72ce7c 100644 --- a/main/source/window/win_window.cpp +++ b/main/source/window/win_window.cpp @@ -30,6 +30,9 @@ namespace hex { + template + using WinUniquePtr = std::unique_ptr, BOOL(*)(T)>; + static LONG_PTR g_oldWndProc; static float g_titleBarHeight; static Microsoft::WRL::ComPtr g_taskbarList; @@ -349,17 +352,20 @@ namespace hex { EventManager::subscribe([this]{ auto hwnd = glfwGetWin32Window(this->m_window); - const HINSTANCE user32Dll = LoadLibraryA("user32.dll"); + const auto user32Dll = WinUniquePtr(LoadLibraryA("user32.dll"), FreeLibrary); if (user32Dll != nullptr) { using SetWindowCompositionAttributeFunc = BOOL(WINAPI*)(HWND, WINCOMPATTRDATA*); - const auto SetWindowCompositionAttribute = (SetWindowCompositionAttributeFunc)(void*)GetProcAddress(user32Dll, "SetWindowCompositionAttribute"); + const auto SetWindowCompositionAttribute = + (SetWindowCompositionAttributeFunc) + (void*) + GetProcAddress(user32Dll.get(), "SetWindowCompositionAttribute"); + if (SetWindowCompositionAttribute != nullptr) { ACCENTPOLICY policy = { ImGui::GetCustomStyle().WindowBlur > 0.5F ? 3 : 0, 0, 0, 0 }; WINCOMPATTRDATA data = { 19, &policy, sizeof(ACCENTPOLICY) }; SetWindowCompositionAttribute(hwnd, &data); } - FreeLibrary(user32Dll); } }); diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 139f9f9be..91f0560ea 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -759,6 +759,7 @@ "hex.builtin.view.hex_editor.menu.edit.resize": "Resize...", "hex.builtin.view.hex_editor.menu.edit.select_all": "Select all", "hex.builtin.view.hex_editor.menu.edit.set_base": "Set base address", + "hex.builtin.view.hex_editor.menu.edit.set_page_size": "Set page size", "hex.builtin.view.hex_editor.menu.file.goto": "Goto", "hex.builtin.view.hex_editor.menu.file.load_encoding_file": "Load custom encoding...", "hex.builtin.view.hex_editor.menu.file.save": "Save", diff --git a/plugins/builtin/source/content/providers/gdb_provider.cpp b/plugins/builtin/source/content/providers/gdb_provider.cpp index 2f5e2ba30..be6a440c3 100644 --- a/plugins/builtin/source/content/providers/gdb_provider.cpp +++ b/plugins/builtin/source/content/providers/gdb_provider.cpp @@ -186,7 +186,7 @@ namespace hex::plugin::builtin { if (overlays) { for (u64 i = 0; i < size; i++) if (getPatches().contains(offset + i)) - reinterpret_cast(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i]; + reinterpret_cast(buffer)[i] = getPatches()[offset + this->getPageSize() * this->m_currPage + i]; this->applyOverlays(offset, buffer, size); } diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index 8cef726e3..54666fdc4 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -341,7 +341,7 @@ namespace hex::plugin::builtin { ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_base"_lang); ImGui::InputHexadecimal("##base_address", &this->m_baseAddress); - if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_Enter))) { + if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) { setBaseAddress(this->m_baseAddress); editor->closePopup(); } @@ -353,7 +353,8 @@ namespace hex::plugin::builtin { }, [&]{ editor->closePopup(); - }); + } + ); } private: @@ -366,6 +367,44 @@ namespace hex::plugin::builtin { u64 m_baseAddress; }; + class PopupPageSize : public ViewHexEditor::Popup { + public: + explicit PopupPageSize(u64 pageSize) : m_pageSize(pageSize) { } + + void draw(ViewHexEditor *editor) override { + ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_page_size"_lang); + + ImGui::InputHexadecimal("##page_size", &this->m_pageSize); + if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) { + setPageSize(this->m_pageSize); + editor->closePopup(); + } + + View::confirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang, + [&, this]{ + setPageSize(this->m_pageSize); + editor->closePopup(); + }, + [&]{ + editor->closePopup(); + } + ); + } + + private: + static void setPageSize(u64 pageSize) { + if (ImHexApi::Provider::isValid()) { + auto provider = ImHexApi::Provider::get(); + + provider->setPageSize(pageSize); + provider->setCurrentPage(0); + } + } + + private: + u64 m_pageSize; + }; + class PopupResize : public ViewHexEditor::Popup { public: explicit PopupResize(u64 currSize) : m_size(currSize) {} @@ -374,7 +413,7 @@ namespace hex::plugin::builtin { ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.resize"_lang); ImGui::InputHexadecimal("##resize", &this->m_size); - if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_Enter))) { + if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) { resize(static_cast(this->m_size)); editor->closePopup(); } @@ -1151,7 +1190,14 @@ namespace hex::plugin::builtin { } }, [] { return ImHexApi::Provider::isValid() && ImHexApi::HexEditor::isSelectionValid() && ImHexApi::HexEditor::getSelection()->getSize() <= sizeof(u64); }); - // Popups + + /* Set Page Size */ + ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.set_page_size" }, 1860, Shortcut::None, + [this] { + auto provider = ImHexApi::Provider::get(); + this->openPopup(provider->getPageSize()); + }, + [] { return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isReadable(); }); ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.edit" }, 1900); diff --git a/plugins/builtin/source/ui/hex_editor.cpp b/plugins/builtin/source/ui/hex_editor.cpp index b6be67fb4..6ec148939 100644 --- a/plugins/builtin/source/ui/hex_editor.cpp +++ b/plugins/builtin/source/ui/hex_editor.cpp @@ -693,7 +693,8 @@ namespace hex::plugin::builtin::ui { // Page Address ImGui::TableNextColumn(); { - ImGui::TextFormatted("{0}: 0x{1:08X} - 0x{2:08X} ({1} - {2})", "hex.builtin.hex_editor.region"_lang, this->m_provider->getCurrentPageAddress(), this->m_provider->getSize()); + auto pageAddress = this->m_provider->getCurrentPageAddress(); + ImGui::TextFormatted("{0}: 0x{1:08X} - 0x{2:08X} ({1} - {2})", "hex.builtin.hex_editor.region"_lang, pageAddress, pageAddress + this->m_provider->getSize() - 1); } ImGui::TableNextRow();