From bb73463400725a8b35d69825109a4add335570e1 Mon Sep 17 00:00:00 2001 From: apple1417 Date: Wed, 24 Jun 2026 22:01:40 +0300 Subject: [PATCH] add dinput8 pluginloader --- CMakeLists.txt | 4 +- src/proxy/dinput8.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/proxy/dinput8.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 742bea5..e74f755 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.24) -project(pluginloader VERSION 1.0.6) +project(pluginloader VERSION 1.0.7) add_library(_pluginloader_base INTERFACE) set(CMAKE_EXPORT_COMPILE_COMMANDS True) @@ -58,6 +58,7 @@ endfunction() pluginloader_add_impl(no_proxy "src/proxy/none.cpp") pluginloader_add_impl(d3d11 "src/proxy/d3d11.cpp") +pluginloader_add_impl(dinput8 "src/proxy/dinput8.cpp") pluginloader_add_impl(dsound "src/proxy/dsound.cpp" "src/proxy/dsound.def") pluginloader_add_impl(winmm "src/proxy/winmm.cpp") pluginloader_add_impl(xinput1_3 "src/proxy/xinput1_3.cpp" "src/proxy/xinput1_3.def") @@ -66,6 +67,7 @@ install( TARGETS pluginloader_no_proxy pluginloader_d3d11 + pluginloader_dinput8 pluginloader_dsound pluginloader_winmm pluginloader_xinput1_3 diff --git a/src/proxy/dinput8.cpp b/src/proxy/dinput8.cpp new file mode 100644 index 0000000..5a03980 --- /dev/null +++ b/src/proxy/dinput8.cpp @@ -0,0 +1,105 @@ +#include "pch.h" + +#include "proxy.h" +#include "util.h" + +namespace pluginloader::proxy { + +namespace { + +HMODULE dinput8_dll_handle = nullptr; + +FARPROC direct_input8_create_ptr = nullptr; +FARPROC dll_can_unload_now_ptr = nullptr; +FARPROC dll_get_class_object_ptr = nullptr; +FARPROC dll_register_server_ptr = nullptr; +FARPROC dll_unregister_server_ptr = nullptr; +FARPROC get_df_di_joystick_ptr = nullptr; + +} // namespace + +// NOLINTBEGIN(readability-identifier-naming) + +#ifdef __MINGW32__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-function-type-mismatch" +#endif + +// #include "dsound.h" + +DLL_EXPORT HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, + DWORD dwVersion, + REFIID riidltf, + LPVOID* ppvOut, + void* punkOuter) { + return reinterpret_cast(direct_input8_create_ptr)( + hinst, dwVersion, riidltf, ppvOut, punkOuter); +} + +DLL_EXPORT HRESULT WINAPI DllCanUnloadNow(void) { + return reinterpret_cast(dll_can_unload_now_ptr)(); +} + +DLL_EXPORT HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { + return reinterpret_cast(dll_get_class_object_ptr)(rclsid, riid, + ppv); +} + +DLL_EXPORT HRESULT STDAPICALLTYPE DllRegisterServer(void) { + return reinterpret_cast(dll_register_server_ptr)(); +} + +DLL_EXPORT HRESULT STDAPICALLTYPE DllUnregisterServer(void) { + return reinterpret_cast(dll_unregister_server_ptr)(); +} + +DLL_EXPORT void* WINAPI GetdfDIJoystick(void) { + return reinterpret_cast(get_df_di_joystick_ptr)(); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#ifdef __MINGW32__ +#pragma GCC diagnostic pop +#endif + +// NOLINTEND(readability-identifier-naming) + +void init(HMODULE /*this_dll*/) { + // Suspend all other threads to prevent a giant race condition + const util::ThreadSuspender suspender{}; + + wchar_t buf[MAX_PATH]; + if (GetSystemDirectoryW(&buf[0], ARRAYSIZE(buf)) == 0) { + std::cerr << "Unable to find system dll directory! We're probably about to crash.\n"; + return; + } + + auto system_dinput8 = std::filesystem::path{static_cast(buf)} / "dinput8.dll"; + dinput8_dll_handle = LoadLibraryA(system_dinput8.generic_string().c_str()); + if (dinput8_dll_handle == nullptr) { + std::cerr << "Unable to find system dinput8.dll! We're probably about to crash.\n"; + return; + } + + direct_input8_create_ptr = GetProcAddress(dinput8_dll_handle, "DirectInput8Create"); + dll_can_unload_now_ptr = GetProcAddress(dinput8_dll_handle, "DllCanUnloadNow"); + dll_get_class_object_ptr = GetProcAddress(dinput8_dll_handle, "DllGetClassObject"); + dll_register_server_ptr = GetProcAddress(dinput8_dll_handle, "DllRegisterServer"); + dll_unregister_server_ptr = GetProcAddress(dinput8_dll_handle, "DllUnregisterServer"); + get_df_di_joystick_ptr = GetProcAddress(dinput8_dll_handle, "GetdfDIJoystick"); +} + +void free(void) { + if (dinput8_dll_handle != nullptr) { + FreeLibrary(dinput8_dll_handle); + dinput8_dll_handle = nullptr; + } +} + +} // namespace pluginloader::proxy