3
3
#include " Context.h"
4
4
#include " Utilities.h"
5
5
6
+ // Stores the current directory, and reverts it back to the original when it exits the current scope.
7
+ struct CurrentDirectoryGuard
8
+ {
9
+ WCHAR currentDirectory[0x400 ];
10
+ WCHAR dllDirectory[0x400 ];
11
+
12
+ CurrentDirectoryGuard ()
13
+ {
14
+ GetCurrentDirectoryW (_countof (currentDirectory), currentDirectory);
15
+ GetDllDirectoryW (_countof (dllDirectory), dllDirectory);
16
+ }
17
+
18
+ ~CurrentDirectoryGuard ()
19
+ {
20
+ SetCurrentDirectoryW (currentDirectory);
21
+ SetDllDirectoryW (dllDirectory);
22
+ }
23
+ };
24
+
6
25
constexpr const char * PRE_INIT_FUNC_NAMES[] = { " PreInit" , " preInit" , " pre_init" }; // Called in _scrt_common_main_seh
7
26
constexpr const char * INIT_FUNC_NAMES[] = { " Init" , " init" }; // Called in WinMain
8
27
constexpr const char * POST_INIT_FUNC_NAMES[] = { " PostInit" , " postInit" , " post_init" }; // Called in WinMain after every Init
9
28
constexpr const char * ON_FRAME_FUNC_NAMES[] = { " OnFrame" , " onFrame" , " on_frame" }; // Called every frame before present
10
29
11
30
std::vector<std::wstring> CodeLoader::dllFilePaths;
12
31
13
- std::vector<CodeEvent* > CodeLoader::initEvents;
14
- std::vector<CodeEvent* > CodeLoader::postInitEvents;
32
+ std::vector<CodeEventPair > CodeLoader::initEvents;
33
+ std::vector<CodeEventPair > CodeLoader::postInitEvents;
15
34
std::vector<CodeEvent*> CodeLoader::onFrameEvents;
16
35
17
36
VTABLE_HOOK (HRESULT, WINAPI, IDXGISwapChain, Present, UINT SyncInterval, UINT Flags)
@@ -56,6 +75,14 @@ HOOK(HRESULT, WINAPI, D3D11CreateDeviceAndSwapChain, PROC_ADDRESS("d3d11.dll", "
56
75
return result;
57
76
}
58
77
78
+ void CodeEventPair::run () const
79
+ {
80
+ SetCurrentDirectoryW (directoryPath.c_str ());
81
+ SetDllDirectoryW (directoryPath.c_str ());
82
+
83
+ event ();
84
+ }
85
+
59
86
// Gets called during _scrt_common_main_seh.
60
87
// Loads DLL mods and calls their "PreInit" functions.
61
88
void CodeLoader::init ()
@@ -65,14 +92,10 @@ void CodeLoader::init()
65
92
if (dllFilePaths.empty ())
66
93
return ;
67
94
68
- WCHAR currentDirectory[0x400 ];
69
- WCHAR dllDirectory[0x400 ];
70
-
71
- GetCurrentDirectoryW (_countof (currentDirectory), currentDirectory);
72
- GetDllDirectoryW (_countof (dllDirectory), dllDirectory);
73
-
74
95
LOG (" DLL:" )
75
96
97
+ CurrentDirectoryGuard guard;
98
+
76
99
for (auto & dllFilePath : dllFilePaths)
77
100
{
78
101
const std::wstring directoryPath = std::filesystem::path (dllFilePath).parent_path ().wstring ();
@@ -112,15 +135,15 @@ void CodeLoader::init()
112
135
const FARPROC initEvent = GetProcAddress (module, initFuncName);
113
136
114
137
if (initEvent)
115
- initEvents.push_back ((CodeEvent*)initEvent);
138
+ initEvents.push_back ({ directoryPath, (CodeEvent*)initEvent } );
116
139
}
117
140
118
141
for (auto & postInitFuncName : POST_INIT_FUNC_NAMES)
119
142
{
120
143
const FARPROC postInitEvent = GetProcAddress (module, postInitFuncName);
121
144
122
145
if (postInitEvent)
123
- postInitEvents.push_back ((CodeEvent*)postInitEvent);
146
+ postInitEvents.push_back ({ directoryPath, (CodeEvent*)postInitEvent } );
124
147
}
125
148
126
149
for (auto & onFrameFuncName : ON_FRAME_FUNC_NAMES)
@@ -132,9 +155,6 @@ void CodeLoader::init()
132
155
}
133
156
}
134
157
135
- SetCurrentDirectoryW (currentDirectory);
136
- SetDllDirectoryW (dllDirectory);
137
-
138
158
if (!onFrameEvents.empty ())
139
159
INSTALL_HOOK (D3D11CreateDeviceAndSwapChain);
140
160
}
@@ -143,9 +163,11 @@ void CodeLoader::init()
143
163
// Calls "Init" and "PostInit" functions of DLL mods.
144
164
void CodeLoader::postInit ()
145
165
{
166
+ CurrentDirectoryGuard guard;
167
+
146
168
for (auto & initEvent : initEvents)
147
- initEvent ();
169
+ initEvent. run ();
148
170
149
171
for (auto & postInitEvent : postInitEvents)
150
- postInitEvent ();
172
+ postInitEvent. run ();
151
173
}
0 commit comments