-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdllmain.cpp
More file actions
247 lines (215 loc) · 7.03 KB
/
dllmain.cpp
File metadata and controls
247 lines (215 loc) · 7.03 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#include <cstdio>
#include <fstream>
#include <iostream>
#include <memory>
#include <ostream>
#include <string>
#include <format>
#include <filesystem>
#include <unordered_map>
#include <windows.h>
#include "inipp.h"
// Forward declare DINPUT8 functions
typedef HRESULT(WINAPI* DirectInput8Create_t)(HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN);
typedef HRESULT(WINAPI* DllCanUnloadNow_t)();
typedef HRESULT(WINAPI* DllGetClassObject_t)(REFCLSID, REFIID, LPVOID*);
typedef HRESULT(WINAPI* DllRegisterServer_t)();
typedef HRESULT(WINAPI* DllUnregisterServer_t)();
typedef HRESULT(WINAPI* GetdfDIJoystick_t)();
// Global Variables
HMODULE hOriginalDLL = NULL;
DirectInput8Create_t orig_DirectInput8Create = nullptr;
DllCanUnloadNow_t orig_DllCanUnloadNow = nullptr;
DllGetClassObject_t orig_DllGetClassObject = nullptr;
DllRegisterServer_t orig_DllRegisterServer = nullptr;
DllUnregisterServer_t orig_DllUnregisterServer = nullptr;
GetdfDIJoystick_t orig_GetdfDIJoystick = nullptr;
// Configurable Settings
BOOL ShowMessageBox = true;
BOOL LoadAdditionalDLLs = true;
BOOL CloseProcessOnDLLLoadFailure = true;
BOOL PrintStatusOnLoad = true;
std::vector<std::unique_ptr<std::string>> AdditionalDLLs;
// Settings Mapping
std::unordered_map<std::string, BOOL*> settingsMap = {
{"ShowMessageBox", &ShowMessageBox},
{"LoadAdditionalDLLs", &LoadAdditionalDLLs},
{"CloseProcessOnDLLLoadFailure", &CloseProcessOnDLLLoadFailure},
{"PrintStatusOnLoad", &PrintStatusOnLoad}
};
// Load the original DINPUT8.dll
void LoadOriginalDLL()
{
if (!hOriginalDLL)
{
char systemPath[MAX_PATH];
GetSystemDirectoryA(systemPath, MAX_PATH);
strcat_s(systemPath, "\\DINPUT8.dll");
hOriginalDLL = LoadLibraryA(systemPath);
if (!hOriginalDLL)
{
MessageBoxA(0, "Failed to load original DINPUT8.dll", "Error", MB_ICONERROR);
ExitProcess(1);
}
// Load function pointers
orig_DirectInput8Create = (DirectInput8Create_t)GetProcAddress(hOriginalDLL, "DirectInput8Create");
orig_DllCanUnloadNow = (DllCanUnloadNow_t)GetProcAddress(hOriginalDLL, "DllCanUnloadNow");
orig_DllGetClassObject = (DllGetClassObject_t)GetProcAddress(hOriginalDLL, "DllGetClassObject");
orig_DllRegisterServer = (DllRegisterServer_t)GetProcAddress(hOriginalDLL, "DllRegisterServer");
orig_DllUnregisterServer = (DllUnregisterServer_t)GetProcAddress(hOriginalDLL, "DllUnregisterServer");
orig_GetdfDIJoystick = (GetdfDIJoystick_t)GetProcAddress(hOriginalDLL, "GetdfDIJoystick");
}
}
// Load configuration settings from INI file
void LoadINI()
{
std::filesystem::path path = std::filesystem::current_path() / "dinput8proxy.ini";
std::ifstream iniFile(path.string());
if(iniFile.fail())
{
// Create a default INI file
std::ofstream file(path.string());
file << "[Settings]\n";
for (const auto& setting : settingsMap)
{
file << setting.first << " = " << *setting.second << "\n";
}
file.close();
iniFile.open(path.string());
}
inipp::Ini<char> ini;
ini.parse(iniFile);
ini.interpolate();
for (const auto& setting : settingsMap)
{
std::string value;
if (inipp::get_value(ini.sections["Settings"], setting.first, value))
{
*setting.second = std::stoi(value) != 0;
}
}
iniFile.close();
}
// Handle Additional DLLs
void CreateDefaultAdditionalDLLsFile()
{
std::ofstream file("AdditionalDLLs.txt");
file << "; Add additional DLLs to load here, one per line\n";
file << "; Example:\n";
file << "; YourAwesomeMod.dll\n";
file.close();
}
void DoLoadAdditionalDLLsFile()
{
if (!LoadAdditionalDLLs) return;
std::ifstream file("AdditionalDLLs.txt");
if (!file)
{
MessageBoxA(0, "Failed to open AdditionalDLLs.txt", "Error", MB_ICONERROR);
CreateDefaultAdditionalDLLsFile();
return;
}
std::istringstream stream(std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()));
file.close();
for (std::string line; std::getline(stream, line);)
{
if (!line.empty() && line[0] != ';')
{
AdditionalDLLs.push_back(std::make_unique<std::string>(line));
}
}
}
void DoLoadAdditionalDLLs()
{
if (!LoadAdditionalDLLs) return;
DoLoadAdditionalDLLsFile();
for (const auto& dll : AdditionalDLLs)
{
HMODULE hModule = LoadLibraryA(dll->c_str());
if (!hModule)
{
std::cout << "Failed to load additional DLL: " << *dll << std::endl;
if (CloseProcessOnDLLLoadFailure)
{
Sleep(5000);
ExitProcess(1);
}
}
else
{
std::cout << "Loaded additional DLL: " << *dll << std::endl;
}
}
}
// Console Output
void AllocateConsole()
{
AllocConsole();
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
SetConsoleTitleA("DINPUT8 Proxy Console");
}
void PrintStatus()
{
std::cout << "DINPUT8 Proxy Console\n";
for (const auto& setting : settingsMap)
{
std::cout << setting.first << ": " << *setting.second << std::endl;
}
std::cout << "Additional DLLs: " << AdditionalDLLs.size() << std::endl;
for (const auto& dll : AdditionalDLLs)
{
std::cout << *dll << std::endl;
}
std::cout << std::endl;
}
// Initialization Function
void DoStuff()
{
LoadOriginalDLL();
AllocateConsole();
LoadINI();
if (ShowMessageBox) MessageBoxA(0, "DINPUT8 Proxy Loaded", "Success", MB_ICONINFORMATION);
PrintStatus();
DoLoadAdditionalDLLs();
}
// DllMain Entry Point
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
DoStuff();
}
return TRUE;
}
// Export functions
extern "C" HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter)
{
return orig_DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter);
}
extern "C" HRESULT WINAPI DllCanUnloadNow()
{
return orig_DllCanUnloadNow();
}
extern "C" HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return orig_DllGetClassObject(rclsid, riid, ppv);
}
extern "C" HRESULT WINAPI DllRegisterServer()
{
return orig_DllRegisterServer();
}
extern "C" HRESULT WINAPI DllUnregisterServer()
{
return orig_DllUnregisterServer();
}
extern "C" HRESULT WINAPI GetdfDIJoystick()
{
return orig_GetdfDIJoystick();
}
// Export function directives
#pragma comment(linker, "/export:DirectInput8Create=DirectInput8Create,@1")
#pragma comment(linker, "/export:DllCanUnloadNow=DllCanUnloadNow,PRIVATE")
#pragma comment(linker, "/export:DllGetClassObject=DllGetClassObject,PRIVATE")
#pragma comment(linker, "/export:DllRegisterServer=DllRegisterServer,PRIVATE")
#pragma comment(linker, "/export:DllUnregisterServer=DllUnregisterServer,PRIVATE")
#pragma comment(linker, "/export:GetdfDIJoystick=GetdfDIJoystick,@6")