1515#include " Dialogs.h"
1616#include " Utils.h"
1717#include " SharedUtil.Win32Utf8FileHooks.hpp"
18+
1819#if defined(MTA_DEBUG)
1920 #include " SharedUtil.Tests.hpp"
2021#endif
22+
2123#include < version.h>
24+ #include < memory>
25+ #include < algorithm>
26+
27+ namespace {
28+ // Constants
29+ constexpr size_t MAX_CMD_LINE_LENGTH = 4096 ;
30+ constexpr int ERROR_NULL_INSTANCE = -1 ;
31+ constexpr int ERROR_NULL_INSTALL_MANAGER = -2 ;
32+ constexpr int ERROR_LAUNCH_EXCEPTION = -3 ;
33+ constexpr int ERROR_INSTALL_CONTINUE = -4 ;
34+
35+ // Report log IDs
36+ constexpr int LOG_ID_END = 1044 ;
37+ constexpr int LOG_ID_CONTINUE_EXCEPTION = 1045 ;
38+ constexpr int LOG_ID_LAUNCH_EXCEPTION = 1046 ;
39+
40+ class Utf8FileHooksGuard {
41+ public:
42+ Utf8FileHooksGuard () { AddUtf8FileHooks (); }
43+ ~Utf8FileHooksGuard () { RemoveUtf8FileHooks (); }
44+
45+ // Disable copy and move
46+ Utf8FileHooksGuard (const Utf8FileHooksGuard&) = delete ;
47+ Utf8FileHooksGuard& operator =(const Utf8FileHooksGuard&) = delete ;
48+ Utf8FileHooksGuard (Utf8FileHooksGuard&&) = delete ;
49+ Utf8FileHooksGuard& operator =(Utf8FileHooksGuard&&) = delete ;
50+ };
51+
52+ inline void SafeCopyCommandLine (LPSTR lpCmdLine, char * safeCmdLine, size_t bufferSize) {
53+ if (!lpCmdLine || !safeCmdLine || bufferSize == 0 ) {
54+ return ;
55+ }
56+
57+ const size_t maxCopyLen = bufferSize - 1 ;
58+ const size_t cmdLineLen = strnlen (lpCmdLine, maxCopyLen);
59+
60+ memcpy (safeCmdLine, lpCmdLine, cmdLineLen);
61+ safeCmdLine[cmdLineLen] = ' \0 ' ;
62+ }
63+
64+
65+ inline DWORD GetSafeProcessId () noexcept {
66+ try {
67+ return GetCurrentProcessId ();
68+ }
69+ catch (...) {
70+ return 0 ;
71+ }
72+ }
73+
74+ bool PerformInitialization (const char * safeCmdLine) {
75+ auto * pInstallManager = GetInstallManager ();
76+ if (!pInstallManager) {
77+ return false ;
78+ }
79+
80+ // Configure install manager
81+ pInstallManager->SetMTASAPathSource (safeCmdLine);
82+
83+ // Initialize logging
84+ BeginEventLog ();
85+
86+ // Start localization (non-critical, continue on failure)
87+ InitLocalization (false );
88+
89+ // Handle installer commands
90+ HandleSpecialLaunchOptions ();
91+
92+ // Ensure single instance
93+ HandleDuplicateLaunching ();
94+
95+ // Clear any pending operations
96+ ClearPendingBrowseToSolution ();
97+
98+ // Validate GTA installation
99+ ValidateGTAPath ();
100+
101+ return true ;
102+ }
103+
104+ void PerformPreLaunchSetup (HINSTANCE hInstance) {
105+ // Ensure localization is fully initialized
106+ InitLocalization (true );
107+
108+ // Initialize monitoring systems
109+ PreLaunchWatchDogs ();
110+
111+ // Handle custom configurations
112+ HandleCustomStartMessage ();
113+
114+ #if !defined(MTA_DEBUG) && MTASA_VERSION_TYPE != VERSION_TYPE_CUSTOM
115+ ForbodenProgramsMessage ();
116+ #endif
117+
118+ // Maintenance operations
119+ CycleEventLog ();
120+ BsodDetectionPreLaunch ();
121+ MaybeShowCopySettingsDialog ();
122+
123+ // Check for conflicts
124+ HandleIfGTAIsAlreadyRunning ();
125+
126+ // Maybe warn user if no anti-virus running
127+ CheckAntiVirusStatus ();
128+
129+ // Show splash screen
130+ ShowSplash (hInstance);
131+
132+ // Verify integrity
133+ CheckDataFiles ();
134+ CheckLibVersions ();
135+ }
136+
137+ SString ContinueUpdateProcedure (CInstallManager* pInstallManager) {
138+ if (!pInstallManager) {
139+ return SString ();
140+ }
141+
142+ try {
143+ return pInstallManager->Continue ();
144+ }
145+ catch (...) {
146+ AddReportLog (LOG_ID_CONTINUE_EXCEPTION, " Exception in InstallManager::Continue()" );
147+ return SString ();
148+ }
149+ }
150+
151+ int LaunchGameSafely (const SString& strCmdLine) {
152+ try {
153+ return LaunchGame (strCmdLine);
154+ }
155+ catch (...) {
156+ AddReportLog (LOG_ID_LAUNCH_EXCEPTION, " Exception in LaunchGame()" );
157+ return ERROR_LAUNCH_EXCEPTION;
158+ }
159+ }
160+ }
22161
23162// /////////////////////////////////////////////////////////////
24163//
28167// 1. During install with /kdinstall command (as admin)
29168// 2. During uninstall with /kduninstall command (as admin)
30169// 3. By 'MTA San Andreas.exe' when temporary elevated privileges are required (as admin)
31- // 4. By 'MTA San Andreas.exe' during auto-update (in a temporary directory somewhere) (Which may then call it again as admin)
170+ // 4. By 'MTA San Andreas.exe' during auto-update (in a temporary directory somewhere)
171+ // (Which may then call it again as admin)
32172//
33173// /////////////////////////////////////////////////////////////
34- MTAEXPORT int DoWinMain (HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
174+ MTAEXPORT int DoWinMain (HINSTANCE hLauncherInstance, HINSTANCE hPrevInstance,
175+ LPSTR lpCmdLine, int nCmdShow)
35176{
36- AddUtf8FileHooks ();
177+ // Validate critical parameters
178+ if (!hLauncherInstance) {
179+ return ERROR_NULL_INSTANCE;
180+ }
37181
38- #if defined(MTA_DEBUG)
182+ // RAII guard for UTF8 file hooks
183+ Utf8FileHooksGuard utf8Guard;
184+
185+ // Run debug tests if in debug mode
186+ #if defined(MTA_DEBUG)
39187 SharedUtil_Tests ();
40- #endif
188+ #endif
189+
190+ // Prepare safe command line buffer
191+ char safeCmdLine[MAX_CMD_LINE_LENGTH] = {0 };
192+ SafeCopyCommandLine (lpCmdLine, safeCmdLine, sizeof (safeCmdLine));
41193
42194 //
43- // Init
195+ // Initialization Phase
44196 //
197+ if (!PerformInitialization (safeCmdLine)) {
198+ return ERROR_NULL_INSTALL_MANAGER;
199+ }
45200
46- // Let install manager figure out what MTASA path to use
47- GetInstallManager ()->SetMTASAPathSource (lpCmdLine);
48-
49- // Start logging.....now
50- BeginEventLog ();
51-
52- // Start localization if possible
53- InitLocalization (false );
54-
55- // Handle commands from the installer
56- HandleSpecialLaunchOptions ();
57-
58- // Check MTA is launched only once
59- HandleDuplicateLaunching ();
60-
61- // Show logo
62- ShowSplash (g_hInstance);
63-
64- // Other init stuff
65- ClearPendingBrowseToSolution ();
66-
67- // Find GTA path to use
68- ValidateGTAPath ();
201+ // Show initial splash screen
202+ ShowSplash (hLauncherInstance);
69203
70204 //
71- // Update
205+ // Update Phase
72206 //
73-
74- // Continue any update procedure
75- SString strCmdLine = GetInstallManager ()->Continue ();
207+ auto * pInstallManager = GetInstallManager ();
208+ const SString strCmdLine = ContinueUpdateProcedure (pInstallManager);
76209
77210 //
78- // Launch
211+ // Pre- Launch Phase
79212 //
213+ PerformPreLaunchSetup (hLauncherInstance);
80214
81- // Ensure localization is started
82- InitLocalization (true );
83-
84- // Setup/test various counters and flags for monitoring problems
85- PreLaunchWatchDogs ();
86-
87- // Stuff
88- HandleCustomStartMessage ();
89- #if !defined(MTA_DEBUG) && MTASA_VERSION_TYPE != VERSION_TYPE_CUSTOM
90- ForbodenProgramsMessage ();
91- #endif
92- CycleEventLog ();
93- BsodDetectionPreLaunch ();
94- MaybeShowCopySettingsDialog ();
95-
96- // Make sure GTA is not running
97- HandleIfGTAIsAlreadyRunning ();
98-
99- // Maybe warn user if no anti-virus running
100- CheckAntiVirusStatus ();
101-
102- // Ensure logo is showing
103- ShowSplash (g_hInstance);
104-
105- // Check MTA files look good
106- CheckDataFiles ();
107- CheckLibVersions ();
108-
109- // Go for launch
110- int iReturnCode = LaunchGame (strCmdLine);
111-
215+ //
216+ // Launch Phase
217+ //
218+ const int iReturnCode = LaunchGameSafely (strCmdLine);
219+
220+ // Post-launch monitoring
112221 PostRunWatchDogs (iReturnCode);
113222
114223 //
115- // Quit
224+ // Cleanup Phase
116225 //
117-
118226 HandleOnQuitCommand ();
119-
120- // Maybe show help if trouble was encountered
121227 ProcessPendingBrowseToSolution ();
122228
123- AddReportLog (1044 , SString (" * End (0x%X)* pid:%d" , iReturnCode, GetCurrentProcessId ()));
229+ // Log termination details
230+ const DWORD currentPid = GetSafeProcessId ();
231+ AddReportLog (LOG_ID_END, SString (" * End (0x%X)* pid:%d" , iReturnCode, currentPid));
124232
125- RemoveUtf8FileHooks ();
126233 return iReturnCode;
127- }
234+ }
0 commit comments