17
17
#include < windows.h>
18
18
#include < shlobj.h>
19
19
20
- __forceinline void SetupLibraryExports (HMODULE Handle) noexcept ;
20
+ namespace fs = std::filesystem ;
21
21
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>;
28
26
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 ;
47
29
48
30
static auto winmm = ([]() -> HMODULE {
49
- HMODULE winmm = LoadLibraryExW ( L" winmm.dll " , nullptr , LOAD_LIBRARY_SEARCH_SYSTEM32 );
31
+ auto [ winmm, source] = LoadWinmmLibrary ( );
50
32
51
33
if (!winmm)
52
34
{
@@ -61,11 +43,10 @@ static auto winmm = ([]() -> HMODULE {
61
43
}
62
44
63
45
SetupLibraryExports (winmm);
46
+ winmmSource = source;
64
47
return winmm;
65
48
})();
66
49
67
- static HMODULE core{};
68
-
69
50
BOOL WINAPI DllMain (HINSTANCE, DWORD reason, LPVOID)
70
51
{
71
52
if (reason == DLL_PROCESS_ATTACH)
@@ -134,3 +115,88 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
134
115
135
116
return TRUE ;
136
117
}
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