fix: Replace old defaults path system with a new one

#1767
This commit is contained in:
WerWolv 2024-06-22 10:44:55 +02:00
parent beef0fff33
commit b60a262b58
41 changed files with 461 additions and 356 deletions

View File

@ -36,6 +36,7 @@ set(LIBIMHEX_SOURCES
source/helpers/logger.cpp source/helpers/logger.cpp
source/helpers/tar.cpp source/helpers/tar.cpp
source/helpers/debugging.cpp source/helpers/debugging.cpp
source/helpers/default_paths.cpp
source/test/tests.cpp source/test/tests.cpp

View File

@ -0,0 +1,111 @@
#pragma once
#include <hex/helpers/fs.hpp>
#include <vector>
namespace hex::paths {
namespace impl {
class DefaultPath {
protected:
constexpr DefaultPath() = default;
virtual ~DefaultPath() = default;
public:
DefaultPath(const DefaultPath&) = delete;
DefaultPath(DefaultPath&&) = delete;
DefaultPath& operator=(const DefaultPath&) = delete;
DefaultPath& operator=(DefaultPath&&) = delete;
virtual std::vector<std::fs::path> all() const = 0;
virtual std::vector<std::fs::path> read() const;
virtual std::vector<std::fs::path> write() const;
};
class ConfigPath : public DefaultPath {
public:
explicit ConfigPath(std::fs::path postfix) : m_postfix(std::move(postfix)) {}
std::vector<std::fs::path> all() const override;
private:
std::fs::path m_postfix;
};
class DataPath : public DefaultPath {
public:
explicit DataPath(std::fs::path postfix) : m_postfix(std::move(postfix)) {}
std::vector<std::fs::path> all() const override;
std::vector<std::fs::path> write() const override;
private:
std::fs::path m_postfix;
};
class PluginPath : public DefaultPath {
public:
explicit PluginPath(std::fs::path postfix) : m_postfix(std::move(postfix)) {}
std::vector<std::fs::path> all() const override;
private:
std::fs::path m_postfix;
};
}
std::vector<std::fs::path> getDataPaths(bool includeSystemFolders);
std::vector<std::fs::path> getConfigPaths(bool includeSystemFolders);
const static inline impl::ConfigPath Config("config");
const static inline impl::ConfigPath Recent("recent");
const static inline impl::PluginPath Libraries("lib");
const static inline impl::PluginPath Plugins("plugins");
const static inline impl::DataPath Patterns("patterns");
const static inline impl::DataPath PatternsInclude("patterns/include");
const static inline impl::DataPath Magic("magic");
const static inline impl::DataPath Yara("yara");
const static inline impl::DataPath YaraAdvancedAnalysis("yara/advanced_analysis");
const static inline impl::DataPath Backups("backups");
const static inline impl::DataPath Resources("resources");
const static inline impl::DataPath Constants("constants");
const static inline impl::DataPath Encodings("encodings");
const static inline impl::DataPath Logs("logs");
const static inline impl::DataPath Scripts("scripts");
const static inline impl::DataPath Inspectors("scripts/inspectors");
const static inline impl::DataPath Themes("themes");
const static inline impl::DataPath Nodes("scripts/nodes");
const static inline impl::DataPath Layouts("layouts");
const static inline impl::DataPath Workspaces("workspaces");
constexpr static inline std::array<const impl::DefaultPath*, 20> All = {
&Config,
&Recent,
&Libraries,
&Plugins,
&Patterns,
&PatternsInclude,
&Magic,
&Yara,
&YaraAdvancedAnalysis,
&Backups,
&Resources,
&Constants,
&Encodings,
&Logs,
&Scripts,
&Inspectors,
&Themes,
&Nodes,
&Layouts,
&Workspaces,
};
}

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <hex.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include <filesystem> #include <filesystem>
@ -31,36 +29,7 @@ namespace hex::fs {
void openFolderExternal(const std::fs::path &dirPath); void openFolderExternal(const std::fs::path &dirPath);
void openFolderWithSelectionExternal(const std::fs::path &selectedFilePath); void openFolderWithSelectionExternal(const std::fs::path &selectedFilePath);
enum class ImHexPath : u32 {
Patterns = 0,
PatternsInclude,
Magic,
Plugins,
Yara,
YaraAdvancedAnalysis,
Config,
Backups,
Resources,
Constants,
Encodings,
Logs,
Recent,
Scripts,
Inspectors,
Themes,
Libraries,
Nodes,
Layouts,
Workspaces,
END
};
bool isPathWritable(const std::fs::path &path); bool isPathWritable(const std::fs::path &path);
std::vector<std::fs::path> getDefaultPaths(ImHexPath path, bool listNonExisting = false);
// Temporarily expose these for the migration function
std::vector<std::fs::path> getDataPaths();
std::vector<std::fs::path> appendPath(std::vector<std::fs::path> paths, const std::fs::path &folder);
} }

View File

