mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 13:26:02 -05:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8802a8e861 | ||
|
|
8a01f3cc6b | ||
|
|
7d7bd0d642 | ||
|
|
2b1be7bc30 | ||
|
|
9df21c7952 | ||
|
|
70b9ceba72 | ||
|
|
27f3c634ba | ||
|
|
33b091e9e6 | ||
|
|
976caf53ae | ||
|
|
c2bb6e37b1 | ||
|
|
b4b47ff60e | ||
|
|
db2ad0951f | ||
|
|
e5969c5d2e | ||
|
|
b1d6086c0c | ||
|
|
7dfcbb15a4 | ||
|
|
4d470385d8 | ||
|
|
b0f010690c | ||
|
|
360ae718b9 | ||
|
|
6f45a7939a | ||
|
|
e27a4df8b0 | ||
|
|
84cd3f989b | ||
|
|
2e09a4e567 | ||
|
|
0ce1a87cbf | ||
|
|
6a158f99d7 | ||
|
|
77f46317f0 | ||
|
|
4c98f6bca6 | ||
|
|
77bc45ca17 | ||
|
|
1647fa9446 | ||
|
|
41a3fdaf3c | ||
|
|
e517406f06 |
@@ -70,6 +70,9 @@ macro(detectOS)
|
||||
add_compile_definitions(OS_WEB)
|
||||
elseif (UNIX AND NOT APPLE)
|
||||
add_compile_definitions(OS_LINUX)
|
||||
if (BSD AND BSD STREQUAL "FreeBSD")
|
||||
add_compile_definitions(OS_FREEBSD)
|
||||
endif()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(IMHEX_PLUGINS_IN_SHARE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
find_file(libyara.a YARA_LIBRARIES)
|
||||
find_library(YARA_LIBRARIES NAMES yara)
|
||||
find_file(yara.h YARA_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(YARA_LIBRARIES YARA_INCLUDE_DIRS)
|
||||
@@ -698,6 +698,7 @@ namespace hex {
|
||||
std::vector<GlyphRange> glyphRanges;
|
||||
Offset offset;
|
||||
u32 flags;
|
||||
std::optional<u32> defaultSize;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
@@ -716,8 +717,8 @@ namespace hex {
|
||||
GlyphRange range(const char *glyphBegin, const char *glyphEnd);
|
||||
GlyphRange range(u32 codepointBegin, u32 codepointEnd);
|
||||
|
||||
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0);
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0);
|
||||
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<u32> defaultSize = std::nullopt);
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0, std::optional<u32> defaultSize = std::nullopt);
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
|
||||
|
||||
@@ -40,13 +40,15 @@ namespace hex::log {
|
||||
std::scoped_lock lock(getLoggerMutex());
|
||||
|
||||
auto dest = getDestination();
|
||||
printPrefix(dest, ts, level, IMHEX_PROJECT_NAME);
|
||||
try {
|
||||
printPrefix(dest, ts, level, IMHEX_PROJECT_NAME);
|
||||
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}\n", message);
|
||||
fflush(dest);
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}\n", message);
|
||||
fflush(dest);
|
||||
|
||||
addLogEntry(IMHEX_PROJECT_NAME, level, std::move(message));
|
||||
addLogEntry(IMHEX_PROJECT_NAME, level, std::move(message));
|
||||
} catch (const std::exception&) { }
|
||||
}
|
||||
|
||||
namespace color {
|
||||
@@ -92,19 +94,23 @@ namespace hex::log {
|
||||
[[maybe_unused]] void print(const std::string &fmt, auto && ... args) {
|
||||
std::scoped_lock lock(impl::getLoggerMutex());
|
||||
|
||||
auto dest = impl::getDestination();
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}", message);
|
||||
fflush(dest);
|
||||
try {
|
||||
auto dest = impl::getDestination();
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}", message);
|
||||
fflush(dest);
|
||||
} catch (const std::exception&) { }
|
||||
}
|
||||
|
||||
[[maybe_unused]] void println(const std::string &fmt, auto && ... args) {
|
||||
std::scoped_lock lock(impl::getLoggerMutex());
|
||||
|
||||
auto dest = impl::getDestination();
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}\n", message);
|
||||
fflush(dest);
|
||||
try {
|
||||
auto dest = impl::getDestination();
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}\n", message);
|
||||
fflush(dest);
|
||||
} catch (const std::exception&) { }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace hex {
|
||||
return m_data | std::views::values;
|
||||
}
|
||||
|
||||
void setOnCreateCallback(std::function<void(const prv::Provider *, T&)> callback) {
|
||||
void setOnCreateCallback(std::function<void(prv::Provider *, T&)> callback) {
|
||||
m_onCreateCallback = std::move(callback);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace hex {
|
||||
auto [it, inserted] = m_data.emplace(provider, T());
|
||||
auto &[key, value] = *it;
|
||||
if (m_onCreateCallback)
|
||||
m_onCreateCallback(key, value);
|
||||
m_onCreateCallback(provider, value);
|
||||
});
|
||||
|
||||
EventProviderDeleted::subscribe(this, [this](prv::Provider *provider){
|
||||
@@ -121,7 +121,7 @@ namespace hex {
|
||||
|
||||
private:
|
||||
std::map<const prv::Provider *, T> m_data;
|
||||
std::function<void(const prv::Provider *, T&)> m_onCreateCallback;
|
||||
std::function<void(prv::Provider *, T&)> m_onCreateCallback;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -533,6 +533,11 @@ namespace hex {
|
||||
|
||||
pl::PatternLanguage& getRuntime() {
|
||||
static PerProvider<pl::PatternLanguage> runtime;
|
||||
AT_FIRST_TIME {
|
||||
runtime.setOnCreateCallback([](prv::Provider *provider, pl::PatternLanguage &runtime) {
|
||||
configureRuntime(runtime, provider);
|
||||
});
|
||||
};
|
||||
|
||||
return *runtime;
|
||||
}
|
||||
|
||||
@@ -658,7 +658,11 @@ namespace hex {
|
||||
#if defined(OS_WINDOWS)
|
||||
return "Windows";
|
||||
#elif defined(OS_LINUX)
|
||||
return "Linux";
|
||||
#if defined(OS_FREEBSD)
|
||||
return "FreeBSD";
|
||||
#else
|
||||
return "Linux";
|
||||
#endif
|
||||
#elif defined(OS_MACOS)
|
||||
return "macOS";
|
||||
#elif defined(OS_WEB)
|
||||
@@ -915,7 +919,7 @@ namespace hex {
|
||||
};
|
||||
}
|
||||
|
||||
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags) {
|
||||
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<u32> defaultSize) {
|
||||
wolv::io::File fontFile(path, wolv::io::File::Mode::Read);
|
||||
if (!fontFile.isValid()) {
|
||||
log::error("Failed to load font from file '{}'", wolv::util::toUTF8String(path));
|
||||
@@ -927,17 +931,19 @@ namespace hex {
|
||||
fontFile.readVector(),
|
||||
glyphRanges,
|
||||
offset,
|
||||
flags
|
||||
flags,
|
||||
defaultSize
|
||||
});
|
||||
}
|
||||
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags) {
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags, std::optional<u32> defaultSize) {
|
||||
impl::s_fonts->emplace_back(Font {
|
||||
name,
|
||||
{ data.begin(), data.end() },
|
||||
glyphRanges,
|
||||
offset,
|
||||
flags
|
||||
flags,
|
||||
defaultSize
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
#include <shellapi.h>
|
||||
#elif defined(OS_LINUX) || defined(OS_WEB)
|
||||
#include <xdg.hpp>
|
||||
# if defined(OS_FREEBSD)
|
||||
#include <sys/syslimits.h>
|
||||
# else
|
||||
#include <limits.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(OS_WEB)
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace hex::log {
|
||||
s_loggerFile.disableBuffering();
|
||||
|
||||
if (s_loggerFile.isValid()) {
|
||||
s_colorOutputEnabled = true;
|
||||
s_colorOutputEnabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace hex::init {
|
||||
|
||||
|
||||
FrameResult WindowSplash::fullFrame() {
|
||||
glfwSetWindowSize(m_window, 640_scaled, 400_scaled);
|
||||
glfwSetWindowSize(m_window, 640, 400);
|
||||
centerWindow(m_window);
|
||||
|
||||
glfwPollEvents();
|
||||
@@ -248,23 +248,21 @@ namespace hex::init {
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
auto scale = ImHexApi::System::getGlobalScale();
|
||||
|
||||
// Draw the splash screen background
|
||||
auto drawList = ImGui::GetBackgroundDrawList();
|
||||
{
|
||||
|
||||
// Draw the splash screen background
|
||||
drawList->AddImage(this->splashBackgroundTexture, ImVec2(0, 0), this->splashBackgroundTexture.getSize() * scale);
|
||||
drawList->AddImage(this->splashBackgroundTexture, ImVec2(0, 0), this->splashBackgroundTexture.getSize());
|
||||
|
||||
{
|
||||
|
||||
// Function to highlight a given number of bytes at a position in the splash screen
|
||||
const auto highlightBytes = [&](ImVec2 start, size_t count, ImColor color, float opacity) {
|
||||
// Dimensions and number of bytes that are drawn. Taken from the splash screen image
|
||||
const auto hexSize = ImVec2(29, 18) * scale;
|
||||
const auto hexSpacing = ImVec2(17.4, 15) * scale;
|
||||
const auto hexStart = ImVec2(27, 127) * scale;
|
||||
const auto hexSize = ImVec2(29, 18);
|
||||
const auto hexSpacing = ImVec2(17.4, 15);
|
||||
const auto hexStart = ImVec2(27, 127);
|
||||
|
||||
constexpr auto HexCount = ImVec2(13, 7);
|
||||
|
||||
@@ -312,10 +310,10 @@ namespace hex::init {
|
||||
this->progressLerp += (m_progress - this->progressLerp) * 0.1F;
|
||||
|
||||
// Draw the splash screen foreground
|
||||
drawList->AddImage(this->splashTextTexture, ImVec2(0, 0), this->splashTextTexture.getSize() * scale);
|
||||
drawList->AddImage(this->splashTextTexture, ImVec2(0, 0), this->splashTextTexture.getSize());
|
||||
|
||||
// Draw the "copyright" notice
|
||||
drawList->AddText(ImVec2(35, 85) * scale, ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("WerWolv\n2020 - {0}", &__DATE__[7]).c_str());
|
||||
drawList->AddText(ImVec2(35, 85), ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("WerWolv\n2020 - {0}", &__DATE__[7]).c_str());
|
||||
|
||||
// Draw version information
|
||||
// In debug builds, also display the current commit hash and branch
|
||||
@@ -325,18 +323,18 @@ namespace hex::init {
|
||||
const static auto VersionInfo = hex::format("{0}", ImHexApi::System::getImHexVersion());
|
||||
#endif
|
||||
|
||||
drawList->AddText(ImVec2((this->splashBackgroundTexture.getSize().x * scale - ImGui::CalcTextSize(VersionInfo.c_str()).x) / 2, 105 * scale), ImColor(0xFF, 0xFF, 0xFF, 0xFF), VersionInfo.c_str());
|
||||
drawList->AddText(ImVec2((this->splashBackgroundTexture.getSize().x - ImGui::CalcTextSize(VersionInfo.c_str()).x) / 2, 105), ImColor(0xFF, 0xFF, 0xFF, 0xFF), VersionInfo.c_str());
|
||||
}
|
||||
|
||||
// Draw the task progress bar
|
||||
{
|
||||
std::lock_guard guard(m_progressMutex);
|
||||
|
||||
const auto progressBackgroundStart = ImVec2(99, 357) * scale;
|
||||
const auto progressBackgroundSize = ImVec2(442, 30) * scale;
|
||||
const auto progressBackgroundStart = ImVec2(99, 357);
|
||||
const auto progressBackgroundSize = ImVec2(442, 30);
|
||||
|
||||
const auto progressStart = progressBackgroundStart + ImVec2(0, 20) * scale;
|
||||
const auto progressSize = ImVec2(progressBackgroundSize.x * m_progress, 10 * scale);
|
||||
const auto progressStart = progressBackgroundStart + ImVec2(0, 20);
|
||||
const auto progressSize = ImVec2(progressBackgroundSize.x * m_progress, 10);
|
||||
|
||||
// Draw progress bar
|
||||
drawList->AddRectFilled(progressStart, progressStart + progressSize, 0xD0FFFFFF);
|
||||
@@ -344,7 +342,7 @@ namespace hex::init {
|
||||
// Draw task names separated by | characters
|
||||
if (!m_currTaskNames.empty()) {
|
||||
drawList->PushClipRect(progressBackgroundStart, progressBackgroundStart + progressBackgroundSize, true);
|
||||
drawList->AddText(progressStart + ImVec2(5, -20) * scale, ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("{}", fmt::join(m_currTaskNames, " | ")).c_str());
|
||||
drawList->AddText(progressStart + ImVec2(5, -20), ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("{}", fmt::join(m_currTaskNames, " | ")).c_str());
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
}
|
||||
@@ -492,7 +490,7 @@ namespace hex::init {
|
||||
|
||||
ImFontConfig cfg;
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = 13.0_scaled;
|
||||
cfg.SizePixels = ImHexApi::Fonts::DefaultFontSize;
|
||||
io.Fonts->AddFontDefault(&cfg);
|
||||
|
||||
std::uint8_t *px;
|
||||
|
||||
@@ -213,6 +213,7 @@ namespace hex {
|
||||
constexpr static auto LongSleepFPS = 5.0;
|
||||
const double timeout = std::max(0.0, (1.0 / LongSleepFPS) - (glfwGetTime() - m_lastStartFrameTime));
|
||||
|
||||
glfwPollEvents();
|
||||
glfwWaitEventsTimeout(timeout);
|
||||
} else {
|
||||
glfwPollEvents();
|
||||
@@ -649,8 +650,6 @@ namespace hex {
|
||||
m_unlockFrameRate = true;
|
||||
}
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
// Process layout load requests
|
||||
// NOTE: This needs to be done before a new frame is started, otherwise ImGui won't handle docking correctly
|
||||
LayoutManager::process();
|
||||
|
||||
@@ -61,6 +61,8 @@ std::optional<std::fs::path> downloadUpdate(const std::string &url) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
hex::log::info("Writing update to file: {}", file.getPath().string());
|
||||
|
||||
// Write the downloaded update data to the file
|
||||
file.writeVector(data);
|
||||
|
||||
@@ -97,7 +99,7 @@ int installUpdate(const std::string &type, std::fs::path updatePath) {
|
||||
};
|
||||
|
||||
constexpr static auto UpdateHandlers = {
|
||||
UpdateHandler { "win-msi", ".msi", "msiexec /fa {} /passive" },
|
||||
UpdateHandler { "win-msi", ".msi", "msiexec /passive /package {}" },
|
||||
UpdateHandler { "macos-dmg", ".dmg", "hdiutil attach {}" },
|
||||
UpdateHandler { "linux-deb-22.04", ".deb", "sudo apt update && sudo apt install -y --fix-broken {}" },
|
||||
UpdateHandler { "linux-deb-23.04", ".deb", "sudo apt update && sudo apt install -y --fix-broken {}" },
|
||||
@@ -108,10 +110,14 @@ int installUpdate(const std::string &type, std::fs::path updatePath) {
|
||||
// Rename the update file to the correct extension
|
||||
const auto originalPath = updatePath;
|
||||
updatePath.replace_extension(handler.extension);
|
||||
|
||||
hex::log::info("Moving update package from {} to {}", originalPath.string(), updatePath.string());
|
||||
std::fs::rename(originalPath, updatePath);
|
||||
|
||||
// Install the update using the correct command
|
||||
hex::startProgram(hex::format(handler.command, updatePath.string()));
|
||||
const auto command = hex::format(handler.command, updatePath.string());
|
||||
hex::log::info("Starting update process with command: '{}'", command);
|
||||
hex::startProgram(command);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -163,6 +169,8 @@ int main(int argc, char **argv) {
|
||||
if (!updatePath.has_value())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hex::log::info("Downloaded update successfully");
|
||||
|
||||
// Install the update
|
||||
return installUpdate(updateType, *updatePath);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_WINDOWS) || defined (OS_LINUX)
|
||||
#if defined(OS_WINDOWS) || (defined(OS_LINUX) && !defined(OS_FREEBSD))
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
@@ -46,11 +46,13 @@ namespace hex::plugin::builtin {
|
||||
return m_provider->isSavable();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
void save() override {
|
||||
m_provider->save();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool open() override { return true; }
|
||||
[[nodiscard]] bool open() override { return m_provider != this; }
|
||||
void close() override { }
|
||||
|
||||
void resizeRaw(u64 newSize) override {
|
||||
@@ -101,8 +103,31 @@ namespace hex::plugin::builtin {
|
||||
return m_provider->getDataDescription();
|
||||
}
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }
|
||||
void loadSettings(const nlohmann::json &settings) override {
|
||||
Provider::loadSettings(settings);
|
||||
|
||||
auto id = settings.at("id").get<u64>();
|
||||
m_startAddress = settings.at("start_address").get<u64>();
|
||||
m_size = settings.at("size").get<size_t>();
|
||||
|
||||
const auto &providers = ImHexApi::Provider::getProviders();
|
||||
auto provider = std::ranges::find_if(providers, [id](const prv::Provider *provider) {
|
||||
return provider->getID() == id;
|
||||
});
|
||||
|
||||
if (provider == providers.end())
|
||||
return;
|
||||
|
||||
m_provider = *provider;
|
||||
}
|
||||
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override {
|
||||
settings["id"] = m_provider->getID();
|
||||
settings["start_address"] = m_startAddress;
|
||||
settings["size"] = m_size;
|
||||
|
||||
return Provider::storeSettings(settings);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getTypeName() const override {
|
||||
return "hex.builtin.provider.view";
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace hex::plugin::builtin {
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
} else {
|
||||
EventProviderOpened::post(fileProvider);
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.open_file.name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +278,13 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Disable merge mode for this font but retain the rest of the configuration
|
||||
cfg.MergeMode = false;
|
||||
|
||||
auto size = fontSize;
|
||||
if (font.defaultSize.has_value())
|
||||
size = font.defaultSize.value() * ImHexApi::System::getGlobalScale();
|
||||
|
||||
cfg.SizePixels = size;
|
||||
|
||||
ON_SCOPE_EXIT { cfg.MergeMode = true; };
|
||||
|
||||
// Construct a range that only contains the first glyph of the font
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace hex::plugin::builtin {
|
||||
std::vector<u8> bytes(5_MiB);
|
||||
|
||||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
for (u64 address = selection->getStartAddress(); address <= selection->getEndAddress(); address += bytes.size()) {
|
||||
for (u64 address = selection->getStartAddress(); address < selection->getEndAddress(); address += bytes.size()) {
|
||||
bytes.resize(std::min<u64>(bytes.size(), selection->getEndAddress() - address));
|
||||
provider->read(address, bytes.data(), bytes.size());
|
||||
|
||||
|
||||
@@ -348,6 +348,8 @@ namespace hex::plugin::builtin {
|
||||
// Draw deny button
|
||||
ImGui::SetCursorPosX(buttonPos(2));
|
||||
if (ImGui::Button("hex.ui.common.deny"_lang, buttonSize)) {
|
||||
ContentRegistry::Settings::write<int>("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 0);
|
||||
ContentRegistry::Settings::write<int>("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", 0);
|
||||
page += 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Provider::add<MemoryFileProvider>(false);
|
||||
ContentRegistry::Provider::add<ViewProvider>(false);
|
||||
|
||||
#if defined(OS_WINDOWS) ||defined (OS_LINUX)
|
||||
#if defined(OS_WINDOWS) || (defined(OS_LINUX) && !defined(OS_FREEBSD))
|
||||
ContentRegistry::Provider::add<ProcessMemoryProvider>();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#elif defined(OS_LINUX)
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
#if !defined(OS_FREEBSD)
|
||||
#include <linux/fs.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
@@ -41,8 +43,11 @@
|
||||
#include <sys/disk.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#define lseek lseek64
|
||||
#if defined(OS_LINUX) && !defined(OS_FREEBSD)
|
||||
#define lseek lseek64
|
||||
#elif defined(OS_FREEBSD)
|
||||
#include <sys/disk.h>
|
||||
#define DEFAULT_SECTOR_SIZE 512
|
||||
#endif
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@@ -83,6 +88,12 @@ namespace hex::plugin::builtin {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(OS_FREEBSD) && defined(DIOCGSECTORSIZE)
|
||||
int blkdev_get_sector_size(int fd, int *sector_size) {
|
||||
if (ioctl(fd, DIOCGSECTORSIZE, sector_size) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int blkdev_get_sector_size(int fd, int *sector_size) {
|
||||
(void)fd;
|
||||
@@ -97,6 +108,12 @@ namespace hex::plugin::builtin {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(OS_FREEBSD) && defined(DIOCGMEDIASIZE)
|
||||
int blkdev_get_size(int fd, u64 *bytes) {
|
||||
if (ioctl(fd, DIOCGMEDIASIZE, bytes) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int blkdev_get_size(int fd, u64 *bytes) {
|
||||
struct stat st;
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace hex::plugin::builtin {
|
||||
m_readable = true;
|
||||
m_writable = true;
|
||||
|
||||
if (!std::fs::exists(m_path)) {
|
||||
if (!wolv::io::fs::exists(m_path)) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), ::strerror(ENOENT)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if defined(OS_WINDOWS) || defined (OS_LINUX)
|
||||
#if defined(OS_WINDOWS) || (defined(OS_LINUX) && !defined(OS_FREEBSD))
|
||||
|
||||
#include <content/providers/process_memory_provider.hpp>
|
||||
|
||||
|
||||
@@ -313,8 +313,8 @@ namespace hex::plugin::builtin {
|
||||
u64 droppedBookmarkId = *static_cast<const u64*>(payload->Data);
|
||||
|
||||
// Find the correct bookmark with that id
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks->begin(), m_bookmarks->end(), [droppedBookmarkId](const auto &bookmark) {
|
||||
return bookmark.entry.id == droppedBookmarkId;
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks->begin(), m_bookmarks->end(), [droppedBookmarkId](const auto &bookmarkItem) {
|
||||
return bookmarkItem.entry.id == droppedBookmarkId;
|
||||
});
|
||||
|
||||
// Swap the two bookmarks
|
||||
@@ -412,16 +412,25 @@ namespace hex::plugin::builtin {
|
||||
u64 end = region.getEndAddress();
|
||||
|
||||
if (!locked) {
|
||||
bool updated = false;
|
||||
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGuiExt::InputHexadecimal("##begin", &begin);
|
||||
if (ImGuiExt::InputHexadecimal("##begin", &begin))
|
||||
updated = true;
|
||||
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGui::TextUnformatted(" - ");
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGuiExt::InputHexadecimal("##end", &end);
|
||||
|
||||
if (ImGuiExt::InputHexadecimal("##end", &end))
|
||||
updated = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (end > begin)
|
||||
if (updated && end > begin) {
|
||||
region = Region(begin, end - begin + 1);
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
} else {
|
||||
ImGuiExt::TextFormatted("0x{:02X} - 0x{:02X}", begin, end);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
|
||||
m_validBytes = 0;
|
||||
m_selectedProvider = nullptr;
|
||||
} else {
|
||||
m_validBytes = u64(region.getProvider()->getActualSize() - region.address);
|
||||
m_validBytes = u64((region.getProvider()->getBaseAddress() + region.getProvider()->getActualSize()) - region.address);
|
||||
m_startAddress = region.address;
|
||||
m_selectedProvider = region.getProvider();
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SetClipboardText(
|
||||
callback(
|
||||
provider,
|
||||
selection->getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress(),
|
||||
selection->getStartAddress(),
|
||||
selection->size
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -133,6 +133,9 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
static void drawVirtualFileTree(const std::vector<const ViewPatternEditor::VirtualFile*> &virtualFiles, u32 level = 0) {
|
||||
ImGui::PushID(level + 1);
|
||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||
|
||||
std::map<std::string, std::vector<const ViewPatternEditor::VirtualFile*>> currFolderEntries;
|
||||
for (const auto &file : virtualFiles) {
|
||||
const auto &path = file->path;
|
||||
@@ -146,8 +149,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TreeNodeEx(currSegment.c_str(), ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && ImGui::IsItemHovered()) {
|
||||
ImHexApi::Provider::add<prv::MemoryProvider>(file->data, wolv::util::toUTF8String(file->path.filename()));
|
||||
}
|
||||
|
||||
@@ -157,6 +159,7 @@ namespace hex::plugin::builtin {
|
||||
currFolderEntries[currSegment].emplace_back(file);
|
||||
}
|
||||
|
||||
int id = 1;
|
||||
for (const auto &[segment, entries] : currFolderEntries) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
@@ -167,11 +170,16 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TextUnformatted(ICON_VS_FOLDER);
|
||||
}
|
||||
|
||||
ImGui::PushID(id);
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::TreeNodeEx(segment.c_str(), ImGuiTreeNodeFlags_SpanFullWidth)) {
|
||||
drawVirtualFileTree(entries, level + 1);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
id += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1158,7 +1166,7 @@ namespace hex::plugin::builtin {
|
||||
for (const auto &file : virtualFiles)
|
||||
virtualFilePointers.emplace_back(&file);
|
||||
|
||||
if (ImGui::BeginTable("Virtual File Tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg, size)) {
|
||||
if (ImGui::BeginTable("Virtual File Tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) {
|
||||
ImGui::TableSetupColumn("##path", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
drawVirtualFileTree(virtualFilePointers);
|
||||
@@ -1538,6 +1546,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
m_sectionWindowDrawer.clear();
|
||||
m_consoleEditor.SetText("");
|
||||
m_virtualFiles->clear();
|
||||
|
||||
m_accessHistory = {};
|
||||
m_accessHistoryIndex = 0;
|
||||
|
||||
@@ -198,7 +198,6 @@ namespace hex::plugin::builtin {
|
||||
ImGui::BeginDisabled(m_updateAllTask.isRunning() || m_updateCount == 0);
|
||||
if (ImGuiExt::IconButton(ICON_VS_CLOUD_DOWNLOAD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
m_updateAllTask = TaskManager::createTask("Update All...", m_updateCount, [this](auto &task) {
|
||||
u32 progress = 0;
|
||||
for (auto &category : m_categories) {
|
||||
for (auto &entry : category.entries) {
|
||||
if (entry.hasUpdate) {
|
||||
@@ -212,7 +211,7 @@ namespace hex::plugin::builtin {
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
task.update(progress);
|
||||
task.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,9 +80,10 @@ namespace hex::plugin::decompress {
|
||||
if (stream.avail_out != 0)
|
||||
break;
|
||||
|
||||
section.resize(section.size() * 2);
|
||||
stream.next_out = section.data();
|
||||
stream.avail_out = section.size();
|
||||
const auto prevSectionSize = section.size();
|
||||
section.resize(prevSectionSize * 2);
|
||||
stream.next_out = section.data() + prevSectionSize;
|
||||
stream.avail_out = prevSectionSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -126,9 +127,10 @@ namespace hex::plugin::decompress {
|
||||
if (stream.avail_out != 0)
|
||||
break;
|
||||
|
||||
section.resize(section.size() * 2);
|
||||
stream.next_out = reinterpret_cast<char*>(section.data());
|
||||
stream.avail_out = section.size();
|
||||
const auto prevSectionSize = section.size();
|
||||
section.resize(prevSectionSize * 2);
|
||||
stream.next_out = reinterpret_cast<char*>(section.data()) + prevSectionSize;
|
||||
stream.avail_out = prevSectionSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -173,9 +175,10 @@ namespace hex::plugin::decompress {
|
||||
if (stream.avail_out != 0)
|
||||
break;
|
||||
|
||||
section.resize(section.size() * 2);
|
||||
stream.next_out = compressedData.data();
|
||||
stream.avail_out = compressedData.size();
|
||||
const auto prevSectionSize = section.size();
|
||||
section.resize(prevSectionSize * 2);
|
||||
stream.next_out = section.data() + prevSectionSize;
|
||||
stream.avail_out = prevSectionSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace hex::plugin::diffing {
|
||||
~ViewDiff() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawAlwaysVisibleContent() override;
|
||||
ImGuiWindowFlags getWindowFlags() const override { return ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; }
|
||||
|
||||
public:
|
||||
|
||||
@@ -192,14 +192,12 @@ namespace hex::plugin::diffing {
|
||||
ImGui::TableSetupColumn("hex.diffing.view.diff.provider_b"_lang);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImVec2 buttonPos;
|
||||
ImGui::BeginDisabled(m_diffTask.isRunning());
|
||||
{
|
||||
// Draw settings button
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_SETTINGS_GEAR, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
|
||||
ImGui::OpenPopup("DiffingAlgorithmSettings");
|
||||
buttonPos = ImGui::GetCursorScreenPos();
|
||||
RequestOpenPopup::post("##DiffingAlgorithmSettings");
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
@@ -212,41 +210,6 @@ namespace hex::plugin::diffing {
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SetNextWindowPos(buttonPos);
|
||||
if (ImGui::BeginPopup("DiffingAlgorithmSettings")) {
|
||||
ImGuiExt::Header("hex.diffing.view.diff.algorithm"_lang, true);
|
||||
ImGui::PushItemWidth(300_scaled);
|
||||
if (ImGui::BeginCombo("##Algorithm", m_algorithm == nullptr ? "" : Lang(m_algorithm->getUnlocalizedName()))) {
|
||||
for (const auto &algorithm : ContentRegistry::Diffing::impl::getAlgorithms()) {
|
||||
ImGui::PushID(algorithm.get());
|
||||
if (ImGui::Selectable(Lang(algorithm->getUnlocalizedName()))) {
|
||||
m_algorithm = algorithm.get();
|
||||
m_analyzed = false;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (m_algorithm != nullptr) {
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(m_algorithm->getUnlocalizedDescription()));
|
||||
}
|
||||
|
||||
ImGuiExt::Header("hex.diffing.view.diff.settings"_lang);
|
||||
if (m_algorithm != nullptr) {
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
auto prevIdx = drawList->_VtxCurrentIdx;
|
||||
m_algorithm->drawSettings();
|
||||
auto currIdx = drawList->_VtxCurrentIdx;
|
||||
|
||||
if (prevIdx == currIdx)
|
||||
ImGuiExt::TextFormatted("hex.diffing.view.diff.settings.no_settings"_lang);
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
// Draw first hex editor column
|
||||
@@ -337,4 +300,42 @@ namespace hex::plugin::diffing {
|
||||
}
|
||||
}
|
||||
|
||||
void ViewDiff::drawAlwaysVisibleContent() {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(400_scaled, 600_scaled));
|
||||
if (ImGui::BeginPopup("##DiffingAlgorithmSettings")) {
|
||||
ImGuiExt::Header("hex.diffing.view.diff.algorithm"_lang, true);
|
||||
ImGui::PushItemWidth(300_scaled);
|
||||
if (ImGui::BeginCombo("##Algorithm", m_algorithm == nullptr ? "" : Lang(m_algorithm->getUnlocalizedName()))) {
|
||||
for (const auto &algorithm : ContentRegistry::Diffing::impl::getAlgorithms()) {
|
||||
ImGui::PushID(algorithm.get());
|
||||
if (ImGui::Selectable(Lang(algorithm->getUnlocalizedName()))) {
|
||||
m_algorithm = algorithm.get();
|
||||
m_analyzed = false;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (m_algorithm != nullptr) {
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(m_algorithm->getUnlocalizedDescription()));
|
||||
}
|
||||
|
||||
ImGuiExt::Header("hex.diffing.view.diff.settings"_lang);
|
||||
if (m_algorithm != nullptr) {
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
auto prevIdx = drawList->_VtxCurrentIdx;
|
||||
m_algorithm->drawSettings();
|
||||
auto currIdx = drawList->_VtxCurrentIdx;
|
||||
|
||||
if (prevIdx == currIdx)
|
||||
ImGuiExt::TextFormatted("hex.diffing.view.diff.settings.no_settings"_lang);
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace hex::fonts {
|
||||
* efficient when packing the glyphs into the font atlas and therefor make the atlas much smaller.
|
||||
*/
|
||||
|
||||
ImHexApi::Fonts::loadFont("Blender Icons", romfs::get("fonts/blendericons.ttf").span<u8>(),{ { ICON_MIN_BI, ICON_MAX_BI } }, { -1_scaled, -1_scaled });
|
||||
ImHexApi::Fonts::loadFont("Blender Icons", romfs::get("fonts/blendericons.ttf").span<u8>(),{ { ICON_MIN_BI, ICON_MAX_BI } }, { -1_scaled, -1_scaled }, 0, 13);
|
||||
|
||||
ImHexApi::Fonts::loadFont("VS Codicons", romfs::get("fonts/codicons.ttf").span<u8>(),
|
||||
{
|
||||
{ ICON_MIN_VS, ICON_MAX_VS }
|
||||
},
|
||||
{ -1_scaled, -1_scaled });
|
||||
{ -1_scaled, -1_scaled }, 0, 13);
|
||||
|
||||
ImHexApi::Fonts::loadFont("Unifont", romfs::get("fonts/unifont.otf").span<u8>());
|
||||
ImHexApi::Fonts::loadFont("Unifont", romfs::get("fonts/unifont.otf").span<u8>(), {}, {}, 0, 16);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,6 @@ add_imhex_plugin(
|
||||
INCLUDES
|
||||
include
|
||||
LIBRARIES
|
||||
libpl
|
||||
libpl-gen
|
||||
fonts
|
||||
LIBRARY_PLUGIN
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <popups/popup_notification.hpp>
|
||||
|
||||
@@ -48,18 +49,24 @@ namespace hex::ui {
|
||||
}
|
||||
|
||||
struct ToastInfo : impl::ToastNotification<ToastInfo> {
|
||||
ToastInfo(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerInfo), ICON_VS_INFO, "hex.ui.common.info", std::move(message)) {}
|
||||
explicit ToastInfo(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerInfo), ICON_VS_INFO, "hex.ui.common.info", message) {
|
||||
log::info("{}", message);
|
||||
}
|
||||
};
|
||||
|
||||
struct ToastWarning : impl::ToastNotification<ToastWarning> {
|
||||
ToastWarning(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerWarning), ICON_VS_WARNING, "hex.ui.common.warning", std::move(message)) {}
|
||||
explicit ToastWarning(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerWarning), ICON_VS_WARNING, "hex.ui.common.warning", message) {
|
||||
log::warn("{}", message);
|
||||
}
|
||||
};
|
||||
|
||||
struct ToastError : impl::ToastNotification<ToastError> {
|
||||
ToastError(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError), ICON_VS_ERROR, "hex.ui.common.error", std::move(message)) {}
|
||||
explicit ToastError(std::string message)
|
||||
: ToastNotification(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError), ICON_VS_ERROR, "hex.ui.common.error", message) {
|
||||
log::error("{}", message);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ namespace hex::ui {
|
||||
this->setSelection(selectionStart.value_or(address), endAddress);
|
||||
this->scrollToSelection();
|
||||
}
|
||||
else if (ImGui::IsMouseDown(ImGuiMouseButton_Left) || (ImGui::IsMouseDown(ImGuiMouseButton_Right) && (address < m_selectionStart || address > m_selectionEnd))) {
|
||||
else if (ImGui::IsMouseDown(ImGuiMouseButton_Left) || (ImGui::IsMouseDown(ImGuiMouseButton_Right) && (address < std::min(m_selectionStart, m_selectionEnd) || address > std::max(m_selectionStart, m_selectionEnd)))) {
|
||||
if (ImGui::GetIO().KeyShift)
|
||||
this->setSelection(selectionStart.value_or(address), endAddress);
|
||||
else
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"language": "German",
|
||||
"translations": {
|
||||
"hex.yara.information_section.advanced_data_info": "Erweiterte Dateninformationen",
|
||||
"hex.yara.information_section.advanced_data_info.no_information": "Kein erweiterten Informationen gefunden",
|
||||
"hex.yara_rules.view.yara.error": "Yara Kompilerfehler: {0}",
|
||||
"hex.yara_rules.view.yara.header.matches": "Treffer",
|
||||
"hex.yara_rules.view.yara.header.rules": "Regeln",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"fallback": true,
|
||||
"translations": {
|
||||
"hex.yara.information_section.advanced_data_info": "Advanced Data Information",
|
||||
"hex.yara.information_section.advanced_data_info.no_information": "No further information found",
|
||||
"hex.yara_rules.view.yara.error": "Yara Compiler error: {0}",
|
||||
"hex.yara_rules.view.yara.header.matches": "Matches",
|
||||
"hex.yara_rules.view.yara.header.rules": "Rules",
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/magic.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
@@ -59,28 +57,39 @@ namespace hex::plugin::yara {
|
||||
}
|
||||
|
||||
void drawContent() override {
|
||||
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoKeepColumnsVisible)) {
|
||||
ImGui::TableSetupColumn("Left", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
const auto empty = !std::ranges::any_of(m_categories, [](const auto &entry) {
|
||||
const auto &[categoryName, category] = entry;
|
||||
return !category.matchedRules.empty();
|
||||
});
|
||||
|
||||
ImGui::TableNextRow();
|
||||
if (!empty) {
|
||||
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoKeepColumnsVisible)) {
|
||||
ImGui::TableSetupColumn("Left", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
|
||||
for (auto &[categoryName, category] : m_categories) {
|
||||
if (category.matchedRules.empty())
|
||||
continue;
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::BeginSubWindow(categoryName.c_str());
|
||||
{
|
||||
for (const auto &match : category.matchedRules) {
|
||||
const auto &ruleName = match.metadata.contains("name") ? match.metadata.at("name") : match.identifier;
|
||||
ImGui::TextUnformatted(ruleName.c_str());
|
||||
for (auto &[categoryName, category] : m_categories) {
|
||||
if (category.matchedRules.empty())
|
||||
continue;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::BeginSubWindow(categoryName.c_str());
|
||||
{
|
||||
for (const auto &match : category.matchedRules) {
|
||||
const auto &ruleName = match.metadata.contains("name") ? match.metadata.at("name") : match.identifier;
|
||||
ImGui::TextUnformatted(ruleName.c_str());
|
||||
}
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
ImGui::NewLine();
|
||||
ImGuiExt::TextFormattedCenteredHorizontal("{}", "hex.yara.information_section.advanced_data_info.no_information"_lang);
|
||||
ImGui::NewLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user