1
0
mirror of synced 2025-01-18 00:56:49 +01:00

sys/build: Properly support per-system metadata file paths (#181)

* sys: Move away from metadata paths next to executable in the application

Build system doesn't properly install / pack stuff yet

* build: Updated README to contain better install instructions

* sys: Search for imhex resource files in ~/Application Support

* sys: MAX_PATH -> PATH_MAX

* sys: Seach for imhex resource files in Application Support using NSFileManager (#180)

* sys: Allow for multiple file search paths

Also use install prefix instead of just /usr on Linux

* build: Fixed IMHEX_INSTALL_PREFIX macro definition

* build: Fix duplicate switch entry on Linux

* docs: Updated readme to properly reflect new paths and dependencies

* sys: Install files in their proper paths on linux (#183)

* Install files in their proper paths on linux

* Only create user directories

* Follow the XDG specification on linux

XDG specification specifies how to find config and data directories on
linux systems. Specifically, it says this:

- Data should be written to $XDG_DATA_HOME
- Config should be written to $XDG_CONFIG_HOME
- Data should be read from $XDG_DATA_HOME:$XDG_DATA_DIRS
- Config should be read from $XDG_CONFIG_HOME:$XDG_CONFIG_DIRS

The default values are this:

- XDG_DATA_HOME: $HOME/.local/share
- XDG_CONFIG_HOME: $HOME/.config
- XDG_DATA_DIRS: /usr/share:/usr/local/share
- XDG_CONFIG_DIRS: /etc/xdg

Platforms with non-standard filesystems (like NixOS) will correctly set
up those environment variables, allowing softwares to work unmodified.

In order to make integration as simple as possible, we use a simple
header-only dependency called XDGPP which does all the hard work for us
to find the default directories.

* Look for plugins in all Plugin Paths

If the plugin folder was missing from one of the PluginPaths, we would
immediately stop loading plugins. We now keep looking even if one of the
path is missing.

Co-authored-by: Nichole Mattera <me@nicholemattera.com>
Co-authored-by: Robin Lambertz <unfiltered@roblab.la>
This commit is contained in:
WerWolv 2021-03-01 08:56:49 +01:00 committed by GitHub
parent c26bea06d6
commit 3e6865ffa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 365 additions and 91 deletions

3
.gitmodules vendored
View File

@ -5,3 +5,6 @@
path = external/yara/yara
url = https://github.com/VirusTotal/yara
ignore = dirty
[submodule "external/xdgpp"]
path = external/xdgpp
url = https://git.sr.ht/~danyspin97/xdgpp

View File

@ -113,15 +113,14 @@ You need a C++20 compatible compiler such as GCC 10.2.0 to compile ImHex. Moreov
- libmagic, libgnurx, libtre, libintl, libiconv
- libcrypto
- capstone
- nlohmann json
- Python3
- freetype2
- Brew (macOS only)
- Xcode (macOS only)
### Windows and Linux
Find all-in-one dependency installation scripts for Arch Linux, Fedora, Debian/Ubuntu and/or MSYS2 in [dist](dist).
### Windows
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a mys2 window and run the PKGCONFIG script in the (dist/msys2)[dist/msys2] folder.
After all the dependencies are installed, run the following commands to build ImHex:
```sh
@ -135,8 +134,6 @@ make -j
To create a standalone zipfile on Windows, get the Python standard library (e.g. from https://github.com/python/cpython/tree/master/Lib) and place the files and folders in `lib/python3.8` next to your built executable. Don't forget to also copy the `libpython3.8.dll` and `libwinpthread-1.dll` from your mingw setup next to the executable.
On both Windows and Linux:
- Copy the files from `python_libs` in the `lib` folder next to your built executable.
- Place your magic databases in the `magic` folder next to your built executable
- Place your patterns in the `pattern` folder next to your built executable
@ -154,6 +151,47 @@ CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ PKG_CON
make -j
```
Install the ImHex executable as well as libimhex.dylib to wherever ImHex should be installed.
All other files belong in `~/Library/Application Support/imhex`:
```
Patterns: ~/Library/Application Support/imhex/patterns
Pattern Includes: ~/Library/Application Support/imhex/includes
Magic files: ~/Library/Application Support/imhex/magic
Python: ~/Library/Application Support/imhex/lib/pythonX.X
Plugins: ~/Library/Application Support/imhex/plugins
Configuration: ~/Library/Application Support/imhex/config
Resources: ~/Library/Application Support/imhex/resources
```
### Linux
Dependency installation scripts are available for many common Linux distributions in the (/dist)[dist] folder.
After all the dependencies are installed, run the following commands to build ImHex:
```sh
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j
```
---
Put the ImHex executable into the `/usr/bin` folder.
Put libimhex.so into the `/usr/lib` folder.
All other files belong in `/usr/share/imhex` or `~/.imhex`:
```
Patterns: /usr/share/imhex/patterns
Pattern Includes: /usr/share/imhex/includes
Magic files: /usr/share/imhex/magic
Python: /usr/share/imhex/lib/pythonX.X
Plugins: /usr/share/imhex/imhex/plugins
Configuration: /usr/share/imhex/config
Resources: /usr/share/imhex/resources
```
The `/usr` prefix can be customized by changing the cmake install path
## Credits
- Thanks a lot to ocornut for their amazing [Dear ImGui](https://github.com/ocornut/imgui) which is used for building the entire interface

View File

@ -71,10 +71,22 @@ endmacro()
macro(detectOS)
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_WINDOWS")
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
elseif(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_MACOS")
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
elseif(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_LINUX")
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
set(MAGIC_INSTALL_LOCATION "share/imhex/magic")
else()
message(FATAL_ERROR "Unknown / unsupported system!")
endif()
@ -145,11 +157,11 @@ macro(createPackage)
file(MAKE_DIRECTORY "plugins")
foreach (plugin IN LISTS PLUGINS)
add_subdirectory("plugins/${plugin}")
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
install(TARGETS ${plugin} DESTINATION ${PLUGINS_INSTALL_LOCATION})
add_dependencies(imhex ${plugin})
endforeach()
set_target_properties(libimhex PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
install(TARGETS libimhex DESTINATION ${CMAKE_INSTALL_LIBDIR})
if (WIN32)
# Install binaries directly in the prefix, usually C:\Program Files\ImHex.
@ -188,10 +200,7 @@ macro(createPackage)
endif()
if (UNIX AND NOT APPLE)
install(TARGETS libimhex DESTINATION ${CMAKE_INSTALL_PREFIX})
string(REPLACE ":" ";" EXTRA_MAGICDBS "${EXTRA_MAGICDBS}")
endif ()
if (NOT EXTRA_MAGICDBS STREQUAL "")
@ -199,9 +208,9 @@ macro(createPackage)
if (NOT EXTRA_MAGICDBS STREQUAL "NOTFOUND")
if (EXTRA_MAGICDBS MATCHES ".*\\.mgc")
install(FILES "${EXTRA_MAGICDBS}" DESTINATION magic/)
install(FILES "${EXTRA_MAGICDBS}" DESTINATION ${MAGIC_INSTALL_LOCATION})
else ()
install(FILES "${EXTRA_MAGICDBS}.mgc" DESTINATION magic/)
install(FILES "${EXTRA_MAGICDBS}.mgc" DESTINATION ${MAGIC_INSTALL_LOCATION})
endif ()
endif ()
endif ()
@ -214,12 +223,8 @@ macro(createPackage)
COMMAND file -C -m ${CMAKE_SOURCE_DIR}/magic_dbs
)
foreach (plugin IN LISTS PLUGINS)
install(FILES "$<TARGET_FILE:${plugin}>" DESTINATION plugins/)
endforeach ()
# Install the magicdb files.
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magic_dbs.mgc DESTINATION magic/ RENAME imhex.mgc)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magic_dbs.mgc DESTINATION ${MAGIC_INSTALL_LOCATION} RENAME imhex.mgc)
if (CREATE_BUNDLE)
include(PostprocessBundle)
@ -238,11 +243,7 @@ macro(createPackage)
install(TARGETS imhex BUNDLE DESTINATION .)
else()
if (WIN32)
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
else ()
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
endif ()
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

1
external/xdgpp vendored Submodule

@ -0,0 +1 @@
Subproject commit f01f810714443d0f10c333d4d1d9c0383be41375

View File

@ -36,6 +36,7 @@ namespace hex {
void drawWelcomeScreen();
void resetLayout();
void createDirectories() const;
void initGLFW();
void initImGui();
void deinitGLFW();

View File

@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 20)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/ImGui ${CMAKE_CURRENT_BINARY_DIR}/external/ImGui)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/nlohmann_json ${CMAKE_CURRENT_BINARY_DIR}/external/nlohmann_json)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/nativefiledialog ${CMAKE_CURRENT_BINARY_DIR}/external/nativefiledialog)
set(XDGPP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../external/xdgpp")
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive")
@ -16,34 +16,53 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
add_library(libimhex SHARED
source/api/event.cpp
source/api/imhex_api.cpp
source/api/content_registry.cpp
set(LIBIMHEX_SOURCES
source/api/event.cpp
source/api/imhex_api.cpp
source/api/content_registry.cpp
source/helpers/utils.cpp
source/helpers/shared_data.cpp
source/helpers/crypto.cpp
source/helpers/lang.cpp
source/helpers/utils.cpp
source/helpers/shared_data.cpp
source/helpers/crypto.cpp
source/helpers/lang.cpp
source/lang/pattern_language.cpp
source/lang/preprocessor.cpp
source/lang/lexer.cpp
source/lang/parser.cpp
source/lang/validator.cpp
source/lang/evaluator.cpp
source/lang/builtin_functions.cpp
source/lang/pattern_language.cpp
source/lang/preprocessor.cpp
source/lang/lexer.cpp
source/lang/parser.cpp
source/lang/validator.cpp
source/lang/evaluator.cpp
source/lang/builtin_functions.cpp
source/providers/provider.cpp
source/providers/provider.cpp
source/views/view.cpp
)
source/views/view.cpp
)
target_include_directories(libimhex PUBLIC include ${MBEDTLS_INCLUDE_DIR})
if (APPLE)
set(OSX_11_0_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk)
if (NOT CMAKE_OSX_SYSROOT)
if (IS_DIRECTORY ${OSX_11_0_SDK_PATH})
set(CMAKE_OSX_SYSROOT ${OSX_11_0_SDK_PATH})
else ()
message(WARNING "CMAKE_OSX_SYSROOT not set and macOS 10.9 SDK not found! Using default one.")
endif ()
endif ()
set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/utils_mac.mm)
endif ()
add_library(libimhex SHARED ${LIBIMHEX_SOURCES})
target_include_directories(libimhex PUBLIC include ${MBEDTLS_INCLUDE_DIR} ${XDGPP_INCLUDE_DIRS})
target_link_directories(libimhex PUBLIC ${MBEDTLS_LIBRARY_DIR})
if (WIN32)
target_link_libraries(libimhex PUBLIC imgui nlohmann_json libmbedcrypto.a nfd)
else ()
elseif (APPLE)
find_library(FOUNDATION NAMES Foundation)
target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto ${FOUNDATION} nfd)
else()
target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto nfd)
endif ()

