Skip to content

Commit 1300a16

Browse files
committed
Improve loading of winmm in mtasa.dll
1 parent 9e98040 commit 1300a16

File tree

1 file changed

+94
-28
lines changed

1 file changed

+94
-28
lines changed

Client/loader-proxy/main.cpp

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,18 @@
1717
#include <windows.h>
1818
#include <shlobj.h>
1919

20-
__forceinline void SetupLibraryExports(HMODULE Handle) noexcept;
20+
namespace fs = std::filesystem;
2121

22-
void DisplayErrorMessageBox(const std::wstring& message, const std::wstring& errorCode)
23-
{
24-
std::wstring caption = L"MTA: San Andreas [" + errorCode + L"] (CTRL+C to copy)";
25-
MessageBoxW(nullptr, message.c_str(), caption.c_str(), MB_OK | MB_TOPMOST | MB_ICONWARNING);
26-
TerminateProcess(GetCurrentProcess(), 1);
27-
}
22+
void SetupLibraryExports(HMODULE Handle) noexcept;
23+
void DisplayErrorMessageBox(const std::wstring& message, const std::wstring& errorCode);
24+
auto GetProcessPath() -> fs::path;
25+
auto LoadWinmmLibrary() -> std::pair<HMODULE, DWORD>;
2826

29-
auto GetProcessPath() -> std::filesystem::path
30-
{
31-
std::wstring filePath(4096, L'\0');
32-
33-
while (true)
34-
{
35-
DWORD length = GetModuleFileNameW(nullptr, filePath.data(), static_cast<DWORD>(filePath.size() + 1));
36-
37-
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
38-
{
39-
filePath.resize(filePath.capacity() * 2);
40-
continue;
41-
}
42-
43-
filePath.resize(length);
44-
return {filePath};
45-
}
46-
}
27+
static HMODULE core{};
28+
static DWORD winmmSource = 0;
4729

4830
static auto winmm = ([]() -> HMODULE {
49-
HMODULE winmm = LoadLibraryExW(L"winmm.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
31+
auto [winmm, source] = LoadWinmmLibrary();
5032

5133
if (!winmm)
5234
{
@@ -61,11 +43,10 @@ static auto winmm = ([]() -> HMODULE {
6143
}
6244

6345
SetupLibraryExports(winmm);
46+
winmmSource = source;
6447
return winmm;
6548
})();
6649

67-
static HMODULE core{};
68-
6950
BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
7051
{
7152
if (reason == DLL_PROCESS_ATTACH)
@@ -134,3 +115,88 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
134115

135116
return TRUE;
136117
}
118+
119+
extern "C" __declspec(dllexport) HMODULE mtasaGetLibraryHandle()
120+
{
121+
return winmm;
122+
}
123+
124+
extern "C" __declspec(dllexport) DWORD mtasaGetLibrarySource()
125+
{
126+
return winmmSource;
127+
}
128+
129+
void DisplayErrorMessageBox(const std::wstring& message, const std::wstring& errorCode)
130+
{
131+
std::wstring caption = L"MTA: San Andreas [" + errorCode + L"] (CTRL+C to copy)";
132+
MessageBoxW(nullptr, message.c_str(), caption.c_str(), MB_OK | MB_TOPMOST | MB_ICONWARNING);
133+
TerminateProcess(GetCurrentProcess(), 1);
134+
}
135+
136+
auto GetProcessPath() -> fs::path
137+
{
138+
std::wstring filePath(4096, L'\0');
139+
140+
while (true)
141+
{
142+
DWORD length = GetModuleFileNameW(nullptr, filePath.data(), static_cast<DWORD>(filePath.size() + 1));
143+
144+
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
145+
{
146+
filePath.resize(filePath.capacity() * 2);
147+
continue;
148+
}
149+
150+
filePath.resize(length);
151+
return {filePath};
152+
}
153+
}
154+
155+
auto GetKnownFolderPath(REFKNOWNFOLDERID id, DWORD flags = 0) -> fs::path
156+
{
157+
wchar_t* path{};
158+
159+
if (HRESULT hr = SHGetKnownFolderPath(id, flags, nullptr, &path); SUCCEEDED(hr))
160+
{
161+
fs::path result(path);
162+
CoTaskMemFree(path);
163+
return result;
164+
}
165+
166+
return {};
167+
}
168+
169+
auto GetSystemWinmmPath() -> fs::path
170+
{
171+
std::error_code ec{};
172+
fs::path systemPath = GetKnownFolderPath(FOLDERID_SystemX86);
173+
174+
if (systemPath.empty() || !std::filesystem::is_directory(systemPath, ec))
175+
return {};
176+
177+
fs::path winmmPath = systemPath / "winmm.dll";
178+
179+
if (!fs::is_regular_file(winmmPath, ec))
180+
return {};
181+
182+
return winmmPath;
183+
}
184+
185+
auto LoadWinmmLibrary() -> std::pair<HMODULE, DWORD>
186+
{
187+
HMODULE winmm{};
188+
189+
if (winmm = LoadLibraryExW(L"winmm.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
190+
return {winmm, 1};
191+
192+
if (fs::path winmmPath = GetSystemWinmmPath(); !winmmPath.empty())
193+
{
194+
if (winmm = LoadLibraryW(winmmPath.wstring().c_str()))
195+
return {winmm, 2};
196+
}
197+
198+
if (winmm = LoadLibraryW(L"winmm.dll"))
199+
return {winmm, 3};
200+
201+
return {nullptr, 0};
202+
}

0 commit comments

Comments
 (0)