@ -2,6 +2,7 @@
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/helpers/auto_reset.hpp> #include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/default_paths.hpp>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
@ -197,7 +198,7 @@ namespace hex {
constexpr static auto AchievementsFile = "achievements.json"; constexpr static auto AchievementsFile = "achievements.json";
void AchievementManager::loadProgress() { void AchievementManager::loadProgress() {
for (const auto &directory : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &directory : paths::Config.read()) {
auto path = directory / AchievementsFile; auto path = directory / AchievementsFile;
if (!wolv::io::fs::exists(path)) { if (!wolv::io::fs::exists(path)) {
@ -246,7 +247,7 @@ namespace hex {
if (json.empty()) if (json.empty())
return; return;
for (const auto &directory : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &directory : paths::Config.write()) {
auto path = directory / AchievementsFile; auto path = directory / AchievementsFile;
wolv::io::File file(path, wolv::io::File::Mode::Create); wolv::io::File file(path, wolv::io::File::Mode::Create);

View File

@ -4,6 +4,7 @@
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/auto_reset.hpp> #include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/ui/view.hpp> #include <hex/ui/view.hpp>
#include <hex/data_processor/node.hpp> #include <hex/data_processor/node.hpp>
@ -101,7 +102,7 @@ namespace hex {
void load() { void load() {
bool loaded = false; bool loaded = false;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &dir : paths::Config.read()) {
wolv::io::File file(dir / SettingsFile, wolv::io::File::Mode::Read); wolv::io::File file(dir / SettingsFile, wolv::io::File::Mode::Read);
if (file.isValid()) { if (file.isValid()) {
@ -142,7 +143,7 @@ namespace hex {
if (result.empty()) { if (result.empty()) {
return; return;
} }
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &dir : paths::Config.write()) {
wolv::io::File file(dir / SettingsFile, wolv::io::File::Mode::Create); wolv::io::File file(dir / SettingsFile, wolv::io::File::Mode::Create);
if (file.isValid()) { if (file.isValid()) {
@ -153,7 +154,7 @@ namespace hex {
} }
void clear() { void clear() {
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &dir : paths::Config.write()) {
wolv::io::fs::remove(dir / SettingsFile); wolv::io::fs::remove(dir / SettingsFile);
} }
} }
@ -595,7 +596,7 @@ namespace hex {
); );
} }
runtime.setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude) | fs::getDefaultPaths(fs::ImHexPath::Patterns)); runtime.setIncludePaths(paths::PatternsInclude.read() | paths::Patterns.read());
for (const auto &[ns, name, paramCount, callback, dangerous] : impl::getFunctions()) { for (const auto &[ns, name, paramCount, callback, dangerous] : impl::getFunctions()) {
if (dangerous) if (dangerous)

View File

@ -1,13 +1,15 @@
#include <hex/api/layout_manager.hpp> #include <hex/api/layout_manager.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/ui/view.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/auto_reset.hpp> #include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/api/content_registry.hpp>
#include <hex/ui/view.hpp>
namespace hex { namespace hex {
@ -40,10 +42,7 @@ namespace hex {
fileName += ".hexlyt"; fileName += ".hexlyt";
std::fs::path layoutPath; std::fs::path layoutPath;
for (const auto &path : hex::fs::getDefaultPaths(fs::ImHexPath::Layouts)) { for (const auto &path : paths::Layouts.write()) {
if (!hex::fs::isPathWritable(path))
continue;
layoutPath = path / fileName; layoutPath = path / fileName;
} }
@ -109,7 +108,7 @@ namespace hex {
void LayoutManager::reload() { void LayoutManager::reload() {
s_layouts->clear(); s_layouts->clear();
for (const auto &directory : hex::fs::getDefaultPaths(fs::ImHexPath::Layouts)) { for (const auto &directory : paths::Layouts.read()) {
for (const auto &entry : std::fs::directory_iterator(directory)) { for (const auto &entry : std::fs::directory_iterator(directory)) {
const auto &path = entry.path(); const auto &path = entry.path();

View File

@ -5,6 +5,7 @@
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/auto_reset.hpp> #include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
@ -306,7 +307,7 @@ namespace hex {
bool PluginManager::loadLibraries() { bool PluginManager::loadLibraries() {
bool success = true; bool success = true;
for (const auto &loadPath : fs::getDefaultPaths(fs::ImHexPath::Libraries)) for (const auto &loadPath : paths::Libraries.read())
success = PluginManager::loadLibraries(loadPath) && success; success = PluginManager::loadLibraries(loadPath) && success;
return success; return success;

View File

@ -3,6 +3,7 @@
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/auto_reset.hpp> #include <hex/helpers/auto_reset.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
@ -25,7 +26,7 @@ namespace hex {
.builtin = false .builtin = false
}).first; }).first;
for (const auto &workspaceFolder : fs::getDefaultPaths(fs::ImHexPath::Workspaces)) { for (const auto &workspaceFolder : paths::Workspaces.write()) {
const auto workspacePath = workspaceFolder / (name + ".hexws"); const auto workspacePath = workspaceFolder / (name + ".hexws");
if (exportToFile(workspacePath)) { if (exportToFile(workspacePath)) {
s_currentWorkspace->second.path = workspacePath; s_currentWorkspace->second.path = workspacePath;
@ -157,7 +158,7 @@ namespace hex {
void WorkspaceManager::reload() { void WorkspaceManager::reload() {
WorkspaceManager::reset(); WorkspaceManager::reset();
for (const auto &defaultPath : fs::getDefaultPaths(fs::ImHexPath::Workspaces)) { for (const auto &defaultPath : paths::Workspaces.read()) {
for (const auto &entry : std::fs::directory_iterator(defaultPath)) { for (const auto &entry : std::fs::directory_iterator(defaultPath)) {
if (!entry.is_regular_file()) { if (!entry.is_regular_file()) {
continue; continue;

View File

@ -0,0 +1,150 @@
#include <hex/helpers/default_paths.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/project_file_manager.hpp>
#if defined(OS_WINDOWS)
#include <windows.h>
#include <shlobj.h>
#elif defined(OS_LINUX) || defined(OS_WEB)
#include <xdg.hpp>
# endif
namespace hex::paths {
std::vector<std::fs::path> getDataPaths(bool includeSystemFolders) {
std::vector<std::fs::path> paths;
#if defined(OS_WINDOWS)
// In the portable Windows version, we just use the executable directory
// Prevent the use of the AppData folder here
if (!ImHexApi::System::isPortableVersion()) {
PWSTR wAppDataPath = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) {
paths.emplace_back(wAppDataPath);
CoTaskMemFree(wAppDataPath);
}
}
#elif defined(OS_MACOS)
paths.push_back(wolv::io::fs::getApplicationSupportDirectoryPath());
#elif defined(OS_LINUX) || defined(OS_WEB)
paths.push_back(xdg::DataHomeDir());
auto dataDirs = xdg::DataDirs();
std::copy(dataDirs.begin(), dataDirs.end(), std::back_inserter(paths));
#endif
#if defined(OS_MACOS)
if (includeSystemFolders) {
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) {
paths.push_back(*executablePath);
}
}
#else
for (auto &path : paths)
path = path / "imhex";
if (ImHexApi::System::isPortableVersion() || includeSystemFolders) {
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value())
paths.push_back(executablePath->parent_path());
}
#endif
// Add additional data directories to the path
auto additionalDirs = ImHexApi::System::getAdditionalFolderPaths();
std::ranges::copy(additionalDirs, std::back_inserter(paths));
// Add the project file directory to the path, if one is loaded
if (ProjectFile::hasPath()) {
paths.push_back(ProjectFile::getPath().parent_path());
}
return paths;
}
std::vector<std::fs::path> getConfigPaths(bool includeSystemFolders) {
#if defined(OS_WINDOWS)
return getDataPaths(includeSystemFolders);
#elif defined(OS_MACOS)
return getDataPaths(includeSystemFolders);
#elif defined(OS_LINUX) || defined(OS_WEB)
return {xdg::ConfigHomeDir() / "imhex"};
#endif
}
static std::vector<std::fs::path> appendPath(std::vector<std::fs::path> paths, const std::fs::path &folder) {
for (auto &path : paths)
path = path / folder;
return paths;
}
static std::vector<std::fs::path> getPluginPaths() {
std::vector<std::fs::path> paths = getDataPaths(true);
// Add the system plugin directory to the path if one was provided at compile time
#if defined(OS_LINUX) && defined(SYSTEM_PLUGINS_LOCATION)
paths.push_back(SYSTEM_PLUGINS_LOCATION);
#endif
return paths;
}
namespace impl {
std::vector<std::fs::path> DefaultPath::read() const {
auto result = this->all();
std::erase_if(result, [](const auto &entryPath) {
return !wolv::io::fs::isDirectory(entryPath);
});
return result;
}
std::vector<std::fs::path> DefaultPath::write() const {
auto result = this->read();
std::erase_if(result, [](const auto &entryPath) {
return !hex::fs::isPathWritable(entryPath);
});
return result;
}
std::vector<std::fs::path> ConfigPath::all() const {
return appendPath(getConfigPaths(false), m_postfix);
}
std::vector<std::fs::path> DataPath::all() const {
return appendPath(getConfigPaths(true), m_postfix);
}
std::vector<std::fs::path> DataPath::write() const {
auto result = appendPath(getConfigPaths(false), m_postfix);
std::erase_if(result, [](const auto &entryPath) {
return !hex::fs::isPathWritable(entryPath);
});
return result;
}
std::vector<std::fs::path> PluginPath::all() const {
return appendPath(getPluginPaths(), m_postfix);
}
}
}

View File

@ -286,170 +286,6 @@ namespace hex::fs {
#endif #endif
std::vector<std::fs::path> getDataPaths() {
std::vector<std::fs::path> paths;
#if defined(OS_WINDOWS)
// In the portable Windows version, we just use the executable directory
// Prevent the use of the AppData folder here
if (!ImHexApi::System::isPortableVersion()) {
PWSTR wAppDataPath = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) {
paths.emplace_back(wAppDataPath);
CoTaskMemFree(wAppDataPath);
}
}
#elif defined(OS_MACOS)
paths.push_back(wolv::io::fs::getApplicationSupportDirectoryPath());
#elif defined(OS_LINUX) || defined(OS_WEB)
paths.push_back(xdg::DataHomeDir());
auto dataDirs = xdg::DataDirs();
std::copy(dataDirs.begin(), dataDirs.end(), std::back_inserter(paths));
#endif
#if defined(OS_MACOS)
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value())
paths.push_back(*executablePath);
#else
for (auto &path : paths)
path = path / "imhex";
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value())
paths.push_back(executablePath->parent_path());
#endif
// Add additional data directories to the path
auto additionalDirs = ImHexApi::System::getAdditionalFolderPaths();
std::ranges::copy(additionalDirs, std::back_inserter(paths));
// Add the project file directory to the path, if one is loaded
if (ProjectFile::hasPath()) {
paths.push_back(ProjectFile::getPath().parent_path());
}
return paths;
}
static std::vector<std::fs::path> getConfigPaths() {
#if defined(OS_WINDOWS)
return getDataPaths();
#elif defined(OS_MACOS)
return getDataPaths();
#elif defined(OS_LINUX) || defined(OS_WEB)
return {xdg::ConfigHomeDir() / "imhex"};
#endif
}
std::vector<std::fs::path> appendPath(std::vector<std::fs::path> paths, const std::fs::path &folder) {
for (auto &path : paths)
path = path / folder;
return paths;
}
std::vector<std::fs::path> getPluginPaths() {
std::vector<std::fs::path> paths = getDataPaths();
// Add the system plugin directory to the path if one was provided at compile time
#if defined(OS_LINUX) && defined(SYSTEM_PLUGINS_LOCATION)
paths.push_back(SYSTEM_PLUGINS_LOCATION);
#endif
return paths;
}
std::vector<std::fs::path> getDefaultPaths(ImHexPath path, bool listNonExisting) {
std::vector<std::fs::path> result;
// Return the correct path based on the ImHexPath enum
switch (path) {
case ImHexPath::END:
return { };
case ImHexPath::Constants:
result = appendPath(getDataPaths(), "constants");
break;
case ImHexPath::Config:
result = appendPath(getConfigPaths(), "config");
break;
case ImHexPath::Backups:
result = appendPath(getDataPaths(), "backups");
break;
case ImHexPath::Encodings:
result = appendPath(getDataPaths(), "encodings");
break;
case ImHexPath::Logs:
result = appendPath(getDataPaths(), "logs");
break;
case ImHexPath::Plugins:
result = appendPath(getPluginPaths(), "plugins");
break;
case ImHexPath::Libraries:
result = appendPath(getPluginPaths(), "lib");
break;
case ImHexPath::Resources:
result = appendPath(getDataPaths(), "resources");
break;
case ImHexPath::Magic:
result = appendPath(getDataPaths(), "magic");
break;
case ImHexPath::Patterns:
result = appendPath(getDataPaths(), "patterns");
break;
case ImHexPath::PatternsInclude:
result = appendPath(getDataPaths(), "includes");
break;
case ImHexPath::Yara:
result = appendPath(getDataPaths(), "yara");
break;
case ImHexPath::YaraAdvancedAnalysis:
result = appendPath(getDefaultPaths(ImHexPath::Yara), "advanced_analysis");
break;
case ImHexPath::Recent:
result = appendPath(getConfigPaths(), "recent");
break;
case ImHexPath::Scripts:
result = appendPath(getDataPaths(), "scripts");
break;
case ImHexPath::Inspectors:
result = appendPath(getDefaultPaths(ImHexPath::Scripts), "inspectors");
break;
case ImHexPath::Nodes:
result = appendPath(getDefaultPaths(ImHexPath::Scripts), "nodes");
break;
case ImHexPath::Themes:
result = appendPath(getDataPaths(), "themes");
break;
case ImHexPath::Layouts:
result = appendPath(getDataPaths(), "layouts");
break;
case ImHexPath::Workspaces:
result = appendPath(getDataPaths(), "workspaces");
break;
}
// Remove all paths that don't exist if requested
if (!listNonExisting) {
std::erase_if(result, [](const auto &entryPath) {
return !wolv::io::fs::isDirectory(entryPath);
});
}
return result;
}
bool isPathWritable(const std::fs::path &path) { bool isPathWritable(const std::fs::path &path) {
constexpr static auto TestFileName = "__imhex__tmp__"; constexpr static auto TestFileName = "__imhex__tmp__";

View File

@ -2,8 +2,10 @@
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
@ -80,7 +82,7 @@ namespace hex::log {
void redirectToFile() { void redirectToFile() {
if (s_loggerFile.isValid()) return; if (s_loggerFile.isValid()) return;
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Logs, true)) { for (const auto &path : paths::Logs.all()) {
wolv::io::fs::createDirectories(path); wolv::io::fs::createDirectories(path);
s_loggerFile = wolv::io::File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))), wolv::io::File::Mode::Create); s_loggerFile = wolv::io::File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))), wolv::io::File::Mode::Create);
s_loggerFile.disableBuffering(); s_loggerFile.disableBuffering();

View File

@ -3,6 +3,7 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/guards.hpp> #include <wolv/utils/guards.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
@ -29,7 +30,7 @@ namespace hex::magic {
std::string magicFiles; std::string magicFiles;
std::error_code error; std::error_code error;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Magic)) { for (const auto &dir : paths::Magic.read()) {
for (const auto &entry : std::fs::directory_iterator(dir, error)) { for (const auto &entry : std::fs::directory_iterator(dir, error)) {
auto path = std::fs::absolute(entry.path()); auto path = std::fs::absolute(entry.path());
@ -64,12 +65,12 @@ namespace hex::magic {
if (magicFiles->empty()) if (magicFiles->empty())
return true; return true;
std::array<char, 1024> cwd = { 0x00 }; std::array<char, 1024> cwd = { };
if (getcwd(cwd.data(), cwd.size()) == nullptr) if (getcwd(cwd.data(), cwd.size()) == nullptr)
return false; return false;
std::optional<std::fs::path> magicFolder; std::optional<std::fs::path> magicFolder;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Magic)) { for (const auto &dir : paths::Magic.write()) {
if (std::fs::exists(dir) && fs::isPathWritable(dir)) { if (std::fs::exists(dir) && fs::isPathWritable(dir)) {
magicFolder = dir; magicFolder = dir;
break; break;

View File

@ -2,19 +2,19 @@
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/api/workspace_manager.hpp> #include <hex/api/workspace_manager.hpp>
#include <init/tasks.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
#include <window.hpp> #include <window.hpp>
#include <init/tasks.hpp>
#include <nlohmann/json.hpp>
#include <stacktrace.hpp> #include <stacktrace.hpp>
#include <llvm/Demangle/Demangle.h> #include <llvm/Demangle/Demangle.h>
#include <nlohmann/json.hpp>
#include <csignal> #include <csignal>
#include <exception> #include <exception>
@ -48,7 +48,7 @@ namespace hex::crash {
{ "project", wolv::io::fs::toNormalizedPathString(ProjectFile::getPath()) }, { "project", wolv::io::fs::toNormalizedPathString(ProjectFile::getPath()) },
}; };
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &path : paths::Config.write()) {
wolv::io::File file(path / "crash.json", wolv::io::File::Mode::Create); wolv::io::File file(path / "crash.json", wolv::io::File::Mode::Create);
if (file.isValid()) { if (file.isValid()) {
file.writeString(crashData.dump(4)); file.writeString(crashData.dump(4));
@ -194,7 +194,7 @@ namespace hex::crash {
// Create crash backup if any providers are open // Create crash backup if any providers are open
if (ImHexApi::Provider::isValid()) { if (ImHexApi::Provider::isValid()) {
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &path : paths::Config.write()) {
if (ProjectFile::store(path / CrashBackupFileName, false)) if (ProjectFile::store(path / CrashBackupFileName, false))
break; break;
} }

View File

@ -5,6 +5,7 @@
#include <hex/api/plugin_manager.hpp> #include <hex/api/plugin_manager.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/guards.hpp> #include <wolv/utils/guards.hpp>
@ -60,7 +61,7 @@ namespace hex::init {
// Load all plugins but don't initialize them // Load all plugins but don't initialize them
PluginManager::loadLibraries(); PluginManager::loadLibraries();
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Plugins)) { for (const auto &dir : paths::Plugins.read()) {
PluginManager::load(dir); PluginManager::load(dir);
} }

View File

@ -7,6 +7,7 @@
#include <hex/helpers/http_requests.hpp> #include <hex/helpers/http_requests.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/api/plugin_manager.hpp> #include <hex/api/plugin_manager.hpp>
@ -33,11 +34,9 @@ namespace hex::init {
bool createDirectories() { bool createDirectories() {
bool result = true; bool result = true;
using enum fs::ImHexPath;
// Try to create all default directories // Try to create all default directories
for (u32 path = 0; path < u32(fs::ImHexPath::END); path++) { for (auto path : paths::All) {
for (auto &folder : fs::getDefaultPaths(static_cast<fs::ImHexPath>(path), true)) { for (auto &folder : path->all()) {
try { try {
wolv::io::fs::createDirectories(folder); wolv::io::fs::createDirectories(folder);
} catch (...) { } catch (...) {
@ -95,7 +94,7 @@ namespace hex::init {
bool loadPlugins() { bool loadPlugins() {
// Load all plugins // Load all plugins
#if !defined(IMHEX_STATIC_LINK_PLUGINS) #if !defined(IMHEX_STATIC_LINK_PLUGINS)
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Plugins)) { for (const auto &dir : paths::Plugins.read()) {
PluginManager::addLoadPath(dir); PluginManager::addLoadPath(dir);
} }
@ -185,8 +184,8 @@ namespace hex::init {
bool deleteOldFiles() { bool deleteOldFiles() {
bool result = true; bool result = true;
auto keepNewest = [&](u32 count, fs::ImHexPath pathType) { auto keepNewest = [&](u32 count, const paths::impl::DefaultPath &pathType) {
for (const auto &path : fs::getDefaultPaths(pathType)) { for (const auto &path : pathType.write()) {
try { try {
std::vector<std::filesystem::directory_entry> files; std::vector<std::filesystem::directory_entry> files;
@ -209,8 +208,8 @@ namespace hex::init {
} }
}; };
keepNewest(10, fs::ImHexPath::Logs); keepNewest(10, paths::Logs);
keepNewest(25, fs::ImHexPath::Backups); keepNewest(25, paths::Backups);
return result; return result;
} }

View File

@ -1,14 +1,14 @@
#include <hex/api/project_file_manager.hpp>
#include "window.hpp" #include "window.hpp"
#if defined(OS_MACOS) #if defined(OS_MACOS)
#include <hex/api/project_file_manager.hpp>
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/helpers/utils_macos.hpp> #include <hex/helpers/utils_macos.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <cstdio> #include <cstdio>
#include <unistd.h> #include <unistd.h>
@ -35,7 +35,7 @@ namespace hex {
log::impl::enableColorPrinting(); log::impl::enableColorPrinting();
// Add plugin library folders to dll search path // Add plugin library folders to dll search path
for (const auto &path : hex::fs::getDefaultPaths(fs::ImHexPath::Libraries)) { for (const auto &path : paths::Libraries.read()) {
if (std::fs::exists(path)) if (std::fs::exists(path))
setenv("LD_LIBRARY_PATH", hex::format("{};{}", hex::getEnvironmentVariable("LD_LIBRARY_PATH").value_or(""), path.string().c_str()).c_str(), true); setenv("LD_LIBRARY_PATH", hex::format("{};{}", hex::getEnvironmentVariable("LD_LIBRARY_PATH").value_or(""), path.string().c_str()).c_str(), true);
} }

View File

@ -1,11 +1,13 @@
#include "window.hpp" #include "window.hpp"
#include "messaging.hpp"
#if defined(OS_WINDOWS) #if defined(OS_WINDOWS)
#include <hex/helpers/utils.hpp> #include "messaging.hpp"
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
@ -352,7 +354,7 @@ namespace hex {
} }
// Add plugin library folders to dll search path // Add plugin library folders to dll search path
for (const auto &path : hex::fs::getDefaultPaths(fs::ImHexPath::Libraries)) { for (const auto &path : paths::Libraries.read()) {
if (std::fs::exists(path)) if (std::fs::exists(path))
AddDllDirectory(path.c_str()); AddDllDirectory(path.c_str());
} }

View File

@ -13,6 +13,7 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/ui/view.hpp> #include <hex/ui/view.hpp>
#include <hex/ui/popup.hpp> #include <hex/ui/popup.hpp>
@ -331,7 +332,7 @@ namespace hex {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Plugins, true)) { for (const auto &path : paths::Plugins.all()) {
const auto filePath = path / "builtin.hexplug"; const auto filePath = path / "builtin.hexplug";
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
@ -867,8 +868,11 @@ namespace hex {
// If the key name is only one character long, use the ASCII value instead // If the key name is only one character long, use the ASCII value instead
// Otherwise the keyboard was set to a non-English layout and the key name // Otherwise the keyboard was set to a non-English layout and the key name
// is not the same as the ASCII value // is not the same as the ASCII value
if (name.length() == 1) { if (!name.empty()) {
key = std::toupper(name[0]); const std::uint8_t byte = name[0];
if (name.length() == 1 && byte <= 0x7F) {
key = std::toupper(byte);
}
} }
} }

View File

@ -3,6 +3,7 @@
#include <hex/helpers/http_requests.hpp> #include <hex/helpers/http_requests.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/default_paths.hpp>
using namespace std::literals::string_literals; using namespace std::literals::string_literals;
@ -46,7 +47,7 @@ std::optional<std::fs::path> downloadUpdate(const std::string &url) {
// Loop over all available paths // Loop over all available paths
wolv::io::File file; wolv::io::File file;
for (const auto &path : hex::fs::getDefaultPaths(hex::fs::ImHexPath::Config)) { for (const auto &path : hex::paths::Config.write()) {
// Remove any existing update files // Remove any existing update files
wolv::io::fs::remove(path / UpdateFileName); wolv::io::fs::remove(path / UpdateFileName);

View File

@ -1,8 +1,10 @@
#pragma once #pragma once
#include <hex/api/achievement_manager.hpp>
#include <hex/ui/view.hpp> #include <hex/ui/view.hpp>
#include <hex/providers/provider.hpp>
#include <hex/ui/popup.hpp> #include <hex/ui/popup.hpp>
#include <hex/providers/provider.hpp>
#include <hex/helpers/default_paths.hpp>
#include <pl/pattern_language.hpp> #include <pl/pattern_language.hpp>
#include <pl/core/errors/error.hpp> #include <pl/core/errors/error.hpp>
@ -14,8 +16,7 @@
#include <functional> #include <functional>
#include <TextEditor.h> #include <TextEditor.h>
#include "popups/popup_file_chooser.hpp" #include <popups/popup_file_chooser.hpp>
#include "hex/api/achievement_manager.hpp"
namespace pl::ptrn { class Pattern; } namespace pl::ptrn { class Pattern; }
@ -261,9 +262,9 @@ namespace hex::plugin::builtin {
void registerMenuItems(); void registerMenuItems();
void registerHandlers(); void registerHandlers();
std::function<void()> importPatternFile = [&] { std::function<void()> m_importPatternFile = [this] {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Patterns); const auto basePaths = paths::Patterns.read();
std::vector<std::fs::path> paths; std::vector<std::fs::path> paths;
for (const auto &imhexPath : basePaths) { for (const auto &imhexPath : basePaths) {
@ -284,7 +285,7 @@ namespace hex::plugin::builtin {
); );
}; };
std::function<void()> exportPatternFile = [&] { std::function<void()> m_exportPatternFile = [this] {
fs::openFileBrowser( fs::openFileBrowser(
fs::DialogMode::Save, { {"Pattern", "hexpat"} }, fs::DialogMode::Save, { {"Pattern", "hexpat"} },
[this](const auto &path) { [this](const auto &path) {

View File

@ -7,6 +7,7 @@
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/helpers/http_requests.hpp> #include <hex/helpers/http_requests.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/default_paths.hpp>
#include <future> #include <future>
#include <string> #include <string>
@ -40,7 +41,7 @@ namespace hex::plugin::builtin {
struct StoreCategory { struct StoreCategory {
UnlocalizedString unlocalizedName; UnlocalizedString unlocalizedName;
std::string requestName; std::string requestName;
fs::ImHexPath path; const paths::impl::DefaultPath* path;
std::vector<StoreEntry> entries; std::vector<StoreEntry> entries;
std::function<void()> downloadCallback; std::function<void()> downloadCallback;
}; };
@ -66,10 +67,10 @@ namespace hex::plugin::builtin {
void refresh(); void refresh();
void parseResponse(); void parseResponse();
void addCategory(const UnlocalizedString &unlocalizedName, const std::string &requestName, fs::ImHexPath path, std::function<void()> downloadCallback = []{}); void addCategory(const UnlocalizedString &unlocalizedName, const std::string &requestName, const paths::impl::DefaultPath *path, std::function<void()> downloadCallback = []{});
bool download(fs::ImHexPath pathType, const std::string &fileName, const std::string &url); bool download(const paths::impl::DefaultPath *pathType, const std::string &fileName, const std::string &url);
bool remove(fs::ImHexPath pathType, const std::string &fileName); bool remove(const paths::impl::DefaultPath *pathType, const std::string &fileName);
private: private:
HttpRequest m_httpRequest = HttpRequest("GET", ""); HttpRequest m_httpRequest = HttpRequest("GET", "");

View File

@ -3,16 +3,17 @@
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <wolv/utils/guards.hpp>
#include <wolv/net/socket_server.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <fmt/chrono.h> #include <hex/helpers/default_paths.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <nlohmann/json.hpp> #include <wolv/utils/guards.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
#include <wolv/net/socket_server.hpp>
#include <fmt/chrono.h>
#include <nlohmann/json.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -82,7 +83,7 @@ namespace hex::plugin::builtin {
} }
} }
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Backups)) { for (const auto &path : paths::Backups.write()) {
const auto backupPath = path / hex::format("auto_backup.{:%y%m%d_%H%M%S}.hexproj", fmt::gmtime(std::chrono::system_clock::now())); const auto backupPath = path / hex::format("auto_backup.{:%y%m%d_%H%M%S}.hexproj", fmt::gmtime(std::chrono::system_clock::now()));
if (ProjectFile::store(backupPath, false)) { if (ProjectFile::store(backupPath, false)) {
log::info("Created auto-backup file '{}'", wolv::util::toUTF8String(backupPath)); log::info("Created auto-backup file '{}'", wolv::util::toUTF8String(backupPath));

View File

@ -3,19 +3,19 @@
#include <content/providers/file_provider.hpp> #include <content/providers/file_provider.hpp>
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/magic.hpp> #include <hex/helpers/magic.hpp>
#include <hex/helpers/crypto.hpp> #include <hex/helpers/crypto.hpp>
#include <hex/helpers/literals.hpp> #include <hex/helpers/literals.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <romfs/romfs.hpp> #include <hex/helpers/default_paths.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/subcommands/subcommands.hpp> #include <hex/subcommands/subcommands.hpp>
#include <romfs/romfs.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
#include <wolv/math_eval/math_evaluator.hpp> #include <wolv/math_eval/math_evaluator.hpp>
@ -308,7 +308,7 @@ namespace hex::plugin::builtin {
if (processedArgs.empty()) { if (processedArgs.empty()) {
processedArgs.emplace_back("--help"); processedArgs.emplace_back("--help");
} else { } else {
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::PatternsInclude)) for (const auto &path : paths::PatternsInclude.read())
processedArgs.emplace_back(hex::format("--includes={}", wolv::util::toUTF8String(path))); processedArgs.emplace_back(hex::format("--includes={}", wolv::util::toUTF8String(path)));
} }

View File

@ -4,6 +4,7 @@
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -17,7 +18,7 @@ namespace hex::plugin::builtin {
for (const auto &[extractFolder, alwaysExtract] : Paths) { for (const auto &[extractFolder, alwaysExtract] : Paths) {
for (const auto &romfsPath : romfs::list(extractFolder)) { for (const auto &romfsPath : romfs::list(extractFolder)) {
for (const auto &imhexPath : fs::getDataPaths()) { for (const auto &imhexPath : paths::getDataPaths(false)) {
const auto path = imhexPath / std::fs::relative(romfsPath, extractFolder); const auto path = imhexPath / std::fs::relative(romfsPath, extractFolder);
log::info("Extracting {} to {}", romfsPath.string(), path.string()); log::info("Extracting {} to {}", romfsPath.string(), path.string());
if (!alwaysExtract && wolv::io::fs::exists(path)) if (!alwaysExtract && wolv::io::fs::exists(path))

View File

@ -1,6 +1,8 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <hex/helpers/default_paths.hpp>
#include <toasts/toast_notification.hpp> #include <toasts/toast_notification.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -12,7 +14,7 @@ namespace hex::plugin::builtin {
}); });
ContentRegistry::FileHandler::add({ ".hexlyt" }, [](const std::fs::path &path) { ContentRegistry::FileHandler::add({ ".hexlyt" }, [](const std::fs::path &path) {
for (const auto &folder : fs::getDefaultPaths(fs::ImHexPath::Layouts)) { for (const auto &folder : paths::Layouts.write()) {
if (wolv::io::fs::copyFile(path, folder / path.filename())) if (wolv::io::fs::copyFile(path, folder / path.filename()))
return true; return true;
} }
@ -21,7 +23,7 @@ namespace hex::plugin::builtin {
}); });
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) { ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) { for (const auto &destPath : paths::Magic.write()) {
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) { if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
ui::ToastInfo::open("hex.builtin.view.information.magic_db_added"_lang); ui::ToastInfo::open("hex.builtin.view.information.magic_db_added"_lang);
return true; return true;

View File

@ -8,6 +8,7 @@
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <hex/api/localization_manager.hpp> #include <hex/api/localization_manager.hpp>
#include <hex/api/achievement_manager.hpp> #include <hex/api/achievement_manager.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/event_manager.hpp> #include <hex/api/event_manager.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
@ -177,6 +178,10 @@ namespace hex::plugin::builtin {
} }
void registerProjectHandlers() { void registerProjectHandlers() {
hex::ProjectFile::setProjectFunctions(load, store); hex::ProjectFile::setProjectFunctions(load, store);
ContentRegistry::Interface::addSidebarItem(ICON_VS_PROJECT, [] {
ImGui::TextUnformatted("Test");
});
} }
} }

View File

@ -1,4 +1,3 @@
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
@ -7,6 +6,7 @@
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <fmt/chrono.h> #include <fmt/chrono.h>
@ -41,7 +41,7 @@ namespace hex::plugin::builtin::recent {
}; };
public: public:
PopupAutoBackups() : Popup("hex.builtin.welcome.start.recent.auto_backups", true, true) { PopupAutoBackups() : Popup("hex.builtin.welcome.start.recent.auto_backups", true, true) {
for (const auto &backupPath : fs::getDefaultPaths(fs::ImHexPath::Backups)) { for (const auto &backupPath : paths::Backups.read()) {
for (const auto &entry : std::fs::directory_iterator(backupPath)) { for (const auto &entry : std::fs::directory_iterator(backupPath)) {
if (entry.is_regular_file() && entry.path().extension() == ".hexproj") { if (entry.is_regular_file() && entry.path().extension() == ".hexproj") {
wolv::io::File backupFile(entry.path(), wolv::io::File::Mode::Read); wolv::io::File backupFile(entry.path(), wolv::io::File::Mode::Read);
@ -99,7 +99,7 @@ namespace hex::plugin::builtin::recent {
return; return;
// The recent provider is saved to every "recent" directory // The recent provider is saved to every "recent" directory
for (const auto &recentPath : fs::getDefaultPaths(fs::ImHexPath::Recent)) { for (const auto &recentPath : paths::Recent.write()) {
wolv::io::File recentFile(recentPath / fileName, wolv::io::File::Mode::Create); wolv::io::File recentFile(recentPath / fileName, wolv::io::File::Mode::Create);
if (!recentFile.isValid()) if (!recentFile.isValid())
continue; continue;
@ -129,7 +129,7 @@ namespace hex::plugin::builtin::recent {
return; return;
// The recent provider is saved to every "recent" directory // The recent provider is saved to every "recent" directory
for (const auto &recentPath : fs::getDefaultPaths(fs::ImHexPath::Recent)) { for (const auto &recentPath : paths::Recent.write()) {
wolv::io::File recentFile(recentPath / fileName, wolv::io::File::Mode::Create); wolv::io::File recentFile(recentPath / fileName, wolv::io::File::Mode::Create);
if (!recentFile.isValid()) if (!recentFile.isValid())
continue; continue;
@ -160,7 +160,7 @@ namespace hex::plugin::builtin::recent {
// Query all recent providers // Query all recent providers
std::vector<std::fs::path> recentFilePaths; std::vector<std::fs::path> recentFilePaths;
for (const auto &folder : fs::getDefaultPaths(fs::ImHexPath::Recent)) { for (const auto &folder : paths::Recent.read()) {
for (const auto &entry : std::fs::directory_iterator(folder)) { for (const auto &entry : std::fs::directory_iterator(folder)) {
if (entry.is_regular_file()) if (entry.is_regular_file())
recentFilePaths.push_back(entry.path()); recentFilePaths.push_back(entry.path());
@ -203,7 +203,7 @@ namespace hex::plugin::builtin::recent {
std::copy(uniqueProviders.begin(), uniqueProviders.end(), std::front_inserter(s_recentEntries)); std::copy(uniqueProviders.begin(), uniqueProviders.end(), std::front_inserter(s_recentEntries));
s_autoBackupsFound = false; s_autoBackupsFound = false;
for (const auto &backupPath : fs::getDefaultPaths(fs::ImHexPath::Backups)) { for (const auto &backupPath : paths::Backups.read()) {
for (const auto &entry : std::fs::directory_iterator(backupPath)) { for (const auto &entry : std::fs::directory_iterator(backupPath)) {
if (entry.is_regular_file() && entry.path().extension() == ".hexproj") { if (entry.is_regular_file() && entry.path().extension() == ".hexproj") {
s_autoBackupsFound = true; s_autoBackupsFound = true;
@ -347,7 +347,7 @@ namespace hex::plugin::builtin::recent {
s_recentEntries.clear(); s_recentEntries.clear();
// Remove all recent files // Remove all recent files
for (const auto &recentPath : fs::getDefaultPaths(fs::ImHexPath::Recent)) { for (const auto &recentPath : paths::Recent.write()) {
for (const auto &entry : std::fs::directory_iterator(recentPath)) for (const auto &entry : std::fs::directory_iterator(recentPath))
std::fs::remove(entry.path()); std::fs::remove(entry.path());
} }

View File

@ -1,17 +1,16 @@
#include <hex/api/theme_manager.hpp> #include <hex/api/theme_manager.hpp>
#include <hex/api/event_manager.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/helpers/default_paths.hpp>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <implot.h> #include <implot.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <imnodes.h> #include <imnodes.h>
#include <TextEditor.h> #include <TextEditor.h>
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/api/event_manager.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -369,7 +368,7 @@ namespace hex::plugin::builtin {
} }
// Load user themes // Load user themes
for (const auto &themeFolder : fs::getDefaultPaths(fs::ImHexPath::Themes)) { for (const auto &themeFolder : paths::Themes.read()) {
for (const auto &theme : std::fs::directory_iterator(themeFolder)) { for (const auto &theme : std::fs::directory_iterator(themeFolder)) {
if (theme.is_regular_file()) if (theme.is_regular_file())
ThemeManager::addTheme(wolv::io::File(theme.path(), wolv::io::File::Mode::Read).readString()); ThemeManager::addTheme(wolv::io::File(theme.path(), wolv::io::File::Mode::Read).readString());

View File

@ -10,6 +10,7 @@
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/http_requests.hpp> #include <hex/helpers/http_requests.hpp>
#include <hex/helpers/default_paths.hpp>
#include <content/popups/popup_docs_question.hpp> #include <content/popups/popup_docs_question.hpp>
@ -451,28 +452,28 @@ namespace hex::plugin::builtin {
void ViewAbout::drawPathsPage() { void ViewAbout::drawPathsPage() {
constexpr static std::array<std::pair<const char *, fs::ImHexPath>, size_t(fs::ImHexPath::END)> PathTypes = { constexpr static std::array<std::pair<const char *, const paths::impl::DefaultPath*>, paths::All.size()> PathTypes = {
{ {
{ "Patterns", fs::ImHexPath::Patterns }, { "Patterns", &paths::Patterns },
{ "Patterns Includes", fs::ImHexPath::PatternsInclude }, { "Patterns Includes", &paths::PatternsInclude },
{ "Magic", fs::ImHexPath::Magic }, { "Magic", &paths::Magic },
{ "Plugins", fs::ImHexPath::Plugins }, { "Plugins", &paths::Plugins },
{ "Yara Patterns", fs::ImHexPath::Yara }, { "Yara Patterns", &paths::Yara },
{ "Yara Advaned Analysis", fs::ImHexPath::YaraAdvancedAnalysis }, { "Yara Advaned Analysis", &paths::YaraAdvancedAnalysis },
{ "Config", fs::ImHexPath::Config }, { "Config", &paths::Config },
{ "Backups", fs::ImHexPath::Backups }, { "Backups", &paths::Backups },
{ "Resources", fs::ImHexPath::Resources }, { "Resources", &paths::Resources },
{ "Constants lists", fs::ImHexPath::Constants }, { "Constants lists", &paths::Constants },
{ "Custom encodings", fs::ImHexPath::Encodings }, { "Custom encodings", &paths::Encodings },
{ "Logs", fs::ImHexPath::Logs }, { "Logs", &paths::Logs },
{ "Recent files", fs::ImHexPath::Recent }, { "Recent files", &paths::Recent },
{ "Scripts", fs::ImHexPath::Scripts }, { "Scripts", &paths::Scripts },
{ "Data inspector scripts", fs::ImHexPath::Inspectors }, { "Data inspector scripts", &paths::Inspectors },
{ "Themes", fs::ImHexPath::Themes }, { "Themes", &paths::Themes },
{ "Native Libraries", fs::ImHexPath::Libraries }, { "Native Libraries", &paths::Libraries },
{ "Custom data processor nodes", fs::ImHexPath::Nodes }, { "Custom data processor nodes", &paths::Nodes },
{ "Layouts", fs::ImHexPath::Layouts }, { "Layouts", &paths::Layouts },
{ "Workspaces", fs::ImHexPath::Workspaces }, { "Workspaces", &paths::Workspaces },
} }
}; };
static_assert(PathTypes.back().first != nullptr, "All path items need to be populated!"); static_assert(PathTypes.back().first != nullptr, "All path items need to be populated!");
@ -487,13 +488,13 @@ namespace hex::plugin::builtin {
// Draw the table // Draw the table
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
for (const auto &[name, type] : PathTypes) { for (const auto &[name, paths] : PathTypes) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted(name); ImGui::TextUnformatted(name);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
for (auto &path : fs::getDefaultPaths(type, true)){ for (auto &path : paths->all()){
// Draw hyperlink to paths that exist or red text if they don't // Draw hyperlink to paths that exist or red text if they don't
if (wolv::io::fs::isDirectory(path)){ if (wolv::io::fs::isDirectory(path)){
if (ImGuiExt::Hyperlink(wolv::util::toUTF8String(path).c_str())) { if (ImGuiExt::Hyperlink(wolv::util::toUTF8String(path).c_str())) {

View File

@ -1,8 +1,8 @@
#include "content/views/view_constants.hpp" #include "content/views/view_constants.hpp"
#include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/default_paths.hpp>
#include <wolv/utils/string.hpp> #include <wolv/utils/string.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
@ -22,7 +22,7 @@ namespace hex::plugin::builtin {
m_constants.clear(); m_constants.clear();
m_filterIndices.clear(); m_filterIndices.clear();
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Constants)) { for (const auto &path : paths::Constants.read()) {
if (!wolv::io::fs::exists(path)) continue; if (!wolv::io::fs::exists(path)) continue;
std::error_code error; std::error_code error;

View File

@ -1,13 +1,12 @@
#include "content/views/view_data_inspector.hpp" #include "content/views/view_data_inspector.hpp"
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/providers/provider.hpp>
#include <hex/api/achievement_manager.hpp> #include <hex/api/achievement_manager.hpp>
#include <hex/providers/provider.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <fonts/codicons_font.h> #include <fonts/codicons_font.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <pl/pattern_language.hpp> #include <pl/pattern_language.hpp>
#include <pl/patterns/pattern.hpp> #include <pl/patterns/pattern.hpp>
@ -134,7 +133,7 @@ namespace hex::plugin::builtin {
m_runtime.setStartAddress(m_startAddress); m_runtime.setStartAddress(m_startAddress);
// Loop over all files in the inspectors folder and execute them // Loop over all files in the inspectors folder and execute them
for (const auto &folderPath : fs::getDefaultPaths(fs::ImHexPath::Inspectors)) { for (const auto &folderPath : paths::Inspectors.read()) {
for (const auto &entry: std::fs::recursive_directory_iterator(folderPath)) { for (const auto &entry: std::fs::recursive_directory_iterator(folderPath)) {
const auto &filePath = entry.path(); const auto &filePath = entry.path();
// Skip non-files and files that don't end with .hexpat // Skip non-files and files that don't end with .hexpat

View File

@ -7,6 +7,7 @@
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <imnodes.h> #include <imnodes.h>
#include <imnodes_internal.h> #include <imnodes_internal.h>
@ -127,7 +128,7 @@ namespace hex::plugin::builtin {
void process() override { void process() override {
switch (this->getType()) { switch (this->getType()) {
case dp::Attribute::Type::Integer: m_value = this->getIntegerOnInput(0); break; case dp::Attribute::Type::Integer: m_value = this->getIntegerOnInput(0); break;
case dp::Attribute::Type::Float: m_value = this->getFloatOnInput(0); break; case dp::Attribute::Type::Float: m_value = static_cast<long double>(this->getFloatOnInput(0)); break;
case dp::Attribute::Type::Buffer: m_value = this->getBufferOnInput(0); break; case dp::Attribute::Type::Buffer: m_value = this->getBufferOnInput(0); break;
} }
} }
@ -568,7 +569,7 @@ namespace hex::plugin::builtin {
m_customNodes.clear(); m_customNodes.clear();
// Loop over all custom node folders // Loop over all custom node folders
for (const auto &basePath : fs::getDefaultPaths(fs::ImHexPath::Nodes)) { for (const auto &basePath : paths::Nodes.read()) {
// Loop over all files in the folder // Loop over all files in the folder
for (const auto &entry : std::fs::recursive_directory_iterator(basePath)) { for (const auto &entry : std::fs::recursive_directory_iterator(basePath)) {
// Skip files that are not .hexnode files // Skip files that are not .hexnode files

View File

@ -7,6 +7,7 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/crypto.hpp> #include <hex/helpers/crypto.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/providers/buffered_reader.hpp> #include <hex/providers/buffered_reader.hpp>
@ -19,7 +20,6 @@
#include <popups/popup_file_chooser.hpp> #include <popups/popup_file_chooser.hpp>
#include <content/popups/popup_blocking_task.hpp> #include <content/popups/popup_blocking_task.hpp>
#include <content/popups/hex_editor/popup_hex_editor_find.hpp> #include <content/popups/hex_editor/popup_hex_editor_find.hpp>
#include <wolv/utils/lock.hpp>
#include <pl/patterns/pattern.hpp> #include <pl/patterns/pattern.hpp>
using namespace std::literals::string_literals; using namespace std::literals::string_literals;
@ -1053,7 +1053,7 @@ namespace hex::plugin::builtin {
/* Load Encoding File */ /* Load Encoding File */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.custom_encoding" }, "", 5050, Shortcut::None, ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.custom_encoding" }, "", 5050, Shortcut::None,
[this]{ [this]{
const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Encodings); const auto basePaths = paths::Encodings.read();
std::vector<std::fs::path> paths; std::vector<std::fs::path> paths;
for (const auto &path : basePaths) { for (const auto &path : basePaths) {
std::error_code error; std::error_code error;

View File

@ -14,6 +14,7 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/magic.hpp> #include <hex/helpers/magic.hpp>
#include <hex/helpers/binary_pattern.hpp> #include <hex/helpers/binary_pattern.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/providers/memory_provider.hpp> #include <hex/providers/memory_provider.hpp>
@ -239,9 +240,9 @@ namespace hex::plugin::builtin {
if (ImGui::BeginPopup("##pattern_editor_context_menu")) { if (ImGui::BeginPopup("##pattern_editor_context_menu")) {
// no shortcut for this // no shortcut for this
if (ImGui::MenuItem("hex.builtin.menu.file.import.pattern_file"_lang, nullptr, false)) if (ImGui::MenuItem("hex.builtin.menu.file.import.pattern_file"_lang, nullptr, false))
importPatternFile(); m_importPatternFile();
if (ImGui::MenuItem("hex.builtin.menu.file.export.pattern_file"_lang, nullptr, false)) if (ImGui::MenuItem("hex.builtin.menu.file.export.pattern_file"_lang, nullptr, false))
exportPatternFile(); m_exportPatternFile();
ImGui::Separator(); ImGui::Separator();
@ -1413,7 +1414,7 @@ namespace hex::plugin::builtin {
bool popupOpen = false; bool popupOpen = false;
std::error_code errorCode; std::error_code errorCode;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { for (const auto &dir : paths::Patterns.read()) {
for (auto &entry : std::fs::recursive_directory_iterator(dir, errorCode)) { for (auto &entry : std::fs::recursive_directory_iterator(dir, errorCode)) {
task.update(); task.update();
@ -1792,11 +1793,11 @@ namespace hex::plugin::builtin {
void ViewPatternEditor::registerMenuItems() { void ViewPatternEditor::registerMenuItems() {
/* Import Pattern */ /* Import Pattern */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.pattern" }, ICON_VS_FILE_CODE, 4050, Shortcut::None, ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.pattern" }, ICON_VS_FILE_CODE, 4050, Shortcut::None,
importPatternFile, ImHexApi::Provider::isValid); m_importPatternFile, ImHexApi::Provider::isValid);
/* Export Pattern */ /* Export Pattern */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.pattern" }, ICON_VS_FILE_CODE, 7050, Shortcut::None, ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.pattern" }, ICON_VS_FILE_CODE, 7050, Shortcut::None,
exportPatternFile, [this] { m_exportPatternFile, [this] {
return !wolv::util::trim(m_textEditor.GetText()).empty() && ImHexApi::Provider::isValid(); return !wolv::util::trim(m_textEditor.GetText()).empty() && ImHexApi::Provider::isValid();
} }
); );

View File

@ -38,26 +38,26 @@ namespace hex::plugin::builtin {
m_httpRequest.setTimeout(30'0000); m_httpRequest.setTimeout(30'0000);
addCategory("hex.builtin.view.store.tab.patterns", "patterns", fs::ImHexPath::Patterns); addCategory("hex.builtin.view.store.tab.patterns", "patterns", &paths::Patterns);
addCategory("hex.builtin.view.store.tab.includes", "includes", fs::ImHexPath::PatternsInclude); addCategory("hex.builtin.view.store.tab.includes", "includes", &paths::PatternsInclude);
addCategory("hex.builtin.view.store.tab.magic", "magic", fs::ImHexPath::Magic, []{ addCategory("hex.builtin.view.store.tab.magic", "magic", &paths::Magic, []{
magic::compile(); magic::compile();
}); });
addCategory("hex.builtin.view.store.tab.nodes", "nodes", fs::ImHexPath::Nodes); addCategory("hex.builtin.view.store.tab.nodes", "nodes", &paths::Nodes);
addCategory("hex.builtin.view.store.tab.encodings", "encodings", fs::ImHexPath::Encodings); addCategory("hex.builtin.view.store.tab.encodings", "encodings", &paths::Encodings);
addCategory("hex.builtin.view.store.tab.constants", "constants", fs::ImHexPath::Constants); addCategory("hex.builtin.view.store.tab.constants", "constants", &paths::Constants);
addCategory("hex.builtin.view.store.tab.themes", "themes", fs::ImHexPath::Themes, [this]{ addCategory("hex.builtin.view.store.tab.themes", "themes", &paths::Themes, [this]{
auto themeFile = wolv::io::File(m_downloadPath, wolv::io::File::Mode::Read); auto themeFile = wolv::io::File(m_downloadPath, wolv::io::File::Mode::Read);
ThemeManager::addTheme(themeFile.readString()); ThemeManager::addTheme(themeFile.readString());
}); });
addCategory("hex.builtin.view.store.tab.yara", "yara", fs::ImHexPath::Yara); addCategory("hex.builtin.view.store.tab.yara", "yara", &paths::Yara);
} }
void updateEntryMetadata(StoreEntry &storeEntry, const StoreCategory &category) { void updateEntryMetadata(StoreEntry &storeEntry, const StoreCategory &category) {
// Check if file is installed already or has an update available // Check if file is installed already or has an update available
for (const auto &folder : fs::getDefaultPaths(category.path)) { for (const auto &folder : category.path->write()) {
auto path = folder / std::fs::path(storeEntry.fileName); auto path = folder / std::fs::path(storeEntry.fileName);
if (wolv::io::fs::exists(path)) { if (wolv::io::fs::exists(path)) {
@ -296,9 +296,9 @@ namespace hex::plugin::builtin {
this->drawStore(); this->drawStore();
} }
bool ViewStore::download(fs::ImHexPath pathType, const std::string &fileName, const std::string &url) { bool ViewStore::download(const paths::impl::DefaultPath *pathType, const std::string &fileName, const std::string &url) {
bool downloading = false; bool downloading = false;
for (const auto &folderPath : fs::getDefaultPaths(pathType)) { for (const auto &folderPath : pathType->write()) {
if (!fs::isPathWritable(folderPath)) if (!fs::isPathWritable(folderPath))
continue; continue;
@ -327,9 +327,9 @@ namespace hex::plugin::builtin {
return true; return true;
} }
bool ViewStore::remove(fs::ImHexPath pathType, const std::string &fileName) { bool ViewStore::remove(const paths::impl::DefaultPath *pathType, const std::string &fileName) {
bool removed = true; bool removed = true;
for (const auto &path : fs::getDefaultPaths(pathType)) { for (const auto &path : pathType->write()) {
const auto filePath = path / fileName; const auto filePath = path / fileName;
const auto folderPath = (path / std::fs::path(fileName).stem()); const auto folderPath = (path / std::fs::path(fileName).stem());
@ -343,7 +343,7 @@ namespace hex::plugin::builtin {
return removed; return removed;
} }
void ViewStore::addCategory(const UnlocalizedString &unlocalizedName, const std::string &requestName, fs::ImHexPath path, std::function<void()> downloadCallback) { void ViewStore::addCategory(const UnlocalizedString &unlocalizedName, const std::string &requestName, const paths::impl::DefaultPath *path, std::function<void()> downloadCallback) {
m_categories.push_back({ unlocalizedName, requestName, path, { }, std::move(downloadCallback) }); m_categories.push_back({ unlocalizedName, requestName, path, { }, std::move(downloadCallback) });
} }

View File

@ -15,6 +15,7 @@
#include <hex/helpers/http_requests.hpp> #include <hex/helpers/http_requests.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
@ -87,8 +88,8 @@ namespace hex::plugin::builtin {
// Anonymize the log file // Anonymize the log file
{ {
for (u32 pathType = 0; pathType < u32(fs::ImHexPath::END); pathType++) { for (const auto &paths : paths::All) {
for (auto &folder : fs::getDefaultPaths(static_cast<fs::ImHexPath>(pathType))) { for (auto &folder : paths->all()) {
auto parent = wolv::util::toUTF8String(folder.parent_path()); auto parent = wolv::util::toUTF8String(folder.parent_path());
data = wolv::util::replaceStrings(data, parent, "<*****>"); data = wolv::util::replaceStrings(data, parent, "<*****>");
} }
@ -546,7 +547,7 @@ namespace hex::plugin::builtin {
constexpr static auto BackupFileName = "crash_backup.hexproj"; constexpr static auto BackupFileName = "crash_backup.hexproj";
bool hasCrashed = false; bool hasCrashed = false;
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &path : paths::Config.read()) {
if (auto crashFilePath = std::fs::path(path) / CrashFileName; wolv::io::fs::exists(crashFilePath)) { if (auto crashFilePath = std::fs::path(path) / CrashFileName; wolv::io::fs::exists(crashFilePath)) {
hasCrashed = true; hasCrashed = true;
@ -646,7 +647,7 @@ namespace hex::plugin::builtin {
// Load info banner texture either locally or from the server // Load info banner texture either locally or from the server
TaskManager::doLater([] { TaskManager::doLater([] {
for (const auto &defaultPath : fs::getDefaultPaths(fs::ImHexPath::Resources)) { for (const auto &defaultPath : paths::Resources.read()) {
const auto infoBannerPath = defaultPath / "info_banner.png"; const auto infoBannerPath = defaultPath / "info_banner.png";
if (wolv::io::fs::exists(infoBannerPath)) { if (wolv::io::fs::exists(infoBannerPath)) {
s_infoBannerTexture = ImGuiExt::Texture::fromImage(infoBannerPath, ImGuiExt::Texture::Filter::Linear); s_infoBannerTexture = ImGuiExt::Texture::fromImage(infoBannerPath, ImGuiExt::Texture::Filter::Linear);

View File

@ -75,24 +75,29 @@ namespace hex::plugin::builtin {
void drawSidebar(ImVec2 dockSpaceSize, ImVec2 sidebarPos, float sidebarWidth) { void drawSidebar(ImVec2 dockSpaceSize, ImVec2 sidebarPos, float sidebarWidth) {
static i32 openWindow = -1; static i32 openWindow = -1;
u32 index = 0; u32 index = 0;
u32 drawIndex = 0;
ImGui::PushID("SideBarWindows"); ImGui::PushID("SideBarWindows");
for (const auto &[icon, callback, enabledCallback] : ContentRegistry::Interface::impl::getSidebarItems()) { for (const auto &[icon, callback, enabledCallback] : ContentRegistry::Interface::impl::getSidebarItems()) {
ImGui::SetCursorPosY(sidebarPos.y + sidebarWidth * index); ImGui::SetCursorPosY(sidebarPos.y + sidebarWidth * drawIndex);
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered));
ImGui::BeginDisabled(!(ImHexApi::Provider::isValid() && enabledCallback()));
{ if (enabledCallback()) {
if (ImGui::Button(icon.c_str(), ImVec2(sidebarWidth, sidebarWidth))) { drawIndex += 1;
if (static_cast<u32>(openWindow) == index) ImGui::BeginDisabled(!ImHexApi::Provider::isValid());
openWindow = -1; {
else if (ImGui::Button(icon.c_str(), ImVec2(sidebarWidth, sidebarWidth))) {
openWindow = index; if (static_cast<u32>(openWindow) == index)
openWindow = -1;
else
openWindow = index;
}
} }
ImGui::EndDisabled();
} }
ImGui::EndDisabled();
ImGui::PopStyleColor(3); ImGui::PopStyleColor(3);
@ -122,7 +127,7 @@ namespace hex::plugin::builtin {
} }
ImGui::NewLine(); ImGui::NewLine();
index++; index += 1;
} }
ImGui::PopID(); ImGui::PopID();
} }

View File

@ -7,13 +7,16 @@
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <wolv/utils/string.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/default_paths.hpp>
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
#include <wolv/utils/string.hpp>
namespace hex::fonts { namespace hex::fonts {
@ -214,7 +217,7 @@ namespace hex::fonts {
// If no custom font has been specified, search for a file called "font.ttf" in one of the resource folders // If no custom font has been specified, search for a file called "font.ttf" in one of the resource folders
if (fontFile.empty()) { if (fontFile.empty()) {
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Resources)) { for (const auto &dir : paths::Resources.read()) {
auto path = dir / "font.ttf"; auto path = dir / "font.ttf";
if (wolv::io::fs::exists(path)) { if (wolv::io::fs::exists(path)) {
log::info("Loading custom font from {}", wolv::util::toUTF8String(path)); log::info("Loading custom font from {}", wolv::util::toUTF8String(path));

View File

@ -23,6 +23,8 @@
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/default_paths.hpp>
#include <toasts/toast_notification.hpp> #include <toasts/toast_notification.hpp>
extern "C" void igSetCurrentContext(ImGuiContext* ctx); extern "C" void igSetCurrentContext(ImGuiContext* ctx);
@ -57,7 +59,7 @@ namespace hex::script::loader {
auto netHostLibrary = loadLibrary("libnethost.so"); auto netHostLibrary = loadLibrary("libnethost.so");
#elif defined(OS_MACOS) #elif defined(OS_MACOS)
void *netHostLibrary = nullptr; void *netHostLibrary = nullptr;
for (const auto &pluginPath : fs::getDefaultPaths(fs::ImHexPath::Plugins)) { for (const auto &pluginPath : paths::Plugins.read()) {
auto frameworksPath = pluginPath.parent_path().parent_path() / "Frameworks"; auto frameworksPath = pluginPath.parent_path().parent_path() / "Frameworks";
netHostLibrary = loadLibrary((frameworksPath / "libnethost.dylib").c_str()); netHostLibrary = loadLibrary((frameworksPath / "libnethost.dylib").c_str());
@ -65,7 +67,7 @@ namespace hex::script::loader {
break; break;
} }
if (netHostLibrary == nullptr) { if (netHostLibrary == nullptr) {
for (const auto &librariesPath : fs::getDefaultPaths(fs::ImHexPath::Libraries)) { for (const auto &librariesPath : paths::Libraries.read()) {
netHostLibrary = loadLibrary((librariesPath / "libnethost.dylib").c_str()); netHostLibrary = loadLibrary((librariesPath / "libnethost.dylib").c_str());
if (netHostLibrary != nullptr) if (netHostLibrary != nullptr)
break; break;
@ -165,7 +167,7 @@ namespace hex::script::loader {
return false; return false;
} }
for (const auto& path : hex::fs::getDefaultPaths(hex::fs::ImHexPath::Plugins)) { for (const auto& path : paths::Plugins.read()) {
auto assemblyLoader = path / "AssemblyLoader.dll"; auto assemblyLoader = path / "AssemblyLoader.dll";
if (!wolv::io::fs::exists(assemblyLoader)) if (!wolv::io::fs::exists(assemblyLoader))
continue; continue;
@ -219,7 +221,7 @@ namespace hex::script::loader {
bool DotNetLoader::loadAll() { bool DotNetLoader::loadAll() {
this->clearScripts(); this->clearScripts();
for (const auto &imhexPath : hex::fs::getDefaultPaths(hex::fs::ImHexPath::Scripts)) { for (const auto &imhexPath : paths::Scripts.read()) {
auto directoryPath = imhexPath / "custom" / "dotnet"; auto directoryPath = imhexPath / "custom" / "dotnet";
if (!wolv::io::fs::exists(directoryPath)) if (!wolv::io::fs::exists(directoryPath))
wolv::io::fs::createDirectories(directoryPath); wolv::io::fs::createDirectories(directoryPath);

View File

@ -2,6 +2,7 @@
#include <imgui.h> #include <imgui.h>
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/ui/imgui_imhex_extensions.h> #include <hex/ui/imgui_imhex_extensions.h>
#include <content/yara_rule.hpp> #include <content/yara_rule.hpp>
@ -25,7 +26,7 @@ namespace hex::plugin::yara {
}; };
void process(Task &task, prv::Provider *provider, Region region) override { void process(Task &task, prv::Provider *provider, Region region) override {
for (const auto &yaraSignaturePath : fs::getDefaultPaths(fs::ImHexPath::YaraAdvancedAnalysis)) { for (const auto &yaraSignaturePath : paths::YaraAdvancedAnalysis.read()) {
for (const auto &ruleFilePath : std::fs::recursive_directory_iterator(yaraSignaturePath)) { for (const auto &ruleFilePath : std::fs::recursive_directory_iterator(yaraSignaturePath)) {
wolv::io::File file(ruleFilePath.path(), wolv::io::File::Mode::Read); wolv::io::File file(ruleFilePath.path(), wolv::io::File::Mode::Read);
if (!file.isValid()) if (!file.isValid())

View File

@ -4,6 +4,7 @@
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
#include <hex/helpers/default_paths.hpp>
#include <toasts/toast_notification.hpp> #include <toasts/toast_notification.hpp>
#include <popups/popup_file_chooser.hpp> #include <popups/popup_file_chooser.hpp>
@ -21,7 +22,7 @@ namespace hex::plugin::yara {
YaraRule::init(); YaraRule::init();
ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) { ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) {
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) { for (const auto &destPath : paths::Yara.write()) {
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) { if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
ui::ToastInfo::open("hex.yara_rules.view.yara.rule_added"_lang); ui::ToastInfo::open("hex.yara_rules.view.yara.rule_added"_lang);
return true; return true;
@ -143,7 +144,7 @@ namespace hex::plugin::yara {
} }
if (ImGuiExt::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { if (ImGuiExt::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Yara); const auto basePaths = paths::Yara.read();
std::vector<std::fs::path> paths; std::vector<std::fs::path> paths;
for (const auto &path : basePaths) { for (const auto &path : basePaths) {
std::error_code error; std::error_code error;