Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add xinput1_3.dll proxy #1

Merged
merged 3 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.24)

project(pluginloader VERSION 1.0.0)
project(pluginloader VERSION 1.0.1)

add_library(_pluginloader_base INTERFACE)
set(CMAKE_EXPORT_COMPILE_COMMANDS True)
Expand All @@ -9,7 +9,6 @@ target_compile_features(_pluginloader_base INTERFACE cxx_std_20)
set_target_properties(_pluginloader_base PROPERTIES
COMPILE_WARNING_AS_ERROR True
INTERPROCEDURAL_OPTIMIZATION True
PREFIX ""
)
if(MSVC)
target_compile_options(_pluginloader_base INTERFACE /W4)
Expand Down Expand Up @@ -41,7 +40,11 @@ target_precompile_headers(_pluginloader_base INTERFACE "src/pch.h")

function(pluginloader_add_impl name)
add_library(pluginloader_${name} SHARED ${ARGN})
set_target_properties(pluginloader_${name} PROPERTIES OUTPUT_NAME ${name})
set_target_properties(pluginloader_${name} PROPERTIES
PREFIX ""
OUTPUT_NAME ${name}
SUFFIX ".dll"
)
target_link_libraries(pluginloader_${name} PUBLIC _pluginloader_base)
endfunction()

Expand All @@ -50,10 +53,12 @@ endfunction()

pluginloader_add_impl(no_proxy "src/proxy/none.cpp")
pluginloader_add_impl(d3d11 "src/proxy/d3d11.cpp")
pluginloader_add_impl(xinput1_3 "src/proxy/xinput1_3.cpp" "src/proxy/xinput1_3.def")

install(
TARGETS
pluginloader_no_proxy
pluginloader_d3d11
pluginloader_xinput1_3
RUNTIME DESTINATION .
)
2 changes: 1 addition & 1 deletion common_cmake
2 changes: 1 addition & 1 deletion src/proxy/d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void init(HMODULE /*this_dll*/) {

wchar_t buf[MAX_PATH];
if (GetSystemDirectoryW(&buf[0], ARRAYSIZE(buf)) == 0) {
std::cerr << "[dhf] Unable to find system dll directory! We're probably about to crash.\n";
std::cerr << "Unable to find system dll directory! We're probably about to crash.\n";
return;
}

Expand Down
106 changes: 106 additions & 0 deletions src/proxy/xinput1_3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "pch.h"
#include <libloaderapi.h>

#include "util.h"

namespace pluginloader::proxy {

namespace {

HMODULE xinput_dll_handle = nullptr;

FARPROC xinput_enable_ptr = nullptr;
FARPROC xinput_get_battery_information_ptr = nullptr;
FARPROC xinput_get_capabilities_ptr = nullptr;
FARPROC xinput_get_dsound_audio_device_guids_ptr = nullptr;
FARPROC xinput_get_keystroke_ptr = nullptr;
FARPROC xinput_get_state_ptr = nullptr;
FARPROC xinput_set_state_ptr = nullptr;

const constexpr auto XINPUT_GET_STATE_EX_ORDINAL = 100;
FARPROC xinput_get_state_ex_ptr = nullptr;

// NOLINTBEGIN(readability-identifier-naming, readability-identifier-length)

DLL_EXPORT void XInputEnable(BOOL enable) {
return reinterpret_cast<decltype(&XInputEnable)>(xinput_enable_ptr)(enable);
}

DLL_EXPORT DWORD XInputGetBatteryInformation(DWORD dwUserIndex,
BYTE devType,
void* pBatteryInformation) {
return reinterpret_cast<decltype(&XInputGetBatteryInformation)>(
xinput_get_battery_information_ptr)(dwUserIndex, devType, pBatteryInformation);
}

DLL_EXPORT DWORD XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, void* pCapabilities) {
return reinterpret_cast<decltype(&XInputGetCapabilities)>(xinput_get_capabilities_ptr)(
dwUserIndex, dwFlags, pCapabilities);
}

DLL_EXPORT DWORD XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex,
GUID* pDSoundRenderGuid,
GUID* pDSoundCaptureGuid) {
return reinterpret_cast<decltype(&XInputGetDSoundAudioDeviceGuids)>(
xinput_get_dsound_audio_device_guids_ptr)(dwUserIndex, pDSoundRenderGuid,
pDSoundCaptureGuid);
}

DLL_EXPORT DWORD XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserved, void* pKeystroke) {
return reinterpret_cast<decltype(&XInputGetKeystroke)>(xinput_get_keystroke_ptr)(
dwUserIndex, dwReserved, pKeystroke);
}

DLL_EXPORT DWORD XInputGetState(DWORD dwUserIndex, void* pState) {
return reinterpret_cast<decltype(&XInputGetState)>(xinput_get_state_ptr)(dwUserIndex, pState);
}

DLL_EXPORT DWORD XInputSetState(DWORD dwUserIndex, void* pVibration) {
return reinterpret_cast<decltype(&XInputSetState)>(xinput_set_state_ptr)(dwUserIndex,
pVibration);
}

DLL_EXPORT DWORD XInputGetStateEx(DWORD dwUserIndex, void* pState) {
return reinterpret_cast<decltype(&XInputGetStateEx)>(xinput_get_state_ex_ptr)(dwUserIndex,
pState);
}

// NOLINTEND(readability-identifier-naming, readability-identifier-length)

} // namespace

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_xinput = std::filesystem::path{static_cast<wchar_t*>(buf)} / "xinput1_3.dll";
xinput_dll_handle = LoadLibraryA(system_xinput.generic_string().c_str());

xinput_enable_ptr = GetProcAddress(xinput_dll_handle, "XInputEnable");
xinput_get_battery_information_ptr =
GetProcAddress(xinput_dll_handle, "XInputGetBatteryInformation");
xinput_get_capabilities_ptr = GetProcAddress(xinput_dll_handle, "XInputGetCapabilities");
xinput_get_dsound_audio_device_guids_ptr =
GetProcAddress(xinput_dll_handle, "XInputGetDSoundAudioDeviceGuids");
xinput_get_keystroke_ptr = GetProcAddress(xinput_dll_handle, "XInputGetKeystroke");
xinput_get_state_ptr = GetProcAddress(xinput_dll_handle, "XInputGetState");
xinput_set_state_ptr = GetProcAddress(xinput_dll_handle, "XInputSetState");

xinput_get_state_ex_ptr =
GetProcAddress(xinput_dll_handle, reinterpret_cast<LPCSTR>(XINPUT_GET_STATE_EX_ORDINAL));
}

void free(void) {
if (xinput_dll_handle != nullptr) {
FreeLibrary(xinput_dll_handle);
xinput_dll_handle = nullptr;
}
}

} // namespace pluginloader::proxy
11 changes: 11 additions & 0 deletions src/proxy/xinput1_3.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
LIBRARY XINPUT1_3
EXPORTS
DllMain @1
XInputGetState @2
XInputSetState @3
XInputGetCapabilities @4
XInputEnable @5
XInputGetDSoundAudioDeviceGuids @6
XInputGetBatteryInformation @7
XInputGetKeystroke @8
XInputGetStateEx @100
Loading