mirror of https://github.com/WerWolv/ImHex.git
sys: Log to a file when ImHex wasn't opened though a terminal
This commit is contained in:
parent
2df4e22bf8
commit
8701e0f402
|
@ -9,5 +9,12 @@
|
||||||
<mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/external/yara/yara" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/external/yara/yara" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/capstone" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/curl" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/fmt" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/libromfs" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/nativefiledialog" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/xdgpp" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/lib/external/yara/yara" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -123,6 +123,7 @@ set(LIBIMHEX_SOURCES
|
||||||
source/helpers/project_file_handler.cpp
|
source/helpers/project_file_handler.cpp
|
||||||
source/helpers/encoding_file.cpp
|
source/helpers/encoding_file.cpp
|
||||||
source/helpers/loader_script_handler.cpp
|
source/helpers/loader_script_handler.cpp
|
||||||
|
source/helpers/logger.cpp
|
||||||
|
|
||||||
source/pattern_language/pattern_language.cpp
|
source/pattern_language/pattern_language.cpp
|
||||||
source/pattern_language/preprocessor.cpp
|
source/pattern_language/preprocessor.cpp
|
||||||
|
|
|
@ -26,13 +26,16 @@ namespace hex {
|
||||||
Create
|
Create
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit File(const fs::path &path, Mode mode);
|
explicit File(const fs::path &path, Mode mode) noexcept;
|
||||||
File();
|
File() noexcept;
|
||||||
File(const File&) = delete;
|
File(const File&) = delete;
|
||||||
File(File &&other) noexcept;
|
File(File &&other) noexcept;
|
||||||
|
|
||||||
~File();
|
~File();
|
||||||
|
|
||||||
|
File& operator=(File &&other) noexcept;
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] bool isValid() const { return this->m_file != nullptr; }
|
[[nodiscard]] bool isValid() const { return this->m_file != nullptr; }
|
||||||
|
|
||||||
void seek(u64 offset);
|
void seek(u64 offset);
|
||||||
|
|
|
@ -5,36 +5,54 @@
|
||||||
|
|
||||||
namespace hex::log {
|
namespace hex::log {
|
||||||
|
|
||||||
|
FILE *getDestination();
|
||||||
|
bool isRedirected();
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
void print(fmt::format_string<T...> fmt, T&&... args) {
|
||||||
|
fmt::print(getDestination(), fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename S, typename... Args>
|
||||||
|
void print(const fmt::text_style& ts, const S& fmt, const Args&... args) {
|
||||||
|
if (isRedirected())
|
||||||
|
fmt::print(getDestination(), fmt::runtime(fmt), args...);
|
||||||
|
else
|
||||||
|
fmt::print(getDestination(), ts, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
void debug(const std::string &fmt, auto ... args) {
|
void debug(const std::string &fmt, auto ... args) {
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
fmt::print(fg(fmt::color::green_yellow) | fmt::emphasis::bold, "[DEBUG] ");
|
log::print(fg(fmt::color::green_yellow) | fmt::emphasis::bold, "[DEBUG] ");
|
||||||
fmt::print(fmt::runtime(fmt), args...);
|
log::print(fmt::runtime(fmt), args...);
|
||||||
fmt::print("\n");
|
log::print("\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void info(const std::string &fmt, auto ... args) {
|
void info(const std::string &fmt, auto ... args) {
|
||||||
fmt::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ");
|
log::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ");
|
||||||
fmt::print(fmt::runtime(fmt), args...);
|
log::print(fmt::runtime(fmt), args...);
|
||||||
fmt::print("\n");
|
log::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void warn(const std::string &fmt, auto ... args) {
|
void warn(const std::string &fmt, auto ... args) {
|
||||||
fmt::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ");
|
log::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ");
|
||||||
fmt::print(fmt::runtime(fmt), args...);
|
log::print(fmt::runtime(fmt), args...);
|
||||||
fmt::print("\n");
|
log::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void error(const std::string &fmt, auto ... args) {
|
void error(const std::string &fmt, auto ... args) {
|
||||||
fmt::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR] ");
|
log::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR] ");
|
||||||
fmt::print(fmt::runtime(fmt), args...);
|
log::print(fmt::runtime(fmt), args...);
|
||||||
fmt::print("\n");
|
log::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fatal(const std::string &fmt, auto ... args) {
|
void fatal(const std::string &fmt, auto ... args) {
|
||||||
fmt::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL] ");
|
log::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL] ");
|
||||||
fmt::print(fmt::runtime(fmt), args...);
|
log::print(fmt::runtime(fmt), args...);
|
||||||
fmt::print("\n");
|
log::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void redirectToFile();
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,7 +17,8 @@ namespace hex {
|
||||||
Yara,
|
Yara,
|
||||||
Config,
|
Config,
|
||||||
Resources,
|
Resources,
|
||||||
Constants
|
Constants,
|
||||||
|
Logs
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string getExecutablePath();
|
std::string getExecutablePath();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
File::File(const fs::path &path, Mode mode) : m_path(path) {
|
File::File(const fs::path &path, Mode mode) noexcept : m_path(path) {
|
||||||
if (mode == File::Mode::Read)
|
if (mode == File::Mode::Read)
|
||||||
this->m_file = fopen64(path.string().c_str(), "rb");
|
this->m_file = fopen64(path.string().c_str(), "rb");
|
||||||
else if (mode == File::Mode::Write)
|
else if (mode == File::Mode::Write)
|
||||||
|
@ -13,7 +13,7 @@ namespace hex {
|
||||||
this->m_file = fopen64(path.string().c_str(), "w+b");
|
this->m_file = fopen64(path.string().c_str(), "w+b");
|
||||||
}
|
}
|
||||||
|
|
||||||
File::File() {
|
File::File() noexcept {
|
||||||
this->m_file = nullptr;
|
this->m_file = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,16 @@ namespace hex {
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File& File::operator=(File &&other) noexcept {
|
||||||
|
this->m_file = other.m_file;
|
||||||
|
other.m_file = nullptr;
|
||||||
|
|
||||||
|
this->m_path = std::move(other.m_path);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void File::seek(u64 offset) {
|
void File::seek(u64 offset) {
|
||||||
fseeko64(this->m_file, offset, SEEK_SET);
|
fseeko64(this->m_file, offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
|
#include <hex/helpers/file.hpp>
|
||||||
|
#include <hex/helpers/paths.hpp>
|
||||||
|
#include <hex/helpers/fmt.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace hex::log {
|
||||||
|
|
||||||
|
static File g_loggerFile;
|
||||||
|
|
||||||
|
FILE* getDestination() {
|
||||||
|
if (g_loggerFile.isValid())
|
||||||
|
return g_loggerFile.getHandle();
|
||||||
|
else
|
||||||
|
return stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRedirected() {
|
||||||
|
return g_loggerFile.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void redirectToFile() {
|
||||||
|
if (g_loggerFile.isValid()) return;
|
||||||
|
|
||||||
|
for (const auto &path : hex::getPath(ImHexPath::Logs)) {
|
||||||
|
g_loggerFile = File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::now())), File::Mode::Create);
|
||||||
|
|
||||||
|
if (g_loggerFile.isValid()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -98,6 +98,11 @@ namespace hex {
|
||||||
return (path / "constants").string();
|
return (path / "constants").string();
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case ImHexPath::Logs:
|
||||||
|
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path){
|
||||||
|
return (path / "logs").string();
|
||||||
|
});
|
||||||
|
break;
|
||||||
default: __builtin_unreachable();
|
default: __builtin_unreachable();
|
||||||
}
|
}
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
|
@ -137,6 +142,9 @@ namespace hex {
|
||||||
case ImHexPath::Constants:
|
case ImHexPath::Constants:
|
||||||
result.push_back((applicationSupportDir / "constants").string());
|
result.push_back((applicationSupportDir / "constants").string());
|
||||||
break;
|
break;
|
||||||
|
case ImHexPath::Logs:
|
||||||
|
result.push_back((applicationSupportDir / "logs").string());
|
||||||
|
break;
|
||||||
default: __builtin_unreachable();
|
default: __builtin_unreachable();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -191,6 +199,10 @@ namespace hex {
|
||||||
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
|
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
|
||||||
[](auto p) { return (p / "constants").string(); });
|
[](auto p) { return (p / "constants").string(); });
|
||||||
break;
|
break;
|
||||||
|
case ImHexPath::Logs:
|
||||||
|
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
|
||||||
|
[](auto p) { return (p / "logs").string(); });
|
||||||
|
break;
|
||||||
default: __builtin_unreachable();
|
default: __builtin_unreachable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,17 +16,18 @@ namespace hex {
|
||||||
|
|
||||||
class Plugin {
|
class Plugin {
|
||||||
public:
|
public:
|
||||||
Plugin(const fs::path &path);
|
explicit Plugin(const fs::path &path);
|
||||||
Plugin(const Plugin&) = delete;
|
Plugin(const Plugin&) = delete;
|
||||||
Plugin(Plugin &&other) noexcept;
|
Plugin(Plugin &&other) noexcept;
|
||||||
~Plugin();
|
~Plugin();
|
||||||
|
|
||||||
void initializePlugin() const;
|
[[nodiscard]] bool initializePlugin() const;
|
||||||
[[nodiscard]] std::string getPluginName() const;
|
[[nodiscard]] std::string getPluginName() const;
|
||||||
[[nodiscard]] std::string getPluginAuthor() const;
|
[[nodiscard]] std::string getPluginAuthor() const;
|
||||||
[[nodiscard]] std::string getPluginDescription() const;
|
[[nodiscard]] std::string getPluginDescription() const;
|
||||||
void setImGuiContext(ImGuiContext *ctx) const;
|
void setImGuiContext(ImGuiContext *ctx) const;
|
||||||
|
|
||||||
|
[[nodiscard]] const fs::path& getPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using InitializePluginFunc = void(*)();
|
using InitializePluginFunc = void(*)();
|
||||||
|
@ -36,6 +37,7 @@ namespace hex {
|
||||||
using SetImGuiContextFunc = void(*)(ImGuiContext*);
|
using SetImGuiContextFunc = void(*)(ImGuiContext*);
|
||||||
|
|
||||||
void *m_handle = nullptr;
|
void *m_handle = nullptr;
|
||||||
|
fs::path m_path;
|
||||||
|
|
||||||
InitializePluginFunc m_initializePluginFunction = nullptr;
|
InitializePluginFunc m_initializePluginFunction = nullptr;
|
||||||
GetPluginNameFunc m_getPluginNameFunction = nullptr;
|
GetPluginNameFunc m_getPluginNameFunction = nullptr;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace hex {
|
||||||
constexpr auto GetPluginDescriptionSymbol = "_ZN3hex6plugin{0}{1}8internal20getPluginDescriptionEv";
|
constexpr auto GetPluginDescriptionSymbol = "_ZN3hex6plugin{0}{1}8internal20getPluginDescriptionEv";
|
||||||
constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin{0}{1}8internal15setImGuiContextEP12ImGuiContext";
|
constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin{0}{1}8internal15setImGuiContextEP12ImGuiContext";
|
||||||
|
|
||||||
Plugin::Plugin(const fs::path &path) {
|
Plugin::Plugin(const fs::path &path) : m_path(path) {
|
||||||
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
|
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
|
||||||
|
|
||||||
if (this->m_handle == nullptr) {
|
if (this->m_handle == nullptr) {
|
||||||
|
@ -33,6 +33,8 @@ namespace hex {
|
||||||
|
|
||||||
Plugin::Plugin(Plugin &&other) noexcept {
|
Plugin::Plugin(Plugin &&other) noexcept {
|
||||||
this->m_handle = other.m_handle;
|
this->m_handle = other.m_handle;
|
||||||
|
this->m_path = std::move(other.m_path);
|
||||||
|
|
||||||
this->m_initializePluginFunction = other.m_initializePluginFunction;
|
this->m_initializePluginFunction = other.m_initializePluginFunction;
|
||||||
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
|
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
|
||||||
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
|
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
|
||||||
|
@ -52,9 +54,13 @@ namespace hex {
|
||||||
dlclose(this->m_handle);
|
dlclose(this->m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::initializePlugin() const {
|
bool Plugin::initializePlugin() const {
|
||||||
if (this->m_initializePluginFunction != nullptr)
|
if (this->m_initializePluginFunction != nullptr) {
|
||||||
this->m_initializePluginFunction();
|
this->m_initializePluginFunction();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Plugin::getPluginName() const {
|
std::string Plugin::getPluginName() const {
|
||||||
|
@ -83,6 +89,12 @@ namespace hex {
|
||||||
this->m_setImGuiContextFunction(ctx);
|
this->m_setImGuiContextFunction(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fs::path &Plugin::getPath() const {
|
||||||
|
return this->m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PluginManager::load(const fs::path &pluginFolder) {
|
bool PluginManager::load(const fs::path &pluginFolder) {
|
||||||
if (!fs::exists(pluginFolder))
|
if (!fs::exists(pluginFolder))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -49,7 +49,8 @@ namespace hex::init {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
status = task() && status;
|
status = task() && status;
|
||||||
} catch (...) {
|
} catch (std::exception &e) {
|
||||||
|
log::error("Init task {} threw an exception: {}", name, e.what());
|
||||||
status = false;
|
status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace hex::init {
|
||||||
bool createDirectories() {
|
bool createDirectories() {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
std::array paths = {
|
constexpr std::array paths = {
|
||||||
ImHexPath::Patterns,
|
ImHexPath::Patterns,
|
||||||
ImHexPath::PatternsInclude,
|
ImHexPath::PatternsInclude,
|
||||||
ImHexPath::Magic,
|
ImHexPath::Magic,
|
||||||
|
@ -66,7 +66,8 @@ namespace hex::init {
|
||||||
ImHexPath::Config,
|
ImHexPath::Config,
|
||||||
ImHexPath::Constants,
|
ImHexPath::Constants,
|
||||||
ImHexPath::Yara,
|
ImHexPath::Yara,
|
||||||
ImHexPath::Python
|
ImHexPath::Python,
|
||||||
|
ImHexPath::Logs
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto path : paths) {
|
for (auto path : paths) {
|
||||||
|
@ -225,7 +226,8 @@ namespace hex::init {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||||
plugin.initializePlugin();
|
if (!plugin.initializePlugin())
|
||||||
|
log::error("Failed to initialize plugin {}", plugin.getPath().filename().string());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -3,13 +3,18 @@
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
|
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
void Window::initNative() {
|
void Window::initNative() {
|
||||||
|
if (!isatty(STDOUT_FILENO)) {
|
||||||
|
log::redirectToFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupNativeWindow() {
|
void Window::setupNativeWindow() {
|
||||||
|
|
|
@ -2,12 +2,17 @@
|
||||||
|
|
||||||
#if defined(OS_MACOS)
|
#if defined(OS_MACOS)
|
||||||
|
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
void Window::initNative() {
|
void Window::initNative() {
|
||||||
|
if (!isatty(STDOUT_FILENO)) {
|
||||||
|
log::redirectToFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupNativeWindow() {
|
void Window::setupNativeWindow() {
|
||||||
|
|
|
@ -172,25 +172,26 @@
|
||||||
// Redirect cin, cout and cerr to that console
|
// Redirect cin, cout and cerr to that console
|
||||||
freopen("CONIN$", "r", stdin);
|
freopen("CONIN$", "r", stdin);
|
||||||
freopen("CONOUT$", "w", stdout);
|
freopen("CONOUT$", "w", stdout);
|
||||||
freopen("CONERR$", "w", stderr);
|
freopen("CONOUT$", "w", stderr);
|
||||||
setvbuf(stdin, nullptr, _IONBF, 0);
|
setvbuf(stdin, nullptr, _IONBF, 0);
|
||||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
setvbuf(stderr, nullptr, _IONBF, 0);
|
setvbuf(stderr, nullptr, _IONBF, 0);
|
||||||
|
|
||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
}
|
|
||||||
|
|
||||||
|
// Enable color format specifiers in console
|
||||||
// Enable color format specifiers in console
|
{
|
||||||
{
|
auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
if (hConsole != INVALID_HANDLE_VALUE) {
|
||||||
if (hConsole != INVALID_HANDLE_VALUE) {
|
DWORD mode = 0;
|
||||||
DWORD mode = 0;
|
if (::GetConsoleMode(hConsole, &mode)) {
|
||||||
if (::GetConsoleMode(hConsole, &mode)) {
|
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||||
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
::SetConsoleMode(hConsole, mode);
|
||||||
::SetConsoleMode(hConsole, mode);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log::redirectToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open new files in already existing ImHex instance
|
// Open new files in already existing ImHex instance
|
||||||
|
|
Loading…
Reference in New Issue