-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathXInputModuleManager.h
More file actions
149 lines (124 loc) · 4.95 KB
/
Copy pathXInputModuleManager.h
File metadata and controls
149 lines (124 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
#include <string>
#include <windows.h>
#include "stdafx.h"
#include "xinput.h"
#include <string>
#include <memory>
#include <Shlwapi.h>
#include <Shlobj.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "shell32.lib")
class XInputModuleManager
{
public:
// XInput 1.3 and older functions
DWORD(WINAPI* XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState);
DWORD(WINAPI* XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
DWORD(WINAPI* XInputGetCapabilities)(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities);
VOID(WINAPI* XInputEnable)(BOOL enable);
DWORD(WINAPI* XInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid);
DWORD(WINAPI* XInputGetBatteryInformation)(DWORD dwUserIndex, BYTE devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation);
DWORD(WINAPI* XInputGetKeystroke)(DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke);
// XInput 1.3 undocumented functions
DWORD(WINAPI* XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE *pState); // 100
DWORD(WINAPI* XInputWaitForGuideButton)(DWORD dwUserIndex, DWORD dwFlag, LPVOID pVoid); // 101
DWORD(WINAPI* XInputCancelGuideButtonWait)(DWORD dwUserIndex); // 102
DWORD(WINAPI* XInputPowerOffController)(DWORD dwUserIndex); // 103
// XInput 1.4 functions
DWORD(WINAPI* XInputGetAudioDeviceIds)(DWORD dwUserIndex, LPWSTR pRenderDeviceId, UINT* pRenderCount, LPWSTR pCaptureDeviceId, UINT* pCaptureCount);
// XInput 1.4 undocumented functionss
DWORD(WINAPI* XInputGetBaseBusInformation)(DWORD dwUserIndex, struct XINPUT_BUSINFO* pBusinfo); // 104
DWORD(WINAPI* XInputGetCapabilitiesEx)(DWORD unk1, DWORD dwUserIndex, DWORD dwFlags, struct XINPUT_CAPABILITIESEX* pCapabilitiesEx); // 108
XInputModuleManager()
{
std::string current_module;
ModuleFileName(¤t_module, CurrentModule());
std::string loaded_module_path;
m_module = LoadLibrarySystem(current_module, &loaded_module_path);
if (!m_module)
{
HRESULT hr = GetLastError();
std::unique_ptr<char[]> error_msg(new char[MAX_PATH]);
sprintf_s(error_msg.get(), MAX_PATH, "Cannot load \"%s\" error: 0x%x", loaded_module_path.c_str(), hr);
MessageBoxA(NULL, error_msg.get(), "Error", MB_ICONERROR);
exit(hr);
}
// XInput 1.3 and older functions
StoreProcAddress("XInputGetState", &XInputGetState);
StoreProcAddress("XInputSetState", &XInputSetState);
StoreProcAddress("XInputGetCapabilities", &XInputGetCapabilities);
StoreProcAddress("XInputEnable", &XInputEnable);
StoreProcAddress("XInputGetDSoundAudioDeviceGuids", &XInputGetDSoundAudioDeviceGuids);
StoreProcAddress("XInputGetBatteryInformation", &XInputGetBatteryInformation);
StoreProcAddress("XInputGetKeystroke", &XInputGetKeystroke);
// XInput 1.3 undocumented functions
StoreProcAddress((const char*)100, &XInputGetStateEx);
StoreProcAddress((const char*)101, &XInputWaitForGuideButton);
StoreProcAddress((const char*)102, &XInputCancelGuideButtonWait);
StoreProcAddress((const char*)103, &XInputPowerOffController);
// XInput 1.4 functions
StoreProcAddress("XInputGetAudioDeviceIds", &XInputGetAudioDeviceIds);
// XInput 1.4 undocumented functionss
StoreProcAddress((const char*)104, &XInputGetBaseBusInformation);
StoreProcAddress((const char*)108, &XInputGetCapabilitiesEx);
}
~XInputModuleManager()
{
if (m_module)
{
std::string xinput_path;
ModulePath(&xinput_path, m_module);
FreeLibrary(m_module);
}
}
static XInputModuleManager& Get()
{
static XInputModuleManager instance;
return instance;
}
bool ModuleFileName(std::string* out, HMODULE hModule)
{
std::unique_ptr<char[]> buffer(new char[MAX_PATH]);
GetModuleFileNameA(hModule, buffer.get(), MAX_PATH);
*out = PathFindFileNameA(buffer.get());
return !out->empty();
}
bool ModulePath(std::string* out, HMODULE hModule)
{
std::unique_ptr<char[]> buffer(new char[MAX_PATH]);
GetModuleFileNameA(hModule, buffer.get(), MAX_PATH);
*out = buffer.get();
return !out->empty();
}
inline HMODULE& CurrentModule()
{
static HMODULE hModule = 0;
if (!hModule)
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&hModule, &hModule);
return hModule;
}
HMODULE LoadLibrarySystem(const std::string& library_name, std::string* out_path)
{
std::unique_ptr<char[]> system_directory(new char[MAX_PATH]);
GetSystemDirectoryA(system_directory.get(), MAX_PATH);
std::string lib_path(system_directory.get());
StringPathAppend(&lib_path, library_name);
if (out_path)
*out_path = lib_path;
return LoadLibraryA(lib_path.c_str());
}
bool StringPathAppend(std::string* path, const std::string& more)
{
std::unique_ptr<char[]> buffer(new char[MAX_PATH]);
*path = PathCombineA(buffer.get(), path->c_str(), more.c_str());
return !path->empty();
}
private:
template<typename T>
inline void StoreProcAddress(const char* funcname, T* ppfunc)
{
*ppfunc = reinterpret_cast<T>(::GetProcAddress(m_module, funcname));
}
HMODULE m_module;
};