View File

@ -224,10 +224,23 @@ namespace hex {
trimRight(s);
}
enum class ImHexPath {
Patterns,
PatternsInclude,
Magic,
Python,
Plugins,
Yara,
Config,
Resources
};
std::vector<std::string> getPath(ImHexPath path);
#define SCOPE_EXIT(func) ScopeExit TOKEN_CONCAT(scopeGuard, __COUNTER__)([&] { func })
class ScopeExit {
public:
ScopeExit(std::function<void()> func) : m_func(func) {}
ScopeExit(const std::function<void()> &func) : m_func(func) {}
~ScopeExit() { if (this->m_func != nullptr) this->m_func(); }
void release() {

View File

@ -0,0 +1,9 @@
#pragma once
#if defined(OS_MACOS)
#include <hex/helpers/utils.hpp>
namespace hex {
std::string getPathForMac(ImHexPath path);
}
#endif

View File

@ -10,15 +10,25 @@ namespace hex {
/* Settings */
void ContentRegistry::Settings::load() {
std::ifstream settingsFile(std::filesystem::path((SharedData::mainArgv)[0]).parent_path() / "settings.json");
for (const auto &dir : hex::getPath(ImHexPath::Config)) {
std::ifstream settingsFile(dir + "/settings.json");
if (settingsFile.good())
settingsFile >> getSettingsData();
if (settingsFile.good()) {
settingsFile >> getSettingsData();
break;
}
}
}
void ContentRegistry::Settings::store() {
std::ofstream settingsFile(std::filesystem::path((SharedData::mainArgv)[0]).parent_path() / "settings.json", std::ios::trunc);
settingsFile << getSettingsData();
for (const auto &dir : hex::getPath(ImHexPath::Config)) {
std::ofstream settingsFile(dir + "/settings.json", std::ios::trunc);
if (settingsFile.good()) {
settingsFile << getSettingsData();
break;
}
}
}
void ContentRegistry::Settings::add(std::string_view unlocalizedCategory, std::string_view unlocalizedName, s64 defaultValue, const std::function<bool(std::string_view, nlohmann::json&)> &callback) {

View File

@ -3,6 +3,15 @@
#include <cstdio>
#include <codecvt>
#include <locale>
#include <filesystem>
#if defined(OS_WINDOWS)
#include <windows.h>
#elif defined(OS_MACOS)
#include <hex/helpers/utils_mac.h>
#elif defined(OS_LINUX)
#include <xdg.hpp>
#endif
namespace hex {
@ -169,4 +178,78 @@ namespace hex {
}
std::vector<std::string> getPath(ImHexPath path) {
#if defined(OS_WINDOWS)
std::string exePath(MAX_PATH, '\0');
GetModuleFileName(nullptr, exePath.data(), exePath.length());
auto parentDir = std::filesystem::path(exePath).parent_path();
switch (path) {
case ImHexPath::Patterns:
return { (parentDir / "patterns").string() };
case ImHexPath::PatternsInclude:
return { (parentDir / "includes").string() };
case ImHexPath::Magic:
return { (parentDir / "magic").string() };
case ImHexPath::Python:
return { parentDir.string() };
case ImHexPath::Plugins:
return { (parentDir / "plugins").string() };
case ImHexPath::Yara:
return { (parentDir / "yara").string() };
case ImHexPath::Config:
return { (parentDir / "config").string() };
case ImHexPath::Resources:
return { (parentDir / "resources").string() };
default: __builtin_unreachable();
}
#elif defined(OS_MACOS)
return { getPathForMac(path) };
#else
std::vector<std::filesystem::path> configDirs = xdg::ConfigDirs();
std::vector<std::filesystem::path> dataDirs = xdg::DataDirs();
configDirs.insert(configDirs.begin(), xdg::ConfigHomeDir());
dataDirs.insert(dataDirs.begin(), xdg::DataHomeDir());
std::vector<std::string> result;
switch (path) {
case ImHexPath::Patterns:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "patterns").string(); });
return result;
case ImHexPath::PatternsInclude:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "includes").string(); });
return result;
case ImHexPath::Magic:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "magic").string(); });
return result;
case ImHexPath::Python:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex").string(); });
return result;
case ImHexPath::Plugins:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "plugins").string(); });
return result;
case ImHexPath::Yara:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "yara").string(); });
return result;
case ImHexPath::Config:
std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex").string(); });
return result;
case ImHexPath::Resources:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "imhex" / "resources").string(); });
return result;
default: __builtin_unreachable();
}
#endif
}
}

View File

@ -0,0 +1,56 @@
#if defined(OS_MACOS)
#include <hex/helpers/utils_mac.h>
#include <Foundation/Foundation.h>
namespace hex {
std::string getPathForMac(ImHexPath path) {
@autoreleasepool {
NSError * error = nil;
NSURL * appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:&error];
if (error != nil) {
__builtin_unreachable();
}
NSURL * result = nil;
switch (path) {
case ImHexPath::Patterns:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/patterns"];
break;
case ImHexPath::PatternsInclude:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/patterns"];
break;
case ImHexPath::Magic:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/magic"];
break;
case ImHexPath::Python:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex"];
break;
case ImHexPath::Plugins:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/plugins"];
break;
case ImHexPath::Yara:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/yara"];
break;
case ImHexPath::Config:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/config"];
break;
case ImHexPath::Resources:
result = [appSupportDir URLByAppendingPathComponent:@"/imhex/resources"];
break;
}
if (result == nil) {
__builtin_unreachable();
}
return std::string([[result path] UTF8String]);
}
}
}
#endif

View File

@ -1,5 +1,7 @@
#include <hex/lang/preprocessor.hpp>
#include <filesystem>
namespace hex::lang {
Preprocessor::Preprocessor() {
@ -47,8 +49,15 @@ namespace hex::lang {
}
offset += 1;
if (includeFile[0] != '/')
includeFile = "include/" + includeFile;
if (includeFile[0] != '/') {
std::string tempPath = includeFile;
for (const auto &dir : hex::getPath(ImHexPath::PatternsInclude)) {
tempPath = hex::format("%s/%s", dir.c_str(), includeFile.c_str());
if (std::filesystem::exists(includeFile))
break;
}
includeFile = tempPath;
}
FILE *file = fopen(includeFile.c_str(), "r");
if (file == nullptr)

View File

@ -179,8 +179,12 @@ namespace hex {
bool LoaderScript::processFile(std::string_view scriptPath) {
Py_SetProgramName(Py_DecodeLocale((SharedData::mainArgv)[0], nullptr));
if (std::filesystem::exists(std::filesystem::path((SharedData::mainArgv)[0]).parent_path().string() + "/lib/python" PYTHON_VERSION_MAJOR_MINOR))
Py_SetPythonHome(Py_DecodeLocale(std::filesystem::path((SharedData::mainArgv)[0]).parent_path().string().c_str(), nullptr));
for (const auto &dir : hex::getPath(ImHexPath::Python)) {
if (std::filesystem::exists(std::filesystem::path(dir + "/lib/python" PYTHON_VERSION_MAJOR_MINOR))) {
Py_SetPythonHome(Py_DecodeLocale(dir.c_str(), nullptr));
break;
}
}
PyImport_AppendInittab("_imhex", []() -> PyObject* {

View File

@ -86,9 +86,11 @@ namespace hex {
std::string magicFiles;
std::error_code error;
for (const auto &entry : std::filesystem::directory_iterator("magic", error)) {
if (entry.is_regular_file() && entry.path().extension() == ".mgc")
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
for (const auto &dir : hex::getPath(ImHexPath::Magic)) {
for (const auto &entry : std::filesystem::directory_iterator(dir, error)) {
if (entry.is_regular_file() && entry.path().extension() == ".mgc")
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
}
}
if (!error) {

View File

@ -106,9 +106,11 @@ namespace hex {
std::string magicFiles;
std::error_code error;
for (const auto &entry : std::filesystem::directory_iterator("magic", error)) {
if (entry.is_regular_file() && entry.path().extension() == ".mgc")
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
for (const auto &dir : hex::getPath(ImHexPath::Magic)) {
for (const auto &entry : std::filesystem::directory_iterator(dir, error)) {
if (entry.is_regular_file() && entry.path().extension() == ".mgc")
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
}
}
if (error)
@ -142,29 +144,32 @@ namespace hex {
std::error_code errorCode;
for (auto &entry : std::filesystem::directory_iterator("patterns", errorCode)) {
if (!entry.is_regular_file())
continue;
for (const auto &dir : hex::getPath(ImHexPath::Patterns)) {
for (auto &entry : std::filesystem::directory_iterator(dir, errorCode)) {
if (!entry.is_regular_file())
continue;
FILE *file = fopen(entry.path().string().c_str(), "r");
FILE *file = fopen(entry.path().string().c_str(), "r");
if (file == nullptr)
continue;
if (file == nullptr)
continue;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
std::vector<char> patternBuffer( size + 1, 0x00);
fread(patternBuffer.data(), 1, size, file);
fclose(file);
std::vector<char> patternBuffer( size + 1, 0x00);
fread(patternBuffer.data(), 1, size, file);
fclose(file);
preprocessor.preprocess(patternBuffer.data());
preprocessor.preprocess(patternBuffer.data());
if (foundCorrectType)
this->m_possiblePatternFiles.push_back(entry.path().filename().string());
if (foundCorrectType)
this->m_possiblePatternFiles.push_back(entry.path().string());
}
}
if (!this->m_possiblePatternFiles.empty()) {
this->m_selectedPatternFile = 0;
View::doLater([] { ImGui::OpenPopup("hex.view.pattern.accept_pattern"_lang); });
@ -297,7 +302,7 @@ namespace hex {
ImGui::Text("hex.view.pattern.accept_pattern.question"_lang);
confirmButtons("hex.common.yes"_lang, "hex.common.no"_lang, [this]{
this->loadPatternFile("patterns/" + this->m_possiblePatternFiles[this->m_selectedPatternFile]);
this->loadPatternFile(this->m_possiblePatternFiles[this->m_selectedPatternFile]);
ImGui::CloseCurrentPopup();
}, []{
ImGui::CloseCurrentPopup();

View File

@ -50,6 +50,7 @@ namespace hex {
hex::SharedData::mainArgc = argc;
hex::SharedData::mainArgv = argv;
this->createDirectories();
this->initGLFW();
this->initImGui();
@ -512,9 +513,18 @@ namespace hex {
ImGui::DockBuilderFinish(dockId);
}
void Window::initGLFW() {
void Window::createDirectories() const {
std::filesystem::create_directories(hex::getPath(ImHexPath::Patterns)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::PatternsInclude)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Magic)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Plugins)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Resources)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Config)[0]);
}
void Window::initGLFW() {
glfwSetErrorCallback([](int error, const char* desc) {
fprintf(stderr, "Glfw Error %d: %s\n", error, desc);
fprintf(stderr, "Glfw Error %d: %s\n", error, desc);
});
if (!glfwInit())
@ -645,16 +655,14 @@ namespace hex {
if (this->m_globalScale != 0.0f)
style.ScaleAllSizes(this->m_globalScale);
#if defined(OS_WINDOWS)
std::filesystem::path resourcePath = std::filesystem::path((SharedData::mainArgv)[0]).parent_path();
#elif defined(OS_LINUX) || defined(OS_MACOS)
std::filesystem::path resourcePath = "/usr/share/ImHex";
#else
std::filesystem::path resourcePath = "";
#warning "Unsupported OS for custom font support"
#endif
std::string fontFile;
for (const auto &dir : hex::getPath(ImHexPath::Resources)) {
fontFile = dir + "/font.ttf";
if (std::filesystem::exists(fontFile))
break;
}
if (!resourcePath.empty() && this->setFont(resourcePath / "font.ttf")) {
if (this->setFont(fontFile)) {
}
else {
@ -700,15 +708,27 @@ namespace hex {
handler.UserData = this;
ImGui::GetCurrentContext()->SettingsHandlers.push_back(handler);
static std::string iniFileName;
for (const auto &dir : hex::getPath(ImHexPath::Config)) {
if (std::filesystem::exists(dir)) {
iniFileName = dir + "/interface.ini";
break;
}
}
io.IniFilename = iniFileName.c_str();
ImGui_ImplGlfw_InitForOpenGL(this->m_window, true);
ImGui_ImplOpenGL3_Init("#version 150");
}
void Window::initPlugins() {
try {
auto pluginFolderPath = std::filesystem::path((SharedData::mainArgv)[0]).parent_path() / "plugins";
PluginHandler::load(pluginFolderPath.string());
} catch (std::runtime_error &e) { return; }
for (const auto &dir : hex::getPath(ImHexPath::Plugins)) {
try {
PluginHandler::load(dir);
} catch (std::runtime_error &e) {
// Plugin folder not found. Not a problem.
}
}
for (const auto &plugin : PluginHandler::getPlugins()) {
plugin.initializePlugin();