From ac964dc5ece057450abe2223e3f199b5e5499646 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 29 Jun 2022 21:34:17 +0200 Subject: [PATCH] fix: Path handling and plugin loading breaking with non-ASCII paths --- .../include/hex/api/plugin_manager.hpp | 12 +++++- lib/libimhex/source/api/plugin_manager.cpp | 38 ++++++++++++++----- lib/libimhex/source/helpers/fs.cpp | 30 +++++++-------- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/lib/libimhex/include/hex/api/plugin_manager.hpp b/lib/libimhex/include/hex/api/plugin_manager.hpp index 8ba02a031..4ed2dc45c 100644 --- a/lib/libimhex/include/hex/api/plugin_manager.hpp +++ b/lib/libimhex/include/hex/api/plugin_manager.hpp @@ -7,6 +7,12 @@ #include +#if defined(OS_WINDOWS) + #include +#else + #include +#endif + struct ImGuiContext; namespace hex { @@ -39,7 +45,11 @@ namespace hex { using SetImGuiContextFunc = void (*)(ImGuiContext *); using IsBuiltinPluginFunc = bool (*)(); - void *m_handle = nullptr; + #if defined(OS_WINDOWS) + HMODULE m_handle = nullptr; + #else + void *m_handle = nullptr; + #endif std::fs::path m_path; mutable bool m_initialized = false; diff --git a/lib/libimhex/source/api/plugin_manager.cpp b/lib/libimhex/source/api/plugin_manager.cpp index 5ff04a89e..95c3f120a 100644 --- a/lib/libimhex/source/api/plugin_manager.cpp +++ b/lib/libimhex/source/api/plugin_manager.cpp @@ -3,17 +3,26 @@ #include #include -#include +#include namespace hex { Plugin::Plugin(const std::fs::path &path) : m_path(path) { - this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY); + #if defined(OS_WINDOWS) + this->m_handle = LoadLibraryW(path.c_str()); - if (this->m_handle == nullptr) { - log::error("dlopen failed: {}", dlerror()); - return; - } + if (this->m_handle == nullptr) { + log::error("LoadLibraryW failed: {}!", std::system_category().message(::GetLastError())); + return; + } + #else + this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY); + + if (this->m_handle == nullptr) { + log::error("dlopen failed: {}!", dlerror()); + return; + } + #endif auto pluginName = std::fs::path(path).stem().string(); @@ -49,8 +58,13 @@ namespace hex { } Plugin::~Plugin() { - if (this->m_handle != nullptr) - dlclose(this->m_handle); + #if defined(OS_WINDOWS) + if (this->m_handle != nullptr) + FreeLibrary(this->m_handle); + #else + if (this->m_handle != nullptr) + dlclose(this->m_handle); + #endif } bool Plugin::initializePlugin() const { @@ -120,7 +134,11 @@ namespace hex { void *Plugin::getPluginFunction(const std::string &symbol) { - return dlsym(this->m_handle, symbol.c_str()); + #if defined(OS_WINDOWS) + return reinterpret_cast(GetProcAddress(this->m_handle, symbol.c_str())); + #else + return dlsym(this->m_handle, symbol.c_str()); + #endif } @@ -135,7 +153,7 @@ namespace hex { for (auto &pluginPath : std::fs::directory_iterator(pluginFolder)) { if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug") - PluginManager::s_plugins.emplace_back(pluginPath.path().string()); + PluginManager::s_plugins.emplace_back(pluginPath.path()); } if (PluginManager::s_plugins.empty()) diff --git a/lib/libimhex/source/helpers/fs.cpp b/lib/libimhex/source/helpers/fs.cpp index 1f8159764..b03947d3f 100644 --- a/lib/libimhex/source/helpers/fs.cpp +++ b/lib/libimhex/source/helpers/fs.cpp @@ -22,8 +22,8 @@ namespace hex::fs { std::optional getExecutablePath() { #if defined(OS_WINDOWS) - std::string exePath(MAX_PATH, '\0'); - if (GetModuleFileName(nullptr, exePath.data(), exePath.length()) == 0) + std::wstring exePath(MAX_PATH, '\0'); + if (GetModuleFileNameW(nullptr, exePath.data(), exePath.length()) == 0) return std::nullopt; return exePath; @@ -113,11 +113,11 @@ namespace hex::fs { #if defined(OS_WINDOWS) std::fs::path appDataDir; { - LPWSTR wAppDataPath = nullptr; + PWSTR wAppDataPath = nullptr; if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) throw std::runtime_error("Failed to get APPDATA folder path"); - appDataDir = wAppDataPath; + appDataDir = std::wstring(wAppDataPath); CoTaskMemFree(wAppDataPath); } @@ -130,60 +130,60 @@ namespace hex::fs { case ImHexPath::Patterns: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "patterns").string(); + return path / "patterns"; }); break; case ImHexPath::PatternsInclude: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "includes").string(); + return path / "includes"; }); break; case ImHexPath::Magic: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "magic").string(); + return path / "magic"; }); break; case ImHexPath::Python: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "python").string(); + return path / "python"; }); break; case ImHexPath::Plugins: std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "plugins").string(); + return path / "plugins"; }); break; case ImHexPath::Yara: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "yara").string(); + return path / "yara"; }); break; case ImHexPath::Config: - return { (appDataDir / "imhex" / "config").string() }; + return { appDataDir / "imhex" / "config" }; case ImHexPath::Resources: std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "resources").string(); + return path / "resources"; }); break; case ImHexPath::Constants: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "constants").string(); + return path / "constants"; }); break; case ImHexPath::Encodings: addUserDirs(paths); std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "encodings").string(); + return path / "encodings"; }); break; case ImHexPath::Logs: std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return (path / "logs").string(); + return path / "logs"; }); break; default: