@@ -920,6 +920,136 @@ void CheckLibVersions( void )
920
920
}
921
921
922
922
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
+
923
1053
// ////////////////////////////////////////////////////////
924
1054
//
925
1055
// LaunchGame
@@ -948,17 +1078,6 @@ int LaunchGame ( SString strCmdLine )
948
1078
SString strGTAEXEPath = GetInstallManager ()->MaybeRenameExe ( strGTAPath );
949
1079
SetCurrentDirectory ( strGTAPath );
950
1080
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
-
962
1081
WatchDogBeginSection ( " L2" ); // Gets closed when loading screen is shown
963
1082
WatchDogBeginSection ( " L3" ); // Gets closed when loading screen is shown, or a startup problem is handled elsewhere
964
1083
WatchDogBeginSection ( WD_SECTION_NOT_USED_MAIN_MENU ); // Gets closed when the main menu is used
@@ -974,20 +1093,26 @@ int LaunchGame ( SString strCmdLine )
974
1093
975
1094
WString wstrCmdLine = FromUTF8 ( strCmdLine );
976
1095
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 ),
979
1104
(LPWSTR)*wstrCmdLine,
980
1105
NULL ,
981
1106
NULL ,
982
1107
FALSE ,
983
1108
CREATE_SUSPENDED,
984
1109
NULL ,
985
1110
FromUTF8 ( strMtaDir ), // strMTASAPath\mta is used so pthreadVC2.dll can be found
986
- &siLoadee,
987
- &piLoadee ) )
1111
+ &piLoadee,
1112
+ dwError,
1113
+ strErrorContext ) )
988
1114
{
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 ) );
991
1116
992
1117
if ( dwError == ERROR_ELEVATION_REQUIRED && !bDoneAdmin )
993
1118
{
@@ -999,7 +1124,7 @@ int LaunchGame ( SString strCmdLine )
999
1124
else
1000
1125
{
1001
1126
// Otherwise, show error message
1002
- SString strError = GetSystemErrorMessage ( dwError );
1127
+ SString strError = GetSystemErrorMessage ( dwError ) + " ( " + strErrorContext + " ) " ;
1003
1128
DisplayErrorMessageBox ( SString (_ (" Could not start Grand Theft Auto: San Andreas. "
1004
1129
" Please try restarting, or if the problem persists,"
1005
1130
" contact MTA at www.multitheftauto.com. \n\n [%s]" ),*strError), _E (" CL22" ), " createprocess-fail&err=" + strError ); // Could not start GTA:SA
0 commit comments