proxy loader now properly defines ordinal

This commit is contained in:
matcool 2024-06-02 16:38:50 -03:00
parent 9194e8c718
commit 959ae77036
4 changed files with 64 additions and 28 deletions

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.21)
add_library(ProxyLoader SHARED proxyLoader.cpp)
add_library(ProxyLoader SHARED proxyLoader.c proxyLoader.def)
set_target_properties(ProxyLoader PROPERTIES
PREFIX ""
OUTPUT_NAME "XInput1_4"

View file

@ -0,0 +1,59 @@
// Based off https://gist.github.com/absoIute/ce6b463cb1985723dab108a52f5e8815
// with permission
#include <Windows.h>
#include <Xinput.h>
#include <stdio.h>
HINSTANCE s_instance = NULL;
// GD only uses these two functions, and this one in particular is imported by ordinal 2,
// so we make sure to set that up in the .def file
typedef DWORD(WINAPI* f_XInputGetState)(DWORD, XINPUT_STATE*);
f_XInputGetState s_XInputGetState = NULL;
typedef DWORD(WINAPI* f_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
f_XInputGetCapabilities s_XInputGetCapabilities = NULL;
void load() {
WCHAR path[MAX_PATH];
GetSystemDirectoryW(path, MAX_PATH);
wcscat_s(path, MAX_PATH, L"\\XInput1_4.dll");
s_instance = LoadLibraryW(path);
if (!s_instance)
return;
s_XInputGetState = (f_XInputGetState)(GetProcAddress(s_instance, "XInputGetState"));
s_XInputGetCapabilities = (f_XInputGetCapabilities)(GetProcAddress(s_instance, "XInputGetCapabilities"));
}
DWORD WINAPI XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) {
if (!s_XInputGetState)
load();
return s_XInputGetState(dwUserIndex, pState);
}
DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities) {
if (!s_XInputGetCapabilities)
load();
return s_XInputGetCapabilities(dwUserIndex, dwFlags, pCapabilities);
}
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID _) {
if (reason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(module);
// This is UB, but works fine in practice on both Windows and wine
if (LoadLibraryW(L"Geode.dll") == NULL) {
char buffer[256];
sprintf_s(buffer, 256, "Failed to load Geode.dll. Error code: %d", GetLastError());
MessageBoxA(NULL, buffer, "Load failed" , MB_OK | MB_ICONWARNING);
}
}
return TRUE;
}

View file

@ -1,27 +0,0 @@
#include <Windows.h>
#include <string>
// https://github.com/mrexodia/perfect-dll-proxy
#define PROXY(export, ordinal) \
"/export:" #export "=\\\\.\\GLOBALROOT\\SystemRoot\\System32\\XInput1_4.dll.#" #ordinal
// These are the only two functions required by libcocos2d.dll.
#pragma comment(linker, PROXY(XInputGetState, 2))
#pragma comment(linker, PROXY(XInputGetCapabilities, 4))
static std::wstring getErrorString() {
return L"Could not load Geode. Error code: " + std::to_wstring(GetLastError());
}
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID _) {
if (reason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(module);
// This is UB.
if (LoadLibraryW(L"Geode.dll") == NULL)
MessageBoxW(NULL, getErrorString().c_str(), L"Load failed" , MB_OK | MB_ICONWARNING);
}
return TRUE;
}

View file

@ -0,0 +1,4 @@
LIBRARY XINPUT1_4
EXPORTS
XInputGetState @2
XInputGetCapabilities @4