Skip to content

Commit f2efe62

Browse files
committed
Rename loader proxy winmm.dll to mtasa.dll
1 parent 6ae0f65 commit f2efe62

File tree

7 files changed

+163
-46
lines changed

7 files changed

+163
-46
lines changed

Client/loader-proxy/generator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: loader-proxy/generator.cpp
6-
* PURPOSE: Generates setup.cpp, winmm.asm and exports.def for the loader proxy
6+
* PURPOSE: Generates setup.cpp, mtasa.asm and exports.def for the loader proxy
77
*
88
* Multi Theft Auto is available from https://multitheftauto.com/
99
*
@@ -242,7 +242,7 @@ int main(int argc, char* argv[])
242242
}
243243

244244
{
245-
std::ofstream output("winmm.asm");
245+
std::ofstream output("mtasa.asm");
246246
output << "; Do not edit this file manually because it has been generated by generator.cpp\n"
247247
<< "\n"
248248
<< ".386\n"

Client/loader-proxy/main.cpp

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,6 @@ void DisplayErrorMessageBox(const std::wstring& message, const std::wstring& err
2626
TerminateProcess(GetCurrentProcess(), 1);
2727
}
2828

29-
void DisplayWinmmErrorMessageBox(const std::wstring& errorCode)
30-
{
31-
DisplayErrorMessageBox(
32-
L"Loading system-provided winmm.dll failed.\n\n"
33-
L"Please ensure that your Windows installation\n"
34-
L"is not missing files and your user is not lacking\n"
35-
L"any permission to access the system directory.",
36-
errorCode);
37-
}
38-
3929
auto GetKnownFolderPath(REFKNOWNFOLDERID id, DWORD flags = 0) -> std::filesystem::path
4030
{
4131
wchar_t* path{};
@@ -70,29 +60,17 @@ auto GetProcessPath() -> std::filesystem::path
7060
}
7161

7262
static auto winmm = ([]() -> HMODULE {
73-
std::error_code ec{};
74-
std::filesystem::path systemPath = GetKnownFolderPath(FOLDERID_SystemX86);
75-
76-
if (systemPath.empty() || !std::filesystem::is_directory(systemPath, ec))
77-
{
78-
DisplayWinmmErrorMessageBox(L"CL50");
79-
return nullptr;
80-
}
81-
82-
std::filesystem::path winmmPath = systemPath / "winmm.dll";
83-
std::wstring libraryPath = winmmPath.wstring();
84-
85-
if (!std::filesystem::is_regular_file(winmmPath, ec))
86-
{
87-
DisplayWinmmErrorMessageBox(L"CL51");
88-
return nullptr;
89-
}
90-
91-
HMODULE winmm = LoadLibraryW(libraryPath.c_str());
63+
HMODULE winmm = LoadLibraryExW(L"winmm.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
9264

9365
if (!winmm)
9466
{
95-
DisplayWinmmErrorMessageBox(L"CL52");
67+
DisplayErrorMessageBox(
68+
L"Loading system-provided winmm.dll failed.\n\n"
69+
L"Please ensure that your Windows installation\n"
70+
L"is not missing files and your user is not lacking\n"
71+
L"any permission to access the system directory.",
72+
L"CL52");
73+
9674
return nullptr;
9775
}
9876

@@ -108,7 +86,13 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
10886
{
10987
if (!winmm)
11088
{
111-
DisplayWinmmErrorMessageBox(L"CL53");
89+
DisplayErrorMessageBox(
90+
L"Loading system-provided winmm.dll failed.\n\n"
91+
L"Please ensure that your Windows installation\n"
92+
L"is not missing files and your user is not lacking\n"
93+
L"any permission to access the system directory.",
94+
L"CL50");
95+
11296
return FALSE;
11397
}
11498

@@ -126,19 +110,26 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
126110
{
127111
#ifdef MTA_DEBUG
128112
DisplayErrorMessageBox(
129-
L"Loading core failed. Please ensure that \n"
113+
L"Loading core failed. Please ensure that\n"
130114
L"the latest DirectX is correctly installed and you executed win-install-data.bat",
131115
L"CL24");
132116
#else
133117
DisplayErrorMessageBox(
134-
L"Loading core failed. Please ensure that \n"
118+
L"Loading core failed. Please ensure that\n"
135119
L"the latest DirectX is correctly installed.",
136120
L"CL24");
137121
#endif
138122

139123
return FALSE;
140124
}
141125
}
126+
else
127+
{
128+
DisplayErrorMessageBox(
129+
L"Loading core failed. Please ensure that\n"
130+
L"you installed and launched MTA:SA properly.",
131+
L"CL51");
132+
}
142133
}
143134
else if (reason == DLL_PROCESS_DETACH)
144135
{
File renamed without changes.

Client/loader-proxy/premake5.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
project "Loader Proxy"
22
language "C++"
33
kind "SharedLib"
4-
targetname "winmm"
4+
targetname "mtasa"
55
targetdir(buildpath("mta"))
66
targetsuffix ""
77

@@ -15,7 +15,7 @@ project "Loader Proxy"
1515
files {
1616
"premake5.lua",
1717
"exports.def",
18-
"winmm.asm",
18+
"mtasa.asm",
1919
"setup.cpp",
2020
"main.cpp",
2121
}

Client/loader/CExePatchedStatus.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SExePatchedStatus GetExePatchedStatus(bool bUseExeCopy)
2828
status.bNvightmare = UpdatePatchStatusNvightmare(strGTAEXEPath, PATCH_CHECK) == PATCH_CHECK_RESULT_ON;
2929
status.bAltModules = UpdatePatchStatusAltModules(strGTAEXEPath, PATCH_CHECK) == PATCH_CHECK_RESULT_ON;
3030
status.bEntryPoint = UpdatePatchStatusEntryPoint(strGTAEXEPath, PATCH_CHECK) == PATCH_CHECK_RESULT_ON;
31+
status.bProxyLoader = UpdatePatchStatusProxyLoader(strGTAEXEPath, PATCH_CHECK) == PATCH_CHECK_RESULT_ON;
3132

3233
return status;
3334
}
@@ -48,6 +49,7 @@ SExePatchedStatus GetExePatchRequirements()
4849
status.bNvightmare = GetApplicationSettingInt("nvhacks", "optimus-export-enablement") ? true : false;
4950
status.bAltModules = GetPatchRequirementAltModules();
5051
status.bEntryPoint = GetPatchRequirementEntryPoint();
52+
status.bProxyLoader = true;
5153

5254
return status;
5355
}
@@ -71,6 +73,7 @@ bool SetExePatchedStatus(bool bUseExeCopy, const SExePatchedStatus& status)
7173
bReqAdmin |= UpdatePatchStatusNvightmare(strGTAEXEPath, status.bNvightmare ? PATCH_SET_ON : PATCH_SET_OFF) == PATCH_SET_RESULT_REQ_ADMIN;
7274
bReqAdmin |= UpdatePatchStatusAltModules(strGTAEXEPath, status.bAltModules ? PATCH_SET_ON : PATCH_SET_OFF) == PATCH_SET_RESULT_REQ_ADMIN;
7375
bReqAdmin |= UpdatePatchStatusEntryPoint(strGTAEXEPath, status.bEntryPoint ? PATCH_SET_ON : PATCH_SET_OFF) == PATCH_SET_RESULT_REQ_ADMIN;
76+
bReqAdmin |= UpdatePatchStatusProxyLoader(strGTAEXEPath, status.bProxyLoader ? PATCH_SET_ON : PATCH_SET_OFF) == PATCH_SET_RESULT_REQ_ADMIN;
7477

7578
return !bReqAdmin;
7679
}
@@ -99,6 +102,8 @@ bool ShouldUseExeCopy()
99102
if (RequiresAltTabFix())
100103
strUseCopyReason += " AltTabFix";
101104

105+
strUseCopyReason += "ProxyLoader";
106+
102107
// Log reason for using proxy_sa
103108
static SString strUseCopyReasonPrevious;
104109
if (strUseCopyReasonPrevious != strUseCopyReason)
@@ -161,6 +166,8 @@ SString GetPatchExeAdminReason(bool bUseExeCopy, const SExePatchedStatus& reqSta
161166
return _("Fix file issues");
162167
if (status.bEntryPoint != reqStatus.bEntryPoint)
163168
return _("Fix file issues");
169+
if (status.bProxyLoader != reqStatus.bProxyLoader)
170+
return _("Use proxy loader");
164171
return _("Copy main executable to avoid graphic driver issues");
165172
}
166173

@@ -794,3 +801,85 @@ bool GetPatchRequirementEntryPoint()
794801
}
795802
return bMismatch;
796803
}
804+
805+
//////////////////////////////////////////////////////////
806+
//
807+
// UpdatePatchStatusProxyLoader
808+
//
809+
// Replace import library name "winmm.dll" with "mtasa.dll" to load core.dll into the game
810+
// without interference from a preloaded winmm.dll in the system.
811+
//
812+
//////////////////////////////////////////////////////////
813+
EPatchResult UpdatePatchStatusProxyLoader(const SString& strGTAEXEPath, EPatchMode mode)
814+
{
815+
const std::string original = "winmm.dll";
816+
const std::string replacement = "mtasa.dll";
817+
const std::streamoff baseOffset = 0x4a0000;
818+
819+
std::fstream file(FromUTF8(strGTAEXEPath), std::ios::in | std::ios::binary);
820+
std::streamoff position = 0;
821+
bool isPatched = false;
822+
823+
if (file)
824+
{
825+
file.seekg(baseOffset);
826+
827+
std::vector<char> buffer(0x3000, '\0');
828+
file.read(buffer.data(), buffer.size());
829+
830+
auto iter = std::search(buffer.begin(), buffer.end(), original.begin(), original.end(), SearchPredicate);
831+
832+
if (iter == buffer.end())
833+
{
834+
iter = std::search(buffer.begin(), buffer.end(), replacement.begin(), replacement.end(), SearchPredicate);
835+
836+
if (iter != buffer.end())
837+
{
838+
// Replacement value found.
839+
position = baseOffset + std::distance(buffer.begin(), iter);
840+
isPatched = true;
841+
}
842+
}
843+
else
844+
{
845+
// Original value found.
846+
position = baseOffset + std::distance(buffer.begin(), iter);
847+
}
848+
849+
file.close();
850+
}
851+
else
852+
{
853+
WriteDebugEvent("ProxyLoader: Unable to open target executable file");
854+
}
855+
856+
if (mode == PATCH_CHECK)
857+
{
858+
return isPatched ? PATCH_CHECK_RESULT_ON : PATCH_CHECK_RESULT_OFF;
859+
}
860+
861+
if (!position)
862+
{
863+
// Neither original nor replacement were found.
864+
WriteDebugEventAndReport(9807, "ProxyLoader: Unable to open target executable file");
865+
}
866+
867+
if (!isPatched)
868+
{
869+
// Change needed! Can't do this to gta_sa.exe
870+
assert(!strGTAEXEPath.EndsWithI("gta_sa.exe"));
871+
872+
file.open(FromUTF8(strGTAEXEPath), std::ios::in | std::ios::out | std::ios::binary);
873+
file.seekg(position);
874+
file.write(replacement.c_str(), replacement.size());
875+
file.close();
876+
877+
if (file.fail())
878+
{
879+
return PATCH_SET_RESULT_REQ_ADMIN;
880+
}
881+
}
882+
883+
WriteDebugEvent("Proxy loader patch: File update completed");
884+
return PATCH_SET_RESULT_OK;
885+
}

Client/loader/CExePatchedStatus.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ struct SExePatchedStatus
1616
bool bNvightmare;
1717
bool bAltModules;
1818
bool bEntryPoint;
19+
bool bProxyLoader;
1920

2021
bool operator!=(const SExePatchedStatus& other) const { return !operator==(other); }
2122
bool operator==(const SExePatchedStatus& other) const
2223
{
2324
return bTimestamp == other.bTimestamp && bLargeMem == other.bLargeMem && bDep == other.bDep && bNvightmare == other.bNvightmare &&
24-
bAltModules == other.bAltModules && bEntryPoint == other.bEntryPoint;
25+
bAltModules == other.bAltModules && bEntryPoint == other.bEntryPoint && bProxyLoader == other.bProxyLoader;
2526
}
2627
};
2728

@@ -59,3 +60,4 @@ bool GetPatchRequirementAltModules();
5960
EPatchResult UpdatePatchStatusAltModules(const SString& strGTAEXEPath, EPatchMode mode);
6061
bool GetPatchRequirementEntryPoint();
6162
EPatchResult UpdatePatchStatusEntryPoint(const SString& strGTAEXEPath, EPatchMode mode);
63+
EPatchResult UpdatePatchStatusProxyLoader(const SString& strGTAEXEPath, EPatchMode mode);

Client/loader/CInstallManager.cpp

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,23 +1089,58 @@ SString CInstallManager::_ProcessAppCompatChecks()
10891089
//
10901090
// CInstallManager::_ProcessWinmmChecks
10911091
//
1092-
// Ensure winmm.dll does not exist in the gta directory
1092+
// Ensure {winmm,mtasa}.dll does not exist in the wrong directory
10931093
//
10941094
//////////////////////////////////////////////////////////
10951095
SString CInstallManager::_ProcessWinmmChecks()
10961096
{
1097-
SString filePath = PathJoin(GetGTAPath(), "winmm.dll");
1097+
// Rename winmm.dll in the GTA directory.
1098+
{
1099+
SString filePath = PathJoin(GetGTAPath(), "winmm.dll");
1100+
1101+
if (FileExists(filePath))
1102+
{
1103+
SString filePathBak = PathJoin(GetGTAPath(), "winmm.dll.backup");
1104+
FileDelete(filePathBak);
1105+
FileRename(filePath, filePathBak);
10981106

1099-
if (FileExists(filePath))
1107+
if (FileExists(filePath))
1108+
{
1109+
m_strAdminReason = _("Move incompatible files");
1110+
return "fail";
1111+
}
1112+
}
1113+
}
1114+
1115+
// Delete mtasa.dll in the GTA directory.
11001116
{
1101-
SString filePathBak = PathJoin(GetGTAPath(), "winmm.dll.backup");
1102-
FileDelete(filePathBak);
1103-
FileRename(filePath, filePathBak);
1117+
SString filePath = PathJoin(GetGTAPath(), "mtasa.dll");
11041118

11051119
if (FileExists(filePath))
11061120
{
1107-
m_strAdminReason = _("Move incompatible files");
1108-
return "fail";
1121+
FileDelete(filePath);
1122+
1123+
if (FileExists(filePath))
1124+
{
1125+
m_strAdminReason = _("Delete incompatible files");
1126+
return "fail";
1127+
}
1128+
}
1129+
}
1130+
1131+
// Delete winmm.dll in our MTA directory.
1132+
{
1133+
SString filePath = PathJoin(CalcMTASAPath("mta"), "winmm.dll");
1134+
1135+
if (FileExists(filePath))
1136+
{
1137+
FileDelete(filePath);
1138+
1139+
if (FileExists(filePath))
1140+
{
1141+
m_strAdminReason = _("Delete incompatible files");
1142+
return "fail";
1143+
}
11091144
}
11101145
}
11111146

0 commit comments

Comments
 (0)