2021-09-06 18:40:37 -04:00
# include <std_include.hpp>
# include "launcher/launcher.hpp"
# include "loader/loader.hpp"
# include "loader/component_loader.hpp"
# include "game/game.hpp"
# include <utils/string.hpp>
# include <utils/flags.hpp>
# include <utils/io.hpp>
DECLSPEC_NORETURN void WINAPI exit_hook ( const int code )
{
component_loader : : pre_destroy ( ) ;
exit ( code ) ;
}
BOOL WINAPI system_parameters_info_a ( const UINT uiAction , const UINT uiParam , const PVOID pvParam , const UINT fWinIni )
{
return SystemParametersInfoA ( uiAction , uiParam , pvParam , fWinIni ) ;
}
FARPROC WINAPI get_proc_address ( const HMODULE hModule , const LPCSTR lpProcName )
{
if ( lpProcName = = " InitializeCriticalSectionEx " s )
{
component_loader : : post_unpack ( ) ;
}
return GetProcAddress ( hModule , lpProcName ) ;
}
launcher : : mode detect_mode_from_arguments ( )
{
if ( utils : : flags : : has_flag ( " singleplayer " ) )
{
return launcher : : mode : : singleplayer ;
}
return launcher : : mode : : none ;
}
2022-03-18 17:02:44 -04:00
FARPROC load_binary ( const launcher : : mode mode )
2021-09-06 18:40:37 -04:00
{
loader loader ;
utils : : nt : : library self ;
loader . set_import_resolver ( [ self ] ( const std : : string & library , const std : : string & function ) - > void *
{
if ( function = = " ExitProcess " )
{
return exit_hook ;
}
else if ( function = = " SystemParametersInfoA " )
{
return system_parameters_info_a ;
}
else if ( function = = " GetProcAddress " )
{
return get_proc_address ;
}
return component_loader : : load_import ( library , function ) ;
} ) ;
std : : string binary ;
switch ( mode )
{
case launcher : : mode : : singleplayer :
binary = " MW2CR.exe " ;
2021-12-29 16:22:13 -05:00
if ( ! utils : : io : : file_exists ( binary ) )
{
binary = " h2_sp64_bnet_ship.exe " ;
}
2021-09-06 18:40:37 -04:00
break ;
case launcher : : mode : : none :
default :
throw std : : runtime_error ( " Invalid game mode! " ) ;
}
std : : string data ;
if ( ! utils : : io : : read_file ( binary , & data ) )
{
throw std : : runtime_error ( utils : : string : : va (
" Failed to read game binary (%s)! \n Please copy the h2-mod.exe into your Call of Duty: Modern Warfare 2 Campaign Remastered installation folder and run it from there. " ,
binary . data ( ) ) ) ;
}
2022-03-18 17:02:44 -04:00
return loader . load ( self , data ) ;
2021-09-06 18:40:37 -04:00
}
void remove_crash_file ( )
{
utils : : io : : remove_file ( " __h2Exe " ) ;
}
2021-09-06 21:22:52 -04:00
void verify_version ( )
{
2022-03-18 17:02:44 -04:00
const auto value = * reinterpret_cast < DWORD * > ( 0x140123456 ) ;
2021-09-06 21:22:52 -04:00
if ( value ! = 0xE465E151 )
{
throw std : : runtime_error ( " Unsupported Call of Duty: Modern Warfare 2 Campaign Remastered version " ) ;
}
}
2021-09-06 18:40:37 -04:00
void enable_dpi_awareness ( )
{
const utils : : nt : : library user32 { " user32.dll " } ;
const auto set_dpi = user32
? user32 . get_proc < BOOL ( WINAPI * ) ( DPI_AWARENESS_CONTEXT ) > ( " SetProcessDpiAwarenessContext " )
: nullptr ;
if ( set_dpi )
{
set_dpi ( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ) ;
}
}
void limit_parallel_dll_loading ( )
{
const utils : : nt : : library self ;
const auto registry_path = R " (Software \ Microsoft \ Windows NT \ CurrentVersion \ Image File Execution Options \ ) " + self .
get_name ( ) ;
HKEY key = nullptr ;
if ( RegCreateKeyA ( HKEY_LOCAL_MACHINE , registry_path . data ( ) , & key ) = = ERROR_SUCCESS )
{
RegCloseKey ( key ) ;
}
key = nullptr ;
if ( RegOpenKeyExA (
HKEY_LOCAL_MACHINE , registry_path . data ( ) , 0 ,
KEY_ALL_ACCESS , & key ) ! = ERROR_SUCCESS )
{
return ;
}
DWORD value = 1 ;
RegSetValueExA ( key , " MaxLoaderThreads " , 0 , REG_DWORD , reinterpret_cast < const BYTE * > ( & value ) , sizeof ( value ) ) ;
RegCloseKey ( key ) ;
}
int main ( )
{
ShowWindow ( GetConsoleWindow ( ) , SW_HIDE ) ;
FARPROC entry_point ;
enable_dpi_awareness ( ) ;
limit_parallel_dll_loading ( ) ;
srand ( uint32_t ( time ( nullptr ) ) ) ;
remove_crash_file ( ) ;
{
auto premature_shutdown = true ;
const auto _ = gsl : : finally ( [ & premature_shutdown ] ( )
{
if ( premature_shutdown )
{
component_loader : : pre_destroy ( ) ;
}
} ) ;
try
{
if ( ! component_loader : : post_start ( ) )
{
return 0 ;
}
auto mode = detect_mode_from_arguments ( ) ;
if ( mode = = launcher : : mode : : none )
{
const launcher launcher ;
mode = launcher . run ( ) ;
if ( mode = = launcher : : mode : : none )
{
return 0 ;
}
}
game : : environment : : set_mode ( mode ) ;
2022-03-18 17:02:44 -04:00
entry_point = load_binary ( mode ) ;
2021-09-06 18:40:37 -04:00
if ( ! entry_point )
{
throw std : : runtime_error ( " Unable to load binary into memory " ) ;
}
2021-09-06 21:22:52 -04:00
verify_version ( ) ;
2021-09-06 18:40:37 -04:00
if ( ! component_loader : : post_load ( ) )
{
return 0 ;
}
premature_shutdown = false ;
}
catch ( std : : exception & e )
{
MessageBoxA ( nullptr , e . what ( ) , " ERROR " , MB_ICONERROR ) ;
return 1 ;
}
}
return static_cast < int > ( entry_point ( ) ) ;
}
int __stdcall WinMain ( HINSTANCE , HINSTANCE , PSTR , int )
{
return main ( ) ;
}