Update logging to reflect msvc updates on std::format (#883)

This commit is contained in:
kizer 2022-06-17 17:28:10 +09:00 committed by GitHub
parent c6cf47ea2d
commit 2f4c0bbc97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 238 additions and 183 deletions

View file

@ -25,7 +25,7 @@
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<OutDir>..\bin\$(Configuration)\</OutDir> <OutDir>..\bin\$(Configuration)\</OutDir>

View file

@ -13,32 +13,32 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam, HANDLE hMainThreadContinue) {
ConsoleSetup(L"Dalamud Boot"); ConsoleSetup(L"Dalamud Boot");
if (const auto logFilePath = utils::get_env<std::wstring>("DALAMUD_BOOT_LOGFILE"); logFilePath.empty()) if (const auto logFilePath = utils::get_env<std::wstring>("DALAMUD_BOOT_LOGFILE"); logFilePath.empty())
logging::print<logging::I>("No log file path given; not logging to file."); logging::I("No log file path given; not logging to file.");
else { else {
try { try {
logging::start_file_logging(logFilePath, !bootconfig::is_show_console()); logging::start_file_logging(logFilePath, !bootconfig::is_show_console());
logging::print<logging::I>(L"Logging to file: {}", logFilePath); logging::I("Logging to file: {}", logFilePath);
} catch (const std::exception& e) { } catch (const std::exception& e) {
logging::print<logging::E>(L"Couldn't open log file: {}", logFilePath); logging::E("Couldn't open log file: {}", logFilePath);
logging::print<logging::E>("Error: {} / {}", errno, e.what()); logging::E("Error: {} / {}", errno, e.what());
} }
} }
logging::print<logging::I>("Dalamud.Boot Injectable, (c) 2021 XIVLauncher Contributors"); logging::I("Dalamud.Boot Injectable, (c) 2021 XIVLauncher Contributors");
logging::print<logging::I>("Built at: " __DATE__ "@" __TIME__); logging::I("Built at: " __DATE__ "@" __TIME__);
if (bootconfig::wait_messagebox() & bootconfig::WaitMessageboxFlags::BeforeInitialize) if (bootconfig::wait_messagebox() & bootconfig::WaitMessageboxFlags::BeforeInitialize)
MessageBoxW(nullptr, L"Press OK to continue", L"Dalamud Boot", MB_OK); MessageBoxW(nullptr, L"Press OK to continue", L"Dalamud Boot", MB_OK);
logging::print<logging::I>("Applying fixes..."); logging::I("Applying fixes...");
xivfixes::apply_all(true); xivfixes::apply_all(true);
logging::print<logging::I>("Fixes OK"); logging::I("Fixes OK");
if (bootconfig::is_wait_debugger()) { if (bootconfig::is_wait_debugger()) {
logging::print<logging::I>("Waiting for debugger to attach..."); logging::I("Waiting for debugger to attach...");
while (!IsDebuggerPresent()) while (!IsDebuggerPresent())
Sleep(100); Sleep(100);
logging::print<logging::I>("Debugger attached."); logging::I("Debugger attached.");
} }
const auto fs_module_path = utils::get_module_path(g_hModule); const auto fs_module_path = utils::get_module_path(g_hModule);
@ -47,7 +47,7 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam, HANDLE hMainThreadContinue) {
// ============================== CLR ========================================= // // ============================== CLR ========================================= //
logging::print<logging::I>("Calling InitializeClrAndGetEntryPoint"); logging::I("Calling InitializeClrAndGetEntryPoint");
void* entrypoint_vfn; void* entrypoint_vfn;
int result = InitializeClrAndGetEntryPoint( int result = InitializeClrAndGetEntryPoint(
@ -67,16 +67,16 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam, HANDLE hMainThreadContinue) {
// ============================== VEH ======================================== // // ============================== VEH ======================================== //
logging::print<logging::I>("Initializing VEH..."); logging::I("Initializing VEH...");
if (utils::is_running_on_linux()) { if (utils::is_running_on_linux()) {
logging::print<logging::I>("=> VEH was disabled, running on linux"); logging::I("=> VEH was disabled, running on linux");
} else if (bootconfig::is_veh_enabled()) { } else if (bootconfig::is_veh_enabled()) {
if (veh::add_handler(bootconfig::is_veh_full())) if (veh::add_handler(bootconfig::is_veh_full()))
logging::print<logging::I>("=> Done!"); logging::I("=> Done!");
else else
logging::print<logging::I>("=> Failed!"); logging::I("=> Failed!");
} else { } else {
logging::print<logging::I>("VEH was disabled manually"); logging::I("VEH was disabled manually");
} }
// ============================== Dalamud ==================================== // // ============================== Dalamud ==================================== //
@ -91,9 +91,9 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam, HANDLE hMainThreadContinue) {
utils::wait_for_game_window(); utils::wait_for_game_window();
logging::print<logging::I>("Initializing Dalamud..."); logging::I("Initializing Dalamud...");
entrypoint_fn(lpParam, hMainThreadContinue); entrypoint_fn(lpParam, hMainThreadContinue);
logging::print<logging::I>("Done!"); logging::I("Done!");
return 0; return 0;
} }
@ -105,7 +105,7 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
g_hModule = hModule; g_hModule = hModule;
if (const auto mhStatus = MH_Initialize(); MH_OK != mhStatus) { if (const auto mhStatus = MH_Initialize(); MH_OK != mhStatus) {
logging::print<logging::E>("Failed to initialize MinHook (status={})", static_cast<int>(mhStatus)); logging::E("Failed to initialize MinHook (status={})", static_cast<int>(mhStatus));
return FALSE; return FALSE;
} }
@ -118,7 +118,7 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
xivfixes::apply_all(false); xivfixes::apply_all(false);
if (const auto mhStatus = MH_Uninitialize(); MH_OK != mhStatus) { if (const auto mhStatus = MH_Uninitialize(); MH_OK != mhStatus) {
logging::print<logging::E>("Failed to uninitialize MinHook (status={})", static_cast<int>(mhStatus)); logging::E("Failed to uninitialize MinHook (status={})", static_cast<int>(mhStatus));
__fastfail(logging::MinHookUnload); __fastfail(logging::MinHookUnload);
} }

View file

@ -103,7 +103,7 @@ void hooks::getprocaddress_singleton_import_hook::initialize() {
LdrRegisterDllNotification(0, [](ULONG notiReason, const LDR_DLL_NOTIFICATION_DATA* pData, void* context) { LdrRegisterDllNotification(0, [](ULONG notiReason, const LDR_DLL_NOTIFICATION_DATA* pData, void* context) {
if (notiReason == LDR_DLL_NOTIFICATION_REASON_LOADED) { if (notiReason == LDR_DLL_NOTIFICATION_REASON_LOADED) {
const auto dllName = unicode::convert<std::string>(pData->Loaded.FullDllName->Buffer); const auto dllName = unicode::convert<std::string>(pData->Loaded.FullDllName->Buffer);
logging::print<logging::I>(R"({} "{}" has been loaded at 0x{:X} ~ 0x{:X} (0x{:X}); finding import table items to hook.)", logging::I(R"({} "{}" has been loaded at 0x{:X} ~ 0x{:X} (0x{:X}); finding import table items to hook.)",
LogTag, dllName, LogTag, dllName,
reinterpret_cast<size_t>(pData->Loaded.DllBase), reinterpret_cast<size_t>(pData->Loaded.DllBase),
reinterpret_cast<size_t>(pData->Loaded.DllBase) + pData->Loaded.SizeOfImage, reinterpret_cast<size_t>(pData->Loaded.DllBase) + pData->Loaded.SizeOfImage,
@ -111,7 +111,7 @@ void hooks::getprocaddress_singleton_import_hook::initialize() {
reinterpret_cast<getprocaddress_singleton_import_hook*>(context)->hook_module(utils::loaded_module(pData->Loaded.DllBase)); reinterpret_cast<getprocaddress_singleton_import_hook*>(context)->hook_module(utils::loaded_module(pData->Loaded.DllBase));
} else if (notiReason == LDR_DLL_NOTIFICATION_REASON_UNLOADED) { } else if (notiReason == LDR_DLL_NOTIFICATION_REASON_UNLOADED) {
const auto dllName = unicode::convert<std::string>(pData->Unloaded.FullDllName->Buffer); const auto dllName = unicode::convert<std::string>(pData->Unloaded.FullDllName->Buffer);
logging::print<logging::I>(R"({} "{}" has been unloaded.)", LogTag, dllName); logging::I(R"({} "{}" has been unloaded.)", LogTag, dllName);
} }
}, this, &m_ldrDllNotificationCookie); }, this, &m_ldrDllNotificationCookie);
} }
@ -119,7 +119,7 @@ void hooks::getprocaddress_singleton_import_hook::initialize() {
FARPROC hooks::getprocaddress_singleton_import_hook::get_proc_address_handler(HMODULE hModule, LPCSTR lpProcName) { FARPROC hooks::getprocaddress_singleton_import_hook::get_proc_address_handler(HMODULE hModule, LPCSTR lpProcName) {
if (const auto it1 = m_targetFns.find(hModule); it1 != m_targetFns.end()) { if (const auto it1 = m_targetFns.find(hModule); it1 != m_targetFns.end()) {
if (const auto it2 = it1->second.find(lpProcName); it2 != it1->second.end()) { if (const auto it2 = it1->second.find(lpProcName); it2 != it1->second.end()) {
logging::print<logging::I>(R"({} Redirecting GetProcAddress("{}", "{}"))", LogTag, m_dllNameMap[hModule], lpProcName); logging::I(R"({} Redirecting GetProcAddress("{}", "{}"))", LogTag, m_dllNameMap[hModule], lpProcName);
return reinterpret_cast<FARPROC>(it2->second); return reinterpret_cast<FARPROC>(it2->second);
} }
@ -139,7 +139,7 @@ void hooks::getprocaddress_singleton_import_hook::hook_module(const utils::loade
if (void* pGetProcAddressImport; mod.find_imported_function_pointer(dllName.c_str(), targetFn.c_str(), 0, pGetProcAddressImport)) { if (void* pGetProcAddressImport; mod.find_imported_function_pointer(dllName.c_str(), targetFn.c_str(), 0, pGetProcAddressImport)) {
auto& hook = m_hooks[hModule][targetFn][mod]; auto& hook = m_hooks[hModule][targetFn][mod];
if (!hook) { if (!hook) {
logging::print<logging::I>("{} Hooking {}!{} imported by {}", LogTag, dllName, targetFn, unicode::convert<std::string>(mod.path().wstring())); logging::I("{} Hooking {}!{} imported by {}", LogTag, dllName, targetFn, unicode::convert<std::string>(mod.path().wstring()));
hook.emplace(std::format("getprocaddress_singleton_import_hook::hook_module({}!{})", dllName, targetFn), static_cast<void**>(pGetProcAddressImport), pfnThunk); hook.emplace(std::format("getprocaddress_singleton_import_hook::hook_module({}!{})", dllName, targetFn), static_cast<void**>(pGetProcAddressImport), pfnThunk);
} }

View file

@ -10,48 +10,6 @@ static bool s_bLoaded = false;
static bool s_bSkipLogFileWrite = false; static bool s_bSkipLogFileWrite = false;
static std::shared_ptr<void> s_hLogFile; static std::shared_ptr<void> s_hLogFile;
void logging::print(Level level, const char* s) {
SYSTEMTIME st;
GetLocalTime(&st);
std::string estr;
switch (level) {
case Verbose:
estr = std::format("[{:02}:{:02}:{:02} CPP/VRB] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Debug:
estr = std::format("[{:02}:{:02}:{:02} CPP/DBG] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Info:
estr = std::format("[{:02}:{:02}:{:02} CPP/INF] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Warning:
estr = std::format("[{:02}:{:02}:{:02} CPP/WRN] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Error:
estr = std::format("[{:02}:{:02}:{:02} CPP/ERR] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Fatal:
estr = std::format("[{:02}:{:02}:{:02} CPP/FTL] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
default:
estr = std::format("[{:02}:{:02}:{:02} CPP/???] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
}
OutputDebugStringW(unicode::convert<std::wstring>(estr).c_str());
// Handle accesses should not be done during DllMain process attach/detach calls
if (s_bLoaded) {
DWORD wr{};
WriteFile(GetStdHandle(STD_ERROR_HANDLE), &estr[0], static_cast<DWORD>(estr.size()), &wr, nullptr);
if (s_hLogFile && !s_bSkipLogFileWrite) {
WriteFile(s_hLogFile.get(), &estr[0], static_cast<DWORD>(estr.size()), &wr, nullptr);
}
}
}
void logging::start_file_logging(const std::filesystem::path& path, bool redirect_stderrout) { void logging::start_file_logging(const std::filesystem::path& path, bool redirect_stderrout) {
if (s_hLogFile) if (s_hLogFile)
return; return;
@ -69,14 +27,14 @@ void logging::start_file_logging(const std::filesystem::path& path, bool redirec
} }
const auto h = CreateFile(path.wstring().c_str(), const auto h = CreateFile(path.wstring().c_str(),
GENERIC_WRITE, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, OPEN_ALWAYS, 0, nullptr); nullptr, OPEN_ALWAYS, 0, nullptr);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
throw std::runtime_error(std::format("Win32 error {}(0x{:x})", GetLastError(), GetLastError())); throw std::runtime_error(std::format("Win32 error {}(0x{:x})", GetLastError(), GetLastError()));
SetFilePointer(h, 0, 0, FILE_END); SetFilePointer(h, 0, 0, FILE_END);
s_hLogFile = { h, &CloseHandle }; s_hLogFile = {h, &CloseHandle};
if (redirect_stderrout) { if (redirect_stderrout) {
SetStdHandle(STD_ERROR_HANDLE, h); SetStdHandle(STD_ERROR_HANDLE, h);
@ -88,3 +46,46 @@ void logging::start_file_logging(const std::filesystem::path& path, bool redirec
void logging::update_dll_load_status(bool loaded) { void logging::update_dll_load_status(bool loaded) {
s_bLoaded = loaded; s_bLoaded = loaded;
} }
template<>
void logging::print<char>(Level level, const char* s) {
SYSTEMTIME st;
GetLocalTime(&st);
std::string estr;
switch (level) {
case Level::Verbose:
estr = std::format("[{:02}:{:02}:{:02} CPP/VRB] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Level::Debug:
estr = std::format("[{:02}:{:02}:{:02} CPP/DBG] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Level::Info:
estr = std::format("[{:02}:{:02}:{:02} CPP/INF] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Level::Warning:
estr = std::format("[{:02}:{:02}:{:02} CPP/WRN] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Level::Error:
estr = std::format("[{:02}:{:02}:{:02} CPP/ERR] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
case Level::Fatal:
estr = std::format("[{:02}:{:02}:{:02} CPP/FTL] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
default:
estr = std::format("[{:02}:{:02}:{:02} CPP/???] {}\n", st.wHour, st.wMinute, st.wSecond, s);
break;
}
OutputDebugStringW(unicode::convert<std::wstring>(estr).c_str());
// Handle accesses should not be done during DllMain process attach/detach calls
if (s_bLoaded) {
DWORD wr{};
WriteFile(GetStdHandle(STD_ERROR_HANDLE), &estr[0], static_cast<DWORD>(estr.size()), &wr, nullptr);
if (s_hLogFile && !s_bSkipLogFileWrite) {
WriteFile(s_hLogFile.get(), &estr[0], static_cast<DWORD>(estr.size()), &wr, nullptr);
}
}
}

View file

@ -2,25 +2,18 @@
#include <filesystem> #include <filesystem>
#include <format> #include <format>
#include <numeric>
#include <string> #include <string>
#include "unicode.h" #include "unicode.h"
namespace logging { namespace logging {
enum Level : int { enum class Level : int {
Verbose = 0, Verbose = 0,
V = 0,
Debug = 1, Debug = 1,
D = 1,
Info = 2, Info = 2,
I = 2,
Warning = 3, Warning = 3,
W = 3,
Error = 4, Error = 4,
E = 4,
Fatal = 5, Fatal = 5,
F = 5,
}; };
enum FastFailErrorCode : int { enum FastFailErrorCode : int {
@ -28,42 +21,105 @@ namespace logging {
MinHookUnload, MinHookUnload,
}; };
void print(Level level, const char* s); /**
* @brief Starts writing log to specified file.
inline void print(Level level, const wchar_t* s) { */
const auto cs = unicode::convert<std::string>(s);
print(level, cs.c_str());
}
inline void print(Level level, const std::string& s) {
print(level, s.c_str());
}
inline void print(Level level, const std::wstring& s) {
print(level, s.c_str());
}
template<Level level, typename T>
inline void print(const T* s) {
print(level, s);
}
template<typename Arg, typename...Args>
inline void print(Level level, const char* pcszFormat, Arg arg1, Args...args) {
print(level, std::format(pcszFormat, std::forward<Arg>(arg1), std::forward<Args>(args)...));
}
template<typename Arg, typename...Args>
inline void print(Level level, const wchar_t* pcszFormat, Arg arg1, Args...args) {
print(level, std::format(pcszFormat, std::forward<Arg>(arg1), std::forward<Args>(args)...));
}
template<Level level, typename T, typename Arg, typename...Args, typename = std::enable_if_t<std::is_integral_v<T>>>
inline void print(const T* pcszFormat, Arg arg1, Args...args) {
print(level, std::format(pcszFormat, std::forward<Arg>(arg1), std::forward<Args>(args)...));
}
void start_file_logging(const std::filesystem::path& path, bool redirect_stderrout = false); void start_file_logging(const std::filesystem::path& path, bool redirect_stderrout = false);
/**
* @brief Marks this DLL either as loaded or unloaded, top prevent accessing handles when the DLL is not loaded.
*/
void update_dll_load_status(bool loaded); void update_dll_load_status(bool loaded);
};
/**
* @brief Prints log, unformatted.
* @param level Log level.
* @param s Log to print, as a C-string.
*/
template<typename TElem>
void print(Level level, const TElem* s) { print(level, unicode::convert<std::string>(s).c_str()); }
/**
* @brief Prints log, unformatted.
* @param level Log level.
* @param s Log to print, as a basic_string.
*/
template<typename TElem, typename TTraits = std::char_traits<TElem>, typename TAlloc = std::allocator<TElem>>
void print(Level level, const std::basic_string<TElem, TTraits, TAlloc>& s) { print(level, s.c_str()); }
/**
* @brief Prints log, unformatted.
* @param level Log level.
* @param s Log to print, as a basic_string_view.
*/
template<typename TElem, typename TTraits = std::char_traits<TElem>>
void print(Level level, const std::basic_string_view<TElem, TTraits>& s) { print(level, unicode::convert<std::string>(s).c_str()); }
template<>
void print<char>(Level level, const char* s);
template<typename>
struct is_basic_string : std::false_type {};
template<typename TElem, typename TTraits, typename TAlloc>
struct is_basic_string<std::basic_string<TElem, TTraits, TAlloc>> : std::true_type {};
template<typename T>
inline constexpr auto is_basic_string_v = is_basic_string<T>::value;
template<typename>
struct is_basic_string_view : std::false_type {};
template<typename TElem, typename TTraits, typename TAlloc>
struct is_basic_string_view<std::basic_string<TElem, TTraits, TAlloc>> : std::true_type {};
template<typename T>
inline constexpr auto is_basic_string_view_v = is_basic_string_view<T>::value;
template<typename T>
auto to_format_arg(T&& x) {
using Td = std::remove_cvref_t<T>;
if constexpr (std::is_pointer_v<Td>) {
using Tdd = std::remove_cvref_t<std::remove_pointer_t<Td>>;
if constexpr (std::is_same_v<Tdd, wchar_t> || std::is_same_v<Tdd, char8_t> || std::is_same_v<Tdd, char16_t> || std::is_same_v<Tdd, char32_t>)
return unicode::convert<std::string>(x);
else
return std::forward<T>(x);
} else {
if constexpr (is_basic_string_v<Td> || is_basic_string_view_v<Td>) {
using Tdd = Td::value_type;
if constexpr (std::is_same_v<Tdd, wchar_t> || std::is_same_v<Tdd, char8_t> || std::is_same_v<Tdd, char16_t> || std::is_same_v<Tdd, char32_t>)
return unicode::convert<std::string>(x);
else
return std::forward<T>(x);
} else if constexpr (std::is_same_v<Td, std::filesystem::path>) {
auto u8s = x.u8string();
return std::move(*reinterpret_cast<std::string*>(&u8s));
} else {
return std::forward<T>(x);
}
}
}
/**
* @brief Prints log, formatted.
* @param level Log level.
* @param fmt C-string.
* @param arg1 First format parameter.
* @param args Second and further format parameters, if any.
*/
template<typename Arg, typename...Args>
void print(Level level, const char* fmt, Arg&& arg1, Args&&...args) {
print(level, std::vformat(fmt, std::make_format_args(to_format_arg(std::forward<Arg>(arg1)), to_format_arg(std::forward<Args>(args))...)));
}
template<typename...Args> void V(Args&&...args) { print(Level::Verbose, std::forward<Args>(args)...); }
template<typename...Args> void D(Args&&...args) { print(Level::Debug, std::forward<Args>(args)...); }
template<typename...Args> void I(Args&&...args) { print(Level::Info, std::forward<Args>(args)...); }
template<typename...Args> void W(Args&&...args) { print(Level::Warning, std::forward<Args>(args)...); }
template<typename...Args> void E(Args&&...args) { print(Level::Error, std::forward<Args>(args)...); }
template<typename...Args> void F(Args&&...args) { print(Level::Fatal, std::forward<Args>(args)...); }
}

View file

@ -234,7 +234,7 @@ void* get_mapped_image_base_address(HANDLE hProcess, const std::filesystem::path
return mbi.AllocationBase; return mbi.AllocationBase;
} catch (const std::exception& e) { } catch (const std::exception& e) {
logging::print<logging::W>("Failed to check memory block 0x{:X}(len=0x{:X}): {}", mbi.BaseAddress, mbi.RegionSize, e.what()); logging::W("Failed to check memory block 0x{:X}(len=0x{:X}): {}", mbi.BaseAddress, mbi.RegionSize, e.what());
continue; continue;
} }
} }

View file

@ -48,7 +48,7 @@ namespace unicode {
char32_t c{}; char32_t c{};
for (size_t decLen = 0, decIdx = 0; decIdx < in.size() && (decLen = unicode::decode(c, &in[decIdx], in.size() - decIdx, strict)); decIdx += decLen) { for (size_t decLen = 0, decIdx = 0; decIdx < in.size() && (decLen = unicode::decode(c, &in[decIdx], in.size() - decIdx, strict)); decIdx += decLen) {
const auto encIdx = out.size(); const auto encIdx = out.size();
const auto encLen = unicode::encode<TTo::value_type>(nullptr, c, strict); const auto encLen = unicode::encode<typename TTo::value_type>(nullptr, c, strict);
out.resize(encIdx + encLen); out.resize(encIdx + encLen);
unicode::encode(&out[encIdx], c, strict); unicode::encode(&out[encIdx], c, strict);
} }

View file

@ -55,8 +55,8 @@ std::span<char> utils::loaded_module::section(const char* pcszSectionName) const
template<typename TEntryType> template<typename TEntryType>
static bool find_imported_function_pointer_helper(const char* pcBaseAddress, const IMAGE_IMPORT_DESCRIPTOR& desc, const IMAGE_DATA_DIRECTORY& dir, std::string_view reqFunc, uint32_t hintOrOrdinal, void*& ppFunctionAddress) { static bool find_imported_function_pointer_helper(const char* pcBaseAddress, const IMAGE_IMPORT_DESCRIPTOR& desc, const IMAGE_DATA_DIRECTORY& dir, std::string_view reqFunc, uint32_t hintOrOrdinal, void*& ppFunctionAddress) {
const auto importLookupsOversizedSpan = std::span(reinterpret_cast<const TEntryType*>(&pcBaseAddress[desc.OriginalFirstThunk]), (dir.Size - desc.OriginalFirstThunk) / sizeof TEntryType); const auto importLookupsOversizedSpan = std::span(reinterpret_cast<const TEntryType*>(&pcBaseAddress[desc.OriginalFirstThunk]), (dir.Size - desc.OriginalFirstThunk) / sizeof(TEntryType));
const auto importAddressesOversizedSpan = std::span(reinterpret_cast<const TEntryType*>(&pcBaseAddress[desc.FirstThunk]), (dir.Size - desc.FirstThunk) / sizeof TEntryType); const auto importAddressesOversizedSpan = std::span(reinterpret_cast<const TEntryType*>(&pcBaseAddress[desc.FirstThunk]), (dir.Size - desc.FirstThunk) / sizeof(TEntryType));
for (size_t i = 0, i_ = (std::min)(importLookupsOversizedSpan.size(), importAddressesOversizedSpan.size()); i < i_ && importLookupsOversizedSpan[i] && importAddressesOversizedSpan[i]; i++) { for (size_t i = 0, i_ = (std::min)(importLookupsOversizedSpan.size(), importAddressesOversizedSpan.size()); i < i_ && importLookupsOversizedSpan[i] && importAddressesOversizedSpan[i]; i++) {
const auto& importLookup = importLookupsOversizedSpan[i]; const auto& importLookup = importLookupsOversizedSpan[i];

View file

@ -218,9 +218,7 @@ namespace utils {
} }
template<typename T> template<typename T>
T get_env(const wchar_t* pcwzName) { T get_env(const wchar_t* pcwzName) = delete;
static_assert(false);
}
template<> template<>
std::wstring get_env(const wchar_t* pcwzName); std::wstring get_env(const wchar_t* pcwzName);
@ -240,9 +238,7 @@ namespace utils {
} }
template<typename T> template<typename T>
std::vector<T> get_env_list(const wchar_t* pcwzName) { std::vector<T> get_env_list(const wchar_t* pcwzName) = delete;
static_assert(false);
}
template<> template<>
std::vector<std::wstring> get_env_list(const wchar_t* pcwzName); std::vector<std::wstring> get_env_list(const wchar_t* pcwzName);

View file

@ -269,16 +269,18 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
L"Dalamud.EntryPoint+VehDelegate, Dalamud", L"Dalamud.EntryPoint+VehDelegate, Dalamud",
nullptr, nullptr, &fn))) nullptr, nullptr, &fn)))
{ {
const auto msg = L"An error within the game has occurred.\n\n" const auto formatted = std::format(
L"An error within the game has occurred.\n\n"
L"This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n" L"This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n"
L"Please try \"Start Over\" or \"Download Index Backup\" in TexTools, an integrity check in the XIVLauncher settings, and disabling plugins you don't need.\n\n" L"Please try \"Start Over\" or \"Download Index Backup\" in TexTools, an integrity check in the XIVLauncher settings, and disabling plugins you don't need.\n\n"
L"The log file is located at:\n" L"The log file is located at:\n"
L"{1}\n\n" L"{1}\n\n"
L"Press OK to exit the application.\n\nFailed to read stack trace: {2:08x}"; L"Press OK to exit the application.\n\nFailed to read stack trace: {2:08x}",
dmp_path, log_path, err);
// show in another thread to prevent messagebox from pumping messages of current thread // show in another thread to prevent messagebox from pumping messages of current thread
std::thread([&]() { std::thread([&]() {
MessageBoxW(nullptr, std::format(msg, dmp_path, log_path, err).c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST); MessageBoxW(nullptr, formatted.c_str(), L"Dalamud Error", MB_OK | MB_ICONERROR | MB_TOPMOST);
}).join(); }).join();
} }
else else

View file

@ -29,9 +29,9 @@ void xivfixes::unhook_dll(bool bApply) {
std::filesystem::path path; std::filesystem::path path;
try { try {
path = mod.path(); path = mod.path();
logging::print<logging::I>(L"{} [{}/{}] Module 0x{:X} ~ 0x{:X} (0x{:X}): \"{}\"", LogTagW, i + 1, mods.size(), mod.address_int(), mod.address_int() + mod.image_size(), mod.image_size(), path.wstring()); logging::I("{} [{}/{}] Module 0x{:X} ~ 0x{:X} (0x{:X}): \"{}\"", LogTagW, i + 1, mods.size(), mod.address_int(), mod.address_int() + mod.image_size(), mod.image_size(), path.wstring());
} catch (const std::exception& e) { } catch (const std::exception& e) {
logging::print<logging::W>("{} [{}/{}] Module 0x{:X}: Failed to resolve path: {}", LogTag, i + 1, mods.size(), mod.address_int(), e.what()); logging::W("{} [{}/{}] Module 0x{:X}: Failed to resolve path: {}", LogTag, i + 1, mods.size(), mod.address_int(), e.what());
continue; continue;
} }
@ -44,7 +44,7 @@ void xivfixes::unhook_dll(bool bApply) {
const auto section = assume_nonempty_span(mod.span_as<char>(sectionHeader.VirtualAddress, sectionHeader.Misc.VirtualSize), ".text[VA:VA+VS]"); const auto section = assume_nonempty_span(mod.span_as<char>(sectionHeader.VirtualAddress, sectionHeader.Misc.VirtualSize), ".text[VA:VA+VS]");
auto hFsDllRaw = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); auto hFsDllRaw = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (hFsDllRaw == INVALID_HANDLE_VALUE) { if (hFsDllRaw == INVALID_HANDLE_VALUE) {
logging::print<logging::W>("{} Module loaded in current process but could not open file: Win32 error {}", LogTag, GetLastError()); logging::W("{} Module loaded in current process but could not open file: Win32 error {}", LogTag, GetLastError());
continue; continue;
} }
auto hFsDll = std::unique_ptr<void, decltype(CloseHandle)*>(hFsDllRaw, &CloseHandle); auto hFsDll = std::unique_ptr<void, decltype(CloseHandle)*>(hFsDllRaw, &CloseHandle);
@ -53,11 +53,11 @@ void xivfixes::unhook_dll(bool bApply) {
SetFilePointer(hFsDll.get(), sectionHeader.PointerToRawData, nullptr, FILE_CURRENT); SetFilePointer(hFsDll.get(), sectionHeader.PointerToRawData, nullptr, FILE_CURRENT);
if (DWORD read{}; ReadFile(hFsDll.get(), &buf[0], static_cast<DWORD>(buf.size()), &read, nullptr)) { if (DWORD read{}; ReadFile(hFsDll.get(), &buf[0], static_cast<DWORD>(buf.size()), &read, nullptr)) {
if (read < section.size_bytes()) { if (read < section.size_bytes()) {
logging::print<logging::W>(L"{} ReadFile: read {} bytes < requested {} bytes", LogTagW, read, section.size_bytes()); logging::W("{} ReadFile: read {} bytes < requested {} bytes", LogTagW, read, section.size_bytes());
continue; continue;
} }
} else { } else {
logging::print<logging::I>(L"{} ReadFile: Win32 error {}", LogTagW, GetLastError()); logging::I("{} ReadFile: Win32 error {}", LogTagW, GetLastError());
continue; continue;
} }
@ -81,7 +81,7 @@ void xivfixes::unhook_dll(bool bApply) {
if (!nmd_x86_decode(&section[i], section.size() - i, &instruction, NMD_X86_MODE_64, NMD_X86_DECODER_FLAGS_ALL)) { if (!nmd_x86_decode(&section[i], section.size() - i, &instruction, NMD_X86_MODE_64, NMD_X86_DECODER_FLAGS_ALL)) {
instructionLength = 1; instructionLength = 1;
if (printed < 64) { if (printed < 64) {
logging::print<logging::W>("{} {}+0x{:0X}: dd {:02X}", LogTag, moduleName, rva, static_cast<uint8_t>(section[i])); logging::W("{} {}+0x{:0X}: dd {:02X}", LogTag, moduleName, rva, static_cast<uint8_t>(section[i]));
printed++; printed++;
} }
} else { } else {
@ -102,16 +102,16 @@ void xivfixes::unhook_dll(bool bApply) {
std::string_view name; std::string_view name;
if (const char* pcszName = mod.address_as<char>(names[j]); pcszName < mod.address() || pcszName >= mod.address() + mod.image_size()) { if (const char* pcszName = mod.address_as<char>(names[j]); pcszName < mod.address() || pcszName >= mod.address() + mod.image_size()) {
if (IsBadReadPtr(pcszName, 256)) { if (IsBadReadPtr(pcszName, 256)) {
logging::print<logging::W>("{} Name #{} points to an invalid address outside the executable. Skipping.", LogTag, j); logging::W("{} Name #{} points to an invalid address outside the executable. Skipping.", LogTag, j);
continue; continue;
} }
name = std::string_view(pcszName, strnlen(pcszName, 256)); name = std::string_view(pcszName, strnlen(pcszName, 256));
logging::print<logging::W>("{} Name #{} points to a seemingly valid address outside the executable: {}", LogTag, j, name); logging::W("{} Name #{} points to a seemingly valid address outside the executable: {}", LogTag, j, name);
} }
if (ordinals[j] >= functions.size()) { if (ordinals[j] >= functions.size()) {
logging::print<logging::W>("{} Ordinal #{} points to function index #{} >= #{}. Skipping.", LogTag, j, ordinals[j], functions.size()); logging::W("{} Ordinal #{} points to function index #{} >= #{}. Skipping.", LogTag, j, ordinals[j], functions.size());
continue; continue;
} }
@ -122,7 +122,7 @@ void xivfixes::unhook_dll(bool bApply) {
} }
} }
logging::print<logging::W>("{} {}+0x{:0X}{}: {}", LogTag, moduleName, rva, resolvedExportName, formatBuf); logging::W("{} {}+0x{:0X}{}: {}", LogTag, moduleName, rva, resolvedExportName, formatBuf);
printed++; printed++;
} }
} }
@ -135,12 +135,12 @@ void xivfixes::unhook_dll(bool bApply) {
} }
if (tenderizer) if (tenderizer)
logging::print<logging::I>("{} Verification and overwriting complete.", LogTag); logging::I("{} Verification and overwriting complete.", LogTag);
else if (doRestore) else if (doRestore)
logging::print<logging::I>("{} Verification complete. Overwriting was not required.", LogTag); logging::I("{} Verification complete. Overwriting was not required.", LogTag);
} catch (const std::exception& e) { } catch (const std::exception& e) {
logging::print<logging::W>("{} Error: {}", LogTag, e.what()); logging::W("{} Error: {}", LogTag, e.what());
} }
} }
} }
@ -180,7 +180,7 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
if (bApply) { if (bApply) {
if (!bootconfig::gamefix_is_enabled(L"prevent_devicechange_crashes")) { if (!bootconfig::gamefix_is_enabled(L"prevent_devicechange_crashes")) {
logging::print<logging::I>("{} Turned off via environment variable.", LogTag); logging::I("{} Turned off via environment variable.", LogTag);
return; return;
} }
@ -193,7 +193,7 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
|| 0 != strcmp(lpClassName, "FFXIVGAME")) || 0 != strcmp(lpClassName, "FFXIVGAME"))
return hWnd; return hWnd;
logging::print<logging::I>(R"({} CreateWindow(0x{:08X}, "{}", "{}", 0x{:08X}, {}, {}, {}, {}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}) called; unhooking CreateWindowExA and hooking WndProc.)", logging::I(R"({} CreateWindow(0x{:08X}, "{}", "{}", 0x{:08X}, {}, {}, {}, {}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}) called; unhooking CreateWindowExA and hooking WndProc.)",
LogTag, dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, reinterpret_cast<size_t>(hWndParent), reinterpret_cast<size_t>(hMenu), reinterpret_cast<size_t>(hInstance), reinterpret_cast<size_t>(lpParam)); LogTag, dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, reinterpret_cast<size_t>(hWndParent), reinterpret_cast<size_t>(hMenu), reinterpret_cast<size_t>(hInstance), reinterpret_cast<size_t>(lpParam));
s_hookCreateWindowExA.reset(); s_hookCreateWindowExA.reset();
@ -202,7 +202,7 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
s_hookWndProc->set_detour([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT { s_hookWndProc->set_detour([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT {
if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) { if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) {
if (!GetGetInputDeviceManager(hWnd)()) { if (!GetGetInputDeviceManager(hWnd)()) {
logging::print<logging::I>("{} WndProc(0x{:X}, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, {}) called but the game does not have InputDeviceManager initialized; doing nothing.", LogTag, reinterpret_cast<size_t>(hWnd), lParam); logging::I("{} WndProc(0x{:X}, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, {}) called but the game does not have InputDeviceManager initialized; doing nothing.", LogTag, reinterpret_cast<size_t>(hWnd), lParam);
return 0; return 0;
} }
} }
@ -213,17 +213,17 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
return hWnd; return hWnd;
}); });
logging::print<logging::I>("{} Enable", LogTag); logging::I("{} Enable", LogTag);
} else { } else {
if (s_hookCreateWindowExA) { if (s_hookCreateWindowExA) {
logging::print<logging::I>("{} Disable CreateWindowExA", LogTag); logging::I("{} Disable CreateWindowExA", LogTag);
s_hookCreateWindowExA.reset(); s_hookCreateWindowExA.reset();
} }
// This will effectively revert any other WndProc alterations, including Dalamud. // This will effectively revert any other WndProc alterations, including Dalamud.
if (s_hookWndProc) { if (s_hookWndProc) {
logging::print<logging::I>("{} Disable WndProc", LogTag); logging::I("{} Disable WndProc", LogTag);
s_hookWndProc.reset(); s_hookWndProc.reset();
} }
} }
@ -235,18 +235,18 @@ void xivfixes::disable_game_openprocess_access_check(bool bApply) {
if (bApply) { if (bApply) {
if (!bootconfig::gamefix_is_enabled(L"disable_game_openprocess_access_check")) { if (!bootconfig::gamefix_is_enabled(L"disable_game_openprocess_access_check")) {
logging::print<logging::I>("{} Turned off via environment variable.", LogTag); logging::I("{} Turned off via environment variable.", LogTag);
return; return;
} }
s_hook.emplace("kernel32.dll!OpenProcess (import, disable_game_openprocess_access_check)", "kernel32.dll", "OpenProcess", 0); s_hook.emplace("kernel32.dll!OpenProcess (import, disable_game_openprocess_access_check)", "kernel32.dll", "OpenProcess", 0);
s_hook->set_detour([](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE { s_hook->set_detour([](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE {
logging::print<logging::I>("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId()); logging::I("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId());
if (dwProcessId == GetCurrentProcessId()) { if (dwProcessId == GetCurrentProcessId()) {
// Prevent game from feeling unsafe that it restarts // Prevent game from feeling unsafe that it restarts
if (dwDesiredAccess & PROCESS_VM_WRITE) { if (dwDesiredAccess & PROCESS_VM_WRITE) {
logging::print<logging::I>("{} Returning failure with last error code set to ERROR_ACCESS_DENIED(5).", LogTag); logging::I("{} Returning failure with last error code set to ERROR_ACCESS_DENIED(5).", LogTag);
SetLastError(ERROR_ACCESS_DENIED); SetLastError(ERROR_ACCESS_DENIED);
return {}; return {};
} }
@ -255,10 +255,10 @@ void xivfixes::disable_game_openprocess_access_check(bool bApply) {
return s_hook->call_original(dwDesiredAccess, bInheritHandle, dwProcessId); return s_hook->call_original(dwDesiredAccess, bInheritHandle, dwProcessId);
}); });
logging::print<logging::I>("{} Enable", LogTag); logging::I("{} Enable", LogTag);
} else { } else {
if (s_hook) { if (s_hook) {
logging::print<logging::I>("{} Disable OpenProcess", LogTag); logging::I("{} Disable OpenProcess", LogTag);
s_hook.reset(); s_hook.reset();
} }
} }
@ -272,7 +272,7 @@ void xivfixes::redirect_openprocess(bool bApply) {
if (bApply) { if (bApply) {
if (!bootconfig::gamefix_is_enabled(L"redirect_openprocess")) { if (!bootconfig::gamefix_is_enabled(L"redirect_openprocess")) {
logging::print<logging::I>("{} Turned off via environment variable.", LogTag); logging::I("{} Turned off via environment variable.", LogTag);
return; return;
} }
@ -281,7 +281,7 @@ void xivfixes::redirect_openprocess(bool bApply) {
hook->set_detour([hook = hook.get()](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE { hook->set_detour([hook = hook.get()](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE {
if (dwProcessId == GetCurrentProcessId()) { if (dwProcessId == GetCurrentProcessId()) {
if (s_silenceSet.emplace(GetCurrentThreadId()).second) if (s_silenceSet.emplace(GetCurrentThreadId()).second)
logging::print<logging::I>("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}. Redirecting to DuplicateHandle.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId()); logging::I("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}. Redirecting to DuplicateHandle.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId());
if (HANDLE res; DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &res, dwDesiredAccess, bInheritHandle, 0)) if (HANDLE res; DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &res, dwDesiredAccess, bInheritHandle, 0))
return res; return res;
@ -292,14 +292,14 @@ void xivfixes::redirect_openprocess(bool bApply) {
}); });
s_hook = std::dynamic_pointer_cast<hooks::base_untyped_hook>(std::move(hook)); s_hook = std::dynamic_pointer_cast<hooks::base_untyped_hook>(std::move(hook));
logging::print<logging::I>("{} Enable via import_hook", LogTag); logging::I("{} Enable via import_hook", LogTag);
} else { } else {
auto hook = std::make_shared<hooks::direct_hook<decltype(OpenProcess)>>("kernel32.dll!OpenProcess (direct, redirect_openprocess)", OpenProcess); auto hook = std::make_shared<hooks::direct_hook<decltype(OpenProcess)>>("kernel32.dll!OpenProcess (direct, redirect_openprocess)", OpenProcess);
hook->set_detour([hook = hook.get()](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE { hook->set_detour([hook = hook.get()](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE {
if (dwProcessId == GetCurrentProcessId()) { if (dwProcessId == GetCurrentProcessId()) {
if (s_silenceSet.emplace(GetCurrentThreadId()).second) if (s_silenceSet.emplace(GetCurrentThreadId()).second)
logging::print<logging::I>("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}. Redirecting to DuplicateHandle.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId()); logging::I("{} OpenProcess(0x{:08X}, {}, {}) was invoked by thread {}. Redirecting to DuplicateHandle.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId());
if (HANDLE res; DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &res, dwDesiredAccess, bInheritHandle, 0)) if (HANDLE res; DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &res, dwDesiredAccess, bInheritHandle, 0))
return res; return res;
@ -310,7 +310,7 @@ void xivfixes::redirect_openprocess(bool bApply) {
}); });
s_hook = std::dynamic_pointer_cast<hooks::base_untyped_hook>(std::move(hook)); s_hook = std::dynamic_pointer_cast<hooks::base_untyped_hook>(std::move(hook));
logging::print<logging::I>("{} Enable via direct_hook", LogTag); logging::I("{} Enable via direct_hook", LogTag);
} }
//std::thread([]() { //std::thread([]() {
@ -321,7 +321,7 @@ void xivfixes::redirect_openprocess(bool bApply) {
} else { } else {
if (s_hook) { if (s_hook) {
logging::print<logging::I>("{} Disable OpenProcess", LogTag); logging::I("{} Disable OpenProcess", LogTag);
s_hook.reset(); s_hook.reset();
} }
} }
@ -341,16 +341,16 @@ void xivfixes::apply_all(bool bApply) {
} catch (const std::exception& e) { } catch (const std::exception& e) {
if (bApply) if (bApply)
logging::print<logging::W>("Error trying to activate fixup [{}]: {}", taskName, e.what()); logging::W("Error trying to activate fixup [{}]: {}", taskName, e.what());
else else
logging::print<logging::W>("Error trying to deactivate fixup [{}]: {}", taskName, e.what()); logging::W("Error trying to deactivate fixup [{}]: {}", taskName, e.what());
continue; continue;
} }
if (bApply) if (bApply)
logging::print<logging::I>("Fixup [{}] activated.", taskName); logging::I("Fixup [{}] activated.", taskName);
else else
logging::print<logging::I>("Fixup [{}] deactivated.", taskName); logging::I("Fixup [{}] deactivated.", taskName);
} }
} }

View file

@ -26,7 +26,7 @@
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<OutDir>..\bin\$(Configuration)\</OutDir> <OutDir>..\bin\$(Configuration)\</OutDir>

View file

@ -9,8 +9,8 @@
int wmain(int argc, wchar_t** argv) int wmain(int argc, wchar_t** argv)
{ {
logging::print<logging::I>("Dalamud Injector, (c) 2021 XIVLauncher Contributors"); logging::I("Dalamud Injector, (c) 2021 XIVLauncher Contributors");
logging::print<logging::I>("Built at : " __DATE__ "@" __TIME__); logging::I("Built at : " __DATE__ "@" __TIME__);
wchar_t _module_path[MAX_PATH]; wchar_t _module_path[MAX_PATH];
GetModuleFileNameW(NULL, _module_path, sizeof _module_path / 2); GetModuleFileNameW(NULL, _module_path, sizeof _module_path / 2);
@ -37,9 +37,9 @@ int wmain(int argc, wchar_t** argv)
typedef void (CORECLR_DELEGATE_CALLTYPE* custom_component_entry_point_fn)(int, wchar_t**); typedef void (CORECLR_DELEGATE_CALLTYPE* custom_component_entry_point_fn)(int, wchar_t**);
custom_component_entry_point_fn entrypoint_fn = reinterpret_cast<custom_component_entry_point_fn>(entrypoint_vfn); custom_component_entry_point_fn entrypoint_fn = reinterpret_cast<custom_component_entry_point_fn>(entrypoint_vfn);
logging::print<logging::I>("Running Dalamud Injector..."); logging::I("Running Dalamud Injector...");
entrypoint_fn(argc, argv); entrypoint_fn(argc, argv);
logging::print<logging::I>("Done!"); logging::I("Done!");
return 0; return 0;
} }

View file

@ -83,7 +83,7 @@ int CoreCLR::load_runtime(const std::wstring& runtime_config_path, const struct
// Success_HostAlreadyInitialized // Success_HostAlreadyInitialized
if (result == 1) if (result == 1)
{ {
logging::print<logging::I>("Success_HostAlreadyInitialized (0x1)"); logging::I("Success_HostAlreadyInitialized (0x1)");
result = 0; result = 0;
} }

View file

@ -63,7 +63,7 @@ int InitializeClrAndGetEntryPoint(
if (result != 0) if (result != 0)
{ {
logging::print<logging::E>("Unable to get RoamingAppData path (err={})", result); logging::E("Unable to get RoamingAppData path (err={})", result);
return result; return result;
} }
@ -73,13 +73,13 @@ int InitializeClrAndGetEntryPoint(
// =========================================================================== // // =========================================================================== //
logging::print<logging::I>(L"with dotnet_path: {}", dotnet_path); logging::I("with dotnet_path: {}", dotnet_path);
logging::print<logging::I>(L"with config_path: {}", runtimeconfig_path.c_str()); logging::I("with config_path: {}", runtimeconfig_path);
logging::print<logging::I>(L"with module_path: {}", module_path.c_str()); logging::I("with module_path: {}", module_path);
if (!std::filesystem::exists(dotnet_path)) if (!std::filesystem::exists(dotnet_path))
{ {
logging::print<logging::E>("Error: Unable to find .NET runtime path"); logging::E("Error: Unable to find .NET runtime path");
return 1; return 1;
} }
@ -90,13 +90,13 @@ int InitializeClrAndGetEntryPoint(
dotnet_path, dotnet_path,
}; };
logging::print<logging::I>("Loading hostfxr..."); logging::I("Loading hostfxr...");
if ((result = g_clr->load_hostfxr(&init_parameters)) != 0) if ((result = g_clr->load_hostfxr(&init_parameters)) != 0)
{ {
logging::print<logging::E>("Failed to load the `hostfxr` library (err=0x{:08x})", result); logging::E("Failed to load the `hostfxr` library (err=0x{:08x})", result);
return result; return result;
} }
logging::print<logging::I>("Done!"); logging::I("Done!");
// =========================================================================== // // =========================================================================== //
@ -107,17 +107,17 @@ int InitializeClrAndGetEntryPoint(
dotnet_path, dotnet_path,
}; };
logging::print<logging::I>("Loading coreclr... "); logging::I("Loading coreclr... ");
if ((result = g_clr->load_runtime(runtimeconfig_path, &runtime_parameters)) != 0) if ((result = g_clr->load_runtime(runtimeconfig_path, &runtime_parameters)) != 0)
{ {
logging::print<logging::E>("Failed to load coreclr (err=0x{:08X})", static_cast<uint32_t>(result)); logging::E("Failed to load coreclr (err=0x{:08X})", static_cast<uint32_t>(result));
return result; return result;
} }
logging::print<logging::I>("Done!"); logging::I("Done!");
// =========================================================================== // // =========================================================================== //
logging::print<logging::I>("Loading module..."); logging::I("Loading module...");
if ((result = g_clr->load_assembly_and_get_function_pointer( if ((result = g_clr->load_assembly_and_get_function_pointer(
module_path.c_str(), module_path.c_str(),
entrypoint_assembly_name.c_str(), entrypoint_assembly_name.c_str(),
@ -125,10 +125,10 @@ int InitializeClrAndGetEntryPoint(
entrypoint_delegate_type_name.c_str(), entrypoint_delegate_type_name.c_str(),
nullptr, entrypoint_fn)) != 0) nullptr, entrypoint_fn)) != 0)
{ {
logging::print<logging::E>("Failed to load module (err={})", result); logging::E("Failed to load module (err={})", result);
return result; return result;
} }
logging::print<logging::I>("Done!"); logging::I("Done!");
// =========================================================================== // // =========================================================================== //