Compare commits

..

30 Commits

Author SHA1 Message Date
WerWolv
8802a8e861 build: Bumped version to 1.33.2 2024-03-23 10:15:12 +01:00
WerWolv
8a01f3cc6b impr: Show hint if advanced data information section doesn't yield any result 2024-03-22 21:33:57 +01:00
WerWolv
7d7bd0d642 fix: Splash screen being scaled incorrectly 2024-03-22 17:53:43 +01:00
WerWolv
2b1be7bc30 fix: Icons not being scaled correctly anymore 2024-03-22 17:53:34 +01:00
WerWolv
9df21c7952 fix: Missing include in notification toasts 2024-03-22 17:52:55 +01:00
Nobutaka Mantani
70b9ceba72 build: Added support patches for FreeBSD (#1584)
This pull request fixes build on FreeBSD. The changes are conditioned
with `#if defined(__FreeBSD__)` preprocessor macro and they should not
affect build for other operating systems.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
Co-authored-by: iTrooz <hey@itrooz.fr>
2024-03-22 17:52:38 +01:00
WerWolv
27f3c634ba impr: Load unifont at correct size
Fixes #1604
2024-03-22 17:50:45 +01:00
WerWolv
33b091e9e6 fix: Decompress functions not extracting full data
Thanks a lot to tocklime
2024-03-22 17:47:25 +01:00
WerWolv
976caf53ae fix: Prevent view providers from pointing to themselves and being saved as recent provider
#1607
2024-03-22 17:47:14 +01:00
WerWolv
c2bb6e37b1 fix: Crash when trying to open unopenable file 2024-03-22 17:46:50 +01:00
WerWolv
b4b47ff60e fix: Make sure pattern runtime is always properly configured 2024-03-22 17:46:24 +01:00
WerWolv
db2ad0951f fix: File open achievement not triggering when dropping a file onto ImHex 2024-03-22 17:46:13 +01:00
WerWolv
e5969c5d2e fix: Potential crash when log file is unavailable 2024-03-22 17:45:59 +01:00
WerWolv
b1d6086c0c fix: Control characters ending up in log files 2024-03-22 17:45:38 +01:00
WerWolv
7dfcbb15a4 fix: Infinite loop when exporting selection to file 2024-03-22 17:45:11 +01:00
WerWolv
4d470385d8 fix: Right clicking reverse selected regions deselecting it 2024-03-22 17:45:02 +01:00
WerWolv
b0f010690c fix: Various issues with the virtual file system 2024-03-22 17:44:49 +01:00
WerWolv
360ae718b9 fix: Advanced data information not showing up correctly 2024-03-22 17:44:36 +01:00
WerWolv
6f45a7939a fix: Diffing option popup flickering when opening 2024-03-22 17:43:00 +01:00
WerWolv
e27a4df8b0 fix: Base address issues with the data inspector and copy as array option
Fixes #1595
2024-03-22 17:42:17 +01:00
WerWolv
84cd3f989b fix: Denying server contact leaving crash upload option enabled
Fixes #1594
2024-03-22 17:41:35 +01:00
WerWolv
2e09a4e567 fix: ImHex using a ton of CPU power on Linux 2024-03-22 17:41:03 +01:00
WerWolv
0ce1a87cbf fix: Toasts not printing their message to the console correctly 2024-03-22 17:40:51 +01:00
WerWolv
6a158f99d7 fix: Highlighting not updating correctly when changing bookmark region
Fixes #1591
2024-03-22 17:40:06 +01:00
WerWolv
77f46317f0 fix: Update all task progress not increasing correctly 2024-03-22 17:39:56 +01:00
WerWolv
4c98f6bca6 fix: View provider not saving top-level data to project file 2024-03-22 17:39:41 +01:00
WerWolv
77bc45ca17 fix: View provider not correctly saving its state to a project file 2024-03-22 17:39:17 +01:00
iTrooz
1647fa9446 fix: fix ui plugin linking to pl when libimhex already does it (#1583) 2024-03-22 17:38:27 +01:00
WerWolv
41a3fdaf3c fix: Updater not working correctly on Windows 2024-03-22 17:38:05 +01:00
iTrooz
e517406f06 fix: Use find_library() instead of find_file() to find system yara library (#1581)
Discord discussion:
https://discord.com/channels/789833418631675954/789840633414025246/1213564050848485427
2024-03-22 09:44:35 +01:00
38 changed files with 266 additions and 145 deletions

View File

@@ -1 +1 @@
1.33.1
1.33.2

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;

View File

@@ -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&) { }
}
}

View File

@@ -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;
};
}

View File

@@ -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;
}

View File

@@ -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
});
}

View File

@@ -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)

View File

@@ -65,7 +65,7 @@ namespace hex::log {
s_loggerFile.disableBuffering();
if (s_loggerFile.isValid()) {
s_colorOutputEnabled = true;
s_colorOutputEnabled = false;
break;
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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";

View File

@@ -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");
}
}
}

View File

@@ -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

View File

@@ -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());

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -1050,7 +1050,7 @@ namespace hex::plugin::builtin {
ImGui::SetClipboardText(
callback(
provider,
selection->getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress(),
selection->getStartAddress(),
selection->size
).c_str()
);

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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:

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -13,7 +13,6 @@ add_imhex_plugin(
INCLUDES
include
LIBRARIES
libpl
libpl-gen
fonts
LIBRARY_PLUGIN

View File

@@ -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);
}
};
}

View File

@@ -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

View File

@@ -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",

View File

@@ -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",

View File

@@ -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();
}
}