mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Attempt to fix for alex compat (#884)
This commit is contained in:
parent
399bc7b4de
commit
d3c230f9e0
2 changed files with 94 additions and 15 deletions
|
|
@ -53,7 +53,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dbghelp.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\lib\CoreCLR;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ static std::span<T> assume_nonempty_span(std::span<T> t, const char* descr) {
|
|||
throw std::runtime_error(std::format("Unexpected empty span found: {}", descr));
|
||||
return t;
|
||||
}
|
||||
|
||||
void xivfixes::unhook_dll(bool bApply) {
|
||||
static const auto LogTag = "[xivfixes:unhook_dll]";
|
||||
static const auto LogTagW = L"[xivfixes:unhook_dll]";
|
||||
|
|
@ -24,15 +23,15 @@ void xivfixes::unhook_dll(bool bApply) {
|
|||
return;
|
||||
|
||||
const auto mods = utils::loaded_module::all_modules();
|
||||
for (size_t i = 0; i < mods.size(); i++) {
|
||||
const auto& mod = mods[i];
|
||||
|
||||
const auto test_module = [&](size_t i, const utils::loaded_module & mod) {
|
||||
std::filesystem::path path;
|
||||
try {
|
||||
path = mod.path();
|
||||
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) {
|
||||
logging::W("{} [{}/{}] Module 0x{:X}: Failed to resolve path: {}", LogTag, i + 1, mods.size(), mod.address_int(), e.what());
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto moduleName = unicode::convert<std::string>(path.filename().wstring());
|
||||
|
|
@ -45,7 +44,7 @@ void xivfixes::unhook_dll(bool bApply) {
|
|||
auto hFsDllRaw = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (hFsDllRaw == INVALID_HANDLE_VALUE) {
|
||||
logging::W("{} Module loaded in current process but could not open file: Win32 error {}", LogTag, GetLastError());
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
auto hFsDll = std::unique_ptr<void, decltype(CloseHandle)*>(hFsDllRaw, &CloseHandle);
|
||||
|
||||
|
|
@ -54,11 +53,11 @@ void xivfixes::unhook_dll(bool bApply) {
|
|||
if (DWORD read{}; ReadFile(hFsDll.get(), &buf[0], static_cast<DWORD>(buf.size()), &read, nullptr)) {
|
||||
if (read < section.size_bytes()) {
|
||||
logging::W("{} ReadFile: read {} bytes < requested {} bytes", LogTagW, read, section.size_bytes());
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
logging::I("{} ReadFile: Win32 error {}", LogTagW, GetLastError());
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
auto doRestore = false;
|
||||
|
|
@ -142,8 +141,21 @@ void xivfixes::unhook_dll(bool bApply) {
|
|||
} catch (const std::exception& e) {
|
||||
logging::W("{} Error: {}", LogTag, e.what());
|
||||
}
|
||||
};
|
||||
|
||||
const auto aaaa = [&]() {
|
||||
for (size_t i = 0; i < mods.size(); i++) {
|
||||
const auto& mod = mods[i];
|
||||
__try {
|
||||
test_module(i, mod);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
logging::W("{} Error: Access Violation", LogTag);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
aaaa();
|
||||
}
|
||||
|
||||
using TFnGetInputDeviceManager = void* ();
|
||||
static TFnGetInputDeviceManager* GetGetInputDeviceManager(HWND hwnd) {
|
||||
|
|
@ -196,11 +208,12 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
|
|||
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));
|
||||
|
||||
s_hookCreateWindowExA.reset();
|
||||
|
||||
s_hookWndProc.emplace("FFXIVGAME:WndProc (prevent_devicechange_crashes)", hWnd);
|
||||
s_hookWndProc->set_detour([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT {
|
||||
if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) {
|
||||
|
||||
if (uMsg == WM_CREATE) {
|
||||
s_hookCreateWindowExA.reset();
|
||||
} else if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) {
|
||||
if (!GetGetInputDeviceManager(hWnd)()) {
|
||||
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;
|
||||
|
|
@ -229,6 +242,64 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_xivalex(const std::filesystem::path& dllPath) {
|
||||
DWORD verHandle = 0;
|
||||
std::vector<uint8_t> block;
|
||||
block.resize(GetFileVersionInfoSizeW(dllPath.c_str(), &verHandle));
|
||||
if (block.empty())
|
||||
return false;
|
||||
if (!GetFileVersionInfoW(dllPath.c_str(), 0, static_cast<DWORD>(block.size()), &block[0]))
|
||||
return false;
|
||||
struct LANGANDCODEPAGE {
|
||||
WORD wLanguage;
|
||||
WORD wCodePage;
|
||||
} * lpTranslate;
|
||||
UINT cbTranslate;
|
||||
if (!VerQueryValueW(&block[0],
|
||||
TEXT("\\VarFileInfo\\Translation"),
|
||||
reinterpret_cast<LPVOID*>(&lpTranslate),
|
||||
&cbTranslate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++) {
|
||||
wchar_t* buf = nullptr;
|
||||
UINT size = 0;
|
||||
if (!VerQueryValueW(&block[0],
|
||||
std::format(L"\\StringFileInfo\\{:04x}{:04x}\\FileDescription",
|
||||
lpTranslate[i].wLanguage,
|
||||
lpTranslate[i].wCodePage).c_str(),
|
||||
reinterpret_cast<LPVOID*>(&buf),
|
||||
&size)) {
|
||||
continue;
|
||||
}
|
||||
auto currName = std::wstring_view(buf, size);
|
||||
while (!currName.empty() && currName.back() == L'\0')
|
||||
currName = currName.substr(0, currName.size() - 1);
|
||||
if (currName.empty())
|
||||
continue;
|
||||
if (currName == L"XivAlexander Main DLL")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_openprocess_already_dealt_with() {
|
||||
static const auto s_value = [] {
|
||||
for (const auto& mod : utils::loaded_module::all_modules()) {
|
||||
try {
|
||||
if (is_xivalex(mod.path()))
|
||||
return true;
|
||||
|
||||
} catch (...) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
return s_value;
|
||||
}
|
||||
|
||||
void xivfixes::disable_game_openprocess_access_check(bool bApply) {
|
||||
static const char* LogTag = "[xivfixes:disable_game_openprocess_access_check]";
|
||||
static std::optional<hooks::import_hook<decltype(OpenProcess)>> s_hook;
|
||||
|
|
@ -238,6 +309,10 @@ void xivfixes::disable_game_openprocess_access_check(bool bApply) {
|
|||
logging::I("{} Turned off via environment variable.", LogTag);
|
||||
return;
|
||||
}
|
||||
if (is_openprocess_already_dealt_with()) {
|
||||
logging::I("{} Someone else already did it.", LogTag);
|
||||
return;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
@ -275,6 +350,10 @@ void xivfixes::redirect_openprocess(bool bApply) {
|
|||
logging::I("{} Turned off via environment variable.", LogTag);
|
||||
return;
|
||||
}
|
||||
if (is_openprocess_already_dealt_with()) {
|
||||
logging::I("{} Someone else already did it.", LogTag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bootconfig::dotnet_openprocess_hook_mode() == bootconfig::ImportHooks) {
|
||||
auto hook = std::make_shared<hooks::global_import_hook<decltype(OpenProcess)>>("kernel32.dll!OpenProcess (global import, redirect_openprocess)", L"kernel32.dll", "OpenProcess");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue