Skip to content

Commit fb090e6

Browse files
Fix current directory not setting properly when initializing DLLs.
1 parent a55a647 commit fb090e6

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

Source/DivaModLoader/CodeLoader.cpp

+37-15
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,34 @@
33
#include "Context.h"
44
#include "Utilities.h"
55

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+
625
constexpr const char* PRE_INIT_FUNC_NAMES[] = { "PreInit", "preInit", "pre_init" }; // Called in _scrt_common_main_seh
726
constexpr const char* INIT_FUNC_NAMES[] = { "Init", "init" }; // Called in WinMain
827
constexpr const char* POST_INIT_FUNC_NAMES[] = { "PostInit", "postInit", "post_init" }; // Called in WinMain after every Init
928
constexpr const char* ON_FRAME_FUNC_NAMES[] = { "OnFrame", "onFrame", "on_frame" }; // Called every frame before present
1029

1130
std::vector<std::wstring> CodeLoader::dllFilePaths;
1231

13-
std::vector<CodeEvent*> CodeLoader::initEvents;
14-
std::vector<CodeEvent*> CodeLoader::postInitEvents;
32+
std::vector<CodeEventPair> CodeLoader::initEvents;
33+
std::vector<CodeEventPair> CodeLoader::postInitEvents;
1534
std::vector<CodeEvent*> CodeLoader::onFrameEvents;
1635

1736
VTABLE_HOOK(HRESULT, WINAPI, IDXGISwapChain, Present, UINT SyncInterval, UINT Flags)
@@ -56,6 +75,14 @@ HOOK(HRESULT, WINAPI, D3D11CreateDeviceAndSwapChain, PROC_ADDRESS("d3d11.dll", "
5675
return result;
5776
}
5877

78+
void CodeEventPair::run() const
79+
{
80+
SetCurrentDirectoryW(directoryPath.c_str());
81+
SetDllDirectoryW(directoryPath.c_str());
82+
83+
event();
84+
}
85+
5986
// Gets called during _scrt_common_main_seh.
6087
// Loads DLL mods and calls their "PreInit" functions.
6188
void CodeLoader::init()
@@ -65,14 +92,10 @@ void CodeLoader::init()
6592
if (dllFilePaths.empty())
6693
return;
6794

68-
WCHAR currentDirectory[0x400];
69-
WCHAR dllDirectory[0x400];
70-
71-
GetCurrentDirectoryW(_countof(currentDirectory), currentDirectory);
72-
GetDllDirectoryW(_countof(dllDirectory), dllDirectory);
73-
7495
LOG("DLL:")
7596

97+
CurrentDirectoryGuard guard;
98+
7699
for (auto& dllFilePath : dllFilePaths)
77100
{
78101
const std::wstring directoryPath = std::filesystem::path(dllFilePath).parent_path().wstring();
@@ -112,15 +135,15 @@ void CodeLoader::init()
112135
const FARPROC initEvent = GetProcAddress(module, initFuncName);
113136

114137
if (initEvent)
115-
initEvents.push_back((CodeEvent*)initEvent);
138+
initEvents.push_back({ directoryPath, (CodeEvent*)initEvent });
116139
}
117140

118141
for (auto& postInitFuncName : POST_INIT_FUNC_NAMES)
119142
{
120143
const FARPROC postInitEvent = GetProcAddress(module, postInitFuncName);
121144

122145
if (postInitEvent)
123-
postInitEvents.push_back((CodeEvent*)postInitEvent);
146+
postInitEvents.push_back({ directoryPath, (CodeEvent*)postInitEvent });
124147
}
125148

126149
for (auto& onFrameFuncName : ON_FRAME_FUNC_NAMES)
@@ -132,9 +155,6 @@ void CodeLoader::init()
132155
}
133156
}
134157

135-
SetCurrentDirectoryW(currentDirectory);
136-
SetDllDirectoryW(dllDirectory);
137-
138158
if (!onFrameEvents.empty())
139159
INSTALL_HOOK(D3D11CreateDeviceAndSwapChain);
140160
}
@@ -143,9 +163,11 @@ void CodeLoader::init()
143163
// Calls "Init" and "PostInit" functions of DLL mods.
144164
void CodeLoader::postInit()
145165
{
166+
CurrentDirectoryGuard guard;
167+
146168
for (auto& initEvent : initEvents)
147-
initEvent();
169+
initEvent.run();
148170

149171
for (auto& postInitEvent : postInitEvents)
150-
postInitEvent();
172+
postInitEvent.run();
151173
}

Source/DivaModLoader/CodeLoader.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22

33
typedef void CodeEvent();
44

5+
struct CodeEventPair
6+
{
7+
std::wstring directoryPath;
8+
CodeEvent* event;
9+
10+
void run() const;
11+
};
12+
513
class CodeLoader
614
{
715
public:
816
static std::vector<std::wstring> dllFilePaths;
917

10-
static std::vector<CodeEvent*> initEvents;
11-
static std::vector<CodeEvent*> postInitEvents;
18+
static std::vector<CodeEventPair> initEvents;
19+
static std::vector<CodeEventPair> postInitEvents;
1220
static std::vector<CodeEvent*> onFrameEvents;
1321

1422
static void init();

0 commit comments

Comments
 (0)