@@ -920,6 +920,136 @@ void CheckLibVersions( void )
920920}
921921
922922
923+ // ////////////////////////////////////////////////////////
924+ //
925+ // CreateProcessWithMitigationPolicy
926+ //
927+ // Create process with extra security stuff
928+ //
929+ // ////////////////////////////////////////////////////////
930+ BOOL CreateProcessWithMitigationPolicy (
931+ LPCWSTR lpApplicationName,
932+ LPWSTR lpCommandLine,
933+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
934+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
935+ BOOL bInheritHandles,
936+ DWORD dwCreationFlags,
937+ LPVOID lpEnvironment,
938+ LPCWSTR lpCurrentDirectory,
939+ LPPROCESS_INFORMATION lpProcessInformation,
940+ DWORD& dwOutError,
941+ SString& strOutErrorContext
942+ )
943+ {
944+ DWORD64 MitigationPolicy = 0 ;
945+ STARTUPINFOEXW StartupInfoEx = { 0 };
946+ StartupInfoEx.StartupInfo .cb = sizeof ( StartupInfoEx.StartupInfo );
947+
948+ if ( IsWindowsVistaOrGreater () )
949+ {
950+ // We can use extended startup info for Vista and up
951+ StartupInfoEx.StartupInfo .cb = sizeof ( StartupInfoEx );
952+ dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
953+
954+ // Win7 32 bit can only handle DWORD MitigationPolicy
955+ size_t MitigationPolicySize = sizeof ( DWORD );
956+ MitigationPolicy |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE
957+ | PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE
958+ | PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE;
959+
960+ if ( IsWindows8OrGreater () )
961+ {
962+ // We can use more bigger MitigationPolicy for Win8 and up
963+ MitigationPolicySize = sizeof ( DWORD64 );
964+ MitigationPolicy |= PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON;
965+ }
966+
967+ if ( IsWindows10OrGreater () )
968+ {
969+ // Win 10
970+ MitigationPolicy |= PROCESS_CREATION_MITIGATION_POLICY_FONT_DISABLE_ALWAYS_ON;
971+ }
972+
973+ if ( IsWindows10Threshold2OrGreater () )
974+ {
975+ // Win 10 build something
976+ MitigationPolicy |= PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON;
977+ }
978+
979+ #if 0 // TODO
980+ if ( IsWindows10FoamybananaOrGreater () )
981+ {
982+ // Win 10 build something else
983+ MitigationPolicy |= PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON;
984+ }
985+ #endif
986+
987+ // Create AttributeList for mitigation policy application system
988+ SIZE_T AttributeListSize;
989+ if ( _InitializeProcThreadAttributeList ( nullptr , 1 , 0 , &AttributeListSize ) == FALSE )
990+ {
991+ dwOutError = GetLastError ();
992+ if ( dwOutError != ERROR_INSUFFICIENT_BUFFER )
993+ {
994+ strOutErrorContext = " InitializeProcThreadAttributeList #1" ;
995+ return false ;
996+ }
997+ }
998+ else
999+ {
1000+ dwOutError = ERROR_SUCCESS;
1001+ strOutErrorContext = " InitializeProcThreadAttributeList #1 expected error" ;
1002+ return false ;
1003+ }
1004+
1005+ StartupInfoEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc ( GetProcessHeap () ,0 , AttributeListSize );
1006+
1007+ if ( _InitializeProcThreadAttributeList ( StartupInfoEx. lpAttributeList, 1 , 0 , &AttributeListSize ) == FALSE )
1008+ {
1009+ dwOutError = GetLastError ();
1010+ strOutErrorContext = " InitializeProcThreadAttributeList #2" ;
1011+ HeapFree ( GetProcessHeap (), 0 , (LPVOID)StartupInfoEx.lpAttributeList );
1012+ return false ;
1013+ }
1014+
1015+ if ( _UpdateProcThreadAttribute ( StartupInfoEx.lpAttributeList , 0 , PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &MitigationPolicy, MitigationPolicySize, nullptr , nullptr ) == FALSE )
1016+ {
1017+ dwOutError = GetLastError ();
1018+ strOutErrorContext = " UpdateProcThreadAttribute" ;
1019+ _DeleteProcThreadAttributeList ( StartupInfoEx.lpAttributeList );
1020+ HeapFree ( GetProcessHeap (), 0 , (LPVOID)StartupInfoEx.lpAttributeList );
1021+ return false ;
1022+ }
1023+ }
1024+
1025+ // Start GTA
1026+ BOOL bResult = _CreateProcessW ( lpApplicationName,
1027+ lpCommandLine,
1028+ lpProcessAttributes,
1029+ lpThreadAttributes,
1030+ bInheritHandles,
1031+ dwCreationFlags,
1032+ nullptr ,
1033+ lpCurrentDirectory,
1034+ (LPSTARTUPINFOW)&StartupInfoEx,
1035+ lpProcessInformation );
1036+
1037+ if ( bResult == FALSE )
1038+ {
1039+ dwOutError = GetLastError ();
1040+ strOutErrorContext = " CreateProcess" ;
1041+ }
1042+
1043+ if ( IsWindowsVistaOrGreater () )
1044+ {
1045+ // Clean up
1046+ _DeleteProcThreadAttributeList ( StartupInfoEx.lpAttributeList );
1047+ HeapFree ( GetProcessHeap (), 0 , (LPVOID)StartupInfoEx.lpAttributeList );
1048+ }
1049+ return bResult;
1050+ }
1051+
1052+
9231053// ////////////////////////////////////////////////////////
9241054//
9251055// LaunchGame
@@ -948,17 +1078,6 @@ int LaunchGame ( SString strCmdLine )
9481078 SString strGTAEXEPath = GetInstallManager ()->MaybeRenameExe ( strGTAPath );
9491079 SetCurrentDirectory ( strGTAPath );
9501080
951- // ////////////////////////////////////////////////////////
952- //
953- // Hook 'n' go
954- //
955- // Launch GTA using CreateProcess
956- PROCESS_INFORMATION piLoadee;
957- STARTUPINFOW siLoadee;
958- memset ( &piLoadee, 0 , sizeof ( PROCESS_INFORMATION ) );
959- memset ( &siLoadee, 0 , sizeof ( STARTUPINFO ) );
960- siLoadee.cb = sizeof ( STARTUPINFO );
961-
9621081 WatchDogBeginSection ( " L2" ); // Gets closed when loading screen is shown
9631082 WatchDogBeginSection ( " L3" ); // Gets closed when loading screen is shown, or a startup problem is handled elsewhere
9641083 WatchDogBeginSection ( WD_SECTION_NOT_USED_MAIN_MENU ); // Gets closed when the main menu is used
@@ -974,20 +1093,26 @@ int LaunchGame ( SString strCmdLine )
9741093
9751094 WString wstrCmdLine = FromUTF8 ( strCmdLine );
9761095
977- // Start GTA
978- if ( 0 == _CreateProcessW ( FromUTF8 ( strGTAEXEPath ),
1096+ //
1097+ // Launch GTA using CreateProcess
1098+ //
1099+ PROCESS_INFORMATION piLoadee = { 0 };
1100+ DWORD dwError;
1101+ SString strErrorContext;
1102+ if ( FALSE == CreateProcessWithMitigationPolicy (
1103+ FromUTF8 ( strGTAEXEPath ),
9791104 (LPWSTR)*wstrCmdLine,
9801105 NULL ,
9811106 NULL ,
9821107 FALSE ,
9831108 CREATE_SUSPENDED,
9841109 NULL ,
9851110 FromUTF8 ( strMtaDir ), // strMTASAPath\mta is used so pthreadVC2.dll can be found
986- &siLoadee,
987- &piLoadee ) )
1111+ &piLoadee,
1112+ dwError,
1113+ strErrorContext ) )
9881114 {
989- DWORD dwError = GetLastError ();
990- WriteDebugEvent ( SString ( " Loader - Process not created[%d]: %s" , dwError, *strGTAEXEPath ) );
1115+ WriteDebugEvent ( SString ( " Loader - Process not created[%d (%s)]: %s" , dwError, *strErrorContext, *strGTAEXEPath ) );
9911116
9921117 if ( dwError == ERROR_ELEVATION_REQUIRED && !bDoneAdmin )
9931118 {
@@ -999,7 +1124,7 @@ int LaunchGame ( SString strCmdLine )
9991124 else
10001125 {
10011126 // Otherwise, show error message
1002- SString strError = GetSystemErrorMessage ( dwError );
1127+ SString strError = GetSystemErrorMessage ( dwError ) + " ( " + strErrorContext + " ) " ;
10031128 DisplayErrorMessageBox ( SString (_ (" Could not start Grand Theft Auto: San Andreas. "
10041129 " Please try restarting, or if the problem persists,"
10051130 " contact MTA at www.multitheftauto.com. \n\n [%s]" ),*strError), _E (" CL22" ), " createprocess-fail&err=" + strError ); // Could not start GTA:SA
0 commit comments