diff options
-rw-r--r-- | build/server.mk | 8 | ||||
-rwxr-xr-x | configure | 6 | ||||
-rw-r--r-- | source/cl_main.c | 2 | ||||
-rw-r--r-- | source/sv_ac.c | 2 | ||||
-rw-r--r-- | source/sv_init.c | 2 | ||||
-rw-r--r-- | source/sv_local.h | 13 | ||||
-rw-r--r-- | source/sv_main.c | 12 | ||||
-rw-r--r-- | source/sv_user.c | 12 | ||||
-rw-r--r-- | source/sys_public.h | 2 | ||||
-rw-r--r-- | source/sys_unix.c | 2 | ||||
-rw-r--r-- | source/sys_win.c | 1965 | ||||
-rw-r--r-- | source/win_ac.c | 92 | ||||
-rw-r--r-- | source/win_dbg.c | 329 | ||||
-rw-r--r-- | source/win_local.h | 22 |
14 files changed, 1249 insertions, 1220 deletions
diff --git a/build/server.mk b/build/server.mk index 163a904..a334bd3 100644 --- a/build/server.mk +++ b/build/server.mk @@ -26,6 +26,10 @@ SRCFILES+=sv_ccmds.c \ sv_user.c \ sv_world.c +ifdef USE_AC_SERVER +SRCFILES+=sv_ac.c +endif + ifdef USE_MVD_SERVER SRCFILES+=sv_mvd.c endif @@ -36,7 +40,3 @@ SRCFILES+=mvd_client.c \ mvd_game.c endif -ifdef USE_ANTICHEAT -SRCFILES+=sv_ac.c -endif - @@ -186,7 +186,7 @@ echo " --cross-prefix=PREFIX add PREFIX to compile tools [$cross_prefix]" echo " --cc=CC use C compiler [$cc]" echo " --make=MAKE use MAKE processor [$make]" echo " --windres=WINDRES use RC compiler [$windres]" -echo " --disable-client do not build client" +echo " --disable-client do not build graphical client" echo " --enable-server build dedicated server" echo " --enable-openffa build OpenFFA deathmatch mod" echo " --enable-mingw enable Windows build" @@ -517,8 +517,8 @@ if [ "$use_asm" = "yes" ]; then fi if [ "$use_anticheat" = "yes" ]; then - echo "USE_ANTICHEAT=yes" >> $config_mk - echo "#define USE_ANTICHEAT 2" >> $config_h + echo "USE_AC_SERVER=yes" >> $config_mk + echo "#define USE_AC_SERVER 1" >> $config_h fi if [ "$use_mvd_server" = "yes" ]; then diff --git a/source/cl_main.c b/source/cl_main.c index 2b0276d..e3a5aa3 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -1345,7 +1345,7 @@ static void CL_ConnectionlessPacket( void ) { cls.netchan = Netchan_Setup( NS_CLIENT, type, &cls.serverAddress, cls.quakePort, 1024, cls.serverProtocol ); -#if USE_ANTICHEAT & 1 +#if USE_AC_CLIENT if( anticheat ) { MSG_WriteByte( clc_nop ); MSG_FlushTo( &cls.netchan->message ); diff --git a/source/sv_ac.c b/source/sv_ac.c index b3ac447..beec6a2 100644 --- a/source/sv_ac.c +++ b/source/sv_ac.c @@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "sv_local.h" +#include "q_fifo.h" +#include "net_stream.h" typedef enum { ACS_BAD, diff --git a/source/sv_init.c b/source/sv_init.c index a10efa4..5df771f 100644 --- a/source/sv_init.c +++ b/source/sv_init.c @@ -258,7 +258,7 @@ void SV_InitGame( qboolean ismvd ) { client->number = i; } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_Connect( ismvd ); #endif diff --git a/source/sv_local.h b/source/sv_local.h index 9d7ea9c..0ca4906 100644 --- a/source/sv_local.h +++ b/source/sv_local.h @@ -111,7 +111,7 @@ typedef enum { cs_spawned // client is fully in game } clstate_t; -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER typedef enum { AC_NORMAL, @@ -125,7 +125,7 @@ typedef enum { AC_QUERY_DONE } ac_query_t; -#endif // USE_ANTICHEAT +#endif // USE_AC_SERVER #define MSG_POOLSIZE 1024 #define MSG_TRESHOLD ( 64 - 10 ) // keep pmsg_s 64 bytes aligned @@ -248,7 +248,7 @@ typedef struct client_s { netchan_t *netchan; int numpackets; // for that nasty packetdup hack -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER qboolean ac_valid; ac_query_t ac_query_sent; ac_required_t ac_required; @@ -475,6 +475,8 @@ void SV_ClientAddMessage_New( client_t *client, byte *data, void SV_CalcSendTime( client_t *client, size_t messageSize ); +#if USE_MVD_SERVER + // // sv_mvd.c // @@ -495,8 +497,9 @@ void SV_MvdBroadcastPrint( int level, const char *string ); void SV_MvdStartSound( int entnum, int channel, int flags, int soundindex, int volume, int attenuation, int timeofs ); +#endif // USE_MVD_SERVER -#if USE_ANTICHEAT +#if USE_AC_SERVER // // sv_ac.c @@ -515,7 +518,7 @@ void AC_Run( void ); void AC_List_f( void ); void AC_Info_f( void ); -#endif // USE_ANTICHEAT +#endif // USE_AC_SERVER // // sv_user.c diff --git a/source/sv_main.c b/source/sv_main.c index f386dbd..a0f305f 100644 --- a/source/sv_main.c +++ b/source/sv_main.c @@ -122,7 +122,7 @@ void SV_RemoveClient( client_t *client ) { void SV_CleanClient( client_t *client ) { int i; -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER string_entry_t *bad, *next; for( bad = client->ac_bad_files; bad; bad = next ) { @@ -205,7 +205,7 @@ void SV_DropClient( client_t *client, const char *reason ) { ge->ClientDisconnect( client->edict ); } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_ClientDisconnect( client ); #endif @@ -902,7 +902,7 @@ static void SVC_DirectConnect( void ) { Q_strlcpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ) ); SV_UserinfoChanged( newcl ); -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER if( !sv_force_reconnect->string[0] || reconnect_var[0] ) { acstring = AC_ClientConnect( newcl ); } else @@ -1580,7 +1580,7 @@ void SV_Frame( unsigned msec ) { } #endif -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_Run(); #endif @@ -1819,7 +1819,7 @@ void SV_Init( void ) { MVD_Register(); #endif -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_Register(); #endif @@ -1973,7 +1973,7 @@ void SV_Shutdown( const char *finalmsg, killtype_t type ) { return; } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_Disconnect(); #endif diff --git a/source/sv_user.c b/source/sv_user.c index 29f36d2..c57eabb 100644 --- a/source/sv_user.c +++ b/source/sv_user.c @@ -421,7 +421,7 @@ void SV_New_f( void ) { // send version string request if( oldstate == cs_assigned ) { SV_ClientCommand( sv_client, "cmd \177c version $version\n" -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER "cmd \177c actoken $actoken\n" #endif ); @@ -488,7 +488,7 @@ void SV_Begin_f( void ) { return; } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER if( !AC_ClientBegin( sv_client ) ) { return; } @@ -506,7 +506,7 @@ void SV_Begin_f( void ) { // call the game begin function ge->ClientBegin( sv_player ); -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER AC_ClientAnnounce( sv_client ); #endif } @@ -779,14 +779,14 @@ static void SV_CvarResult_f( void ) { } } } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER else if( !strcmp( c, "actoken" ) ) { AC_ClientToken( sv_client, Cmd_Argv( 2 ) ); } #endif } -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER static void SV_AC_List_f( void ) { SV_BeginRedirect( RD_CLIENT ); @@ -830,7 +830,7 @@ static const ucmd_t ucmds[] = { #if USE_PACKETDUP { "packetdup", SV_PacketdupHack_f }, #endif -#if USE_ANTICHEAT & 2 +#if USE_AC_SERVER { "aclist", SV_AC_List_f }, { "acinfo", SV_AC_Info_f }, #else diff --git a/source/sys_public.h b/source/sys_public.h index 86f9451..8dbb129 100644 --- a/source/sys_public.h +++ b/source/sys_public.h @@ -62,7 +62,7 @@ void Sys_DebugBreak( void ); void Sys_FixFPCW( void ); -#ifdef USE_ANTICHEAT +#ifdef USE_AC_CLIENT qboolean Sys_GetAntiCheatAPI( void ); #endif diff --git a/source/sys_unix.c b/source/sys_unix.c index 2128b56..05b665a 100644 --- a/source/sys_unix.c +++ b/source/sys_unix.c @@ -619,7 +619,7 @@ void Sys_Sleep( int msec ) { nanosleep( &req, NULL ); } -#if USE_ANTICHEAT & 1 +#if USE_AC_CLIENT qboolean Sys_GetAntiCheatAPI( void ) { Sys_Sleep( 1500 ); return qfalse; diff --git a/source/sys_win.c b/source/sys_win.c index 5c76c4b..5bcf325 100644 --- a/source/sys_win.c +++ b/source/sys_win.c @@ -26,199 +26,127 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if !USE_CLIENT #include <winsvc.h> #endif -#ifdef USE_DBGHELP -#include <dbghelp.h> -#endif #include <float.h> -#define MAX_CONSOLE_INPUT_EVENTS 16 +#define MAX_CONSOLE_INPUT_EVENTS 16 -static HANDLE hinput = INVALID_HANDLE_VALUE; -static HANDLE houtput = INVALID_HANDLE_VALUE; +static HANDLE hinput = INVALID_HANDLE_VALUE; +static HANDLE houtput = INVALID_HANDLE_VALUE; -static cvar_t *sys_viewlog; -static commandPrompt_t sys_con; -static int sys_hidden; -static CONSOLE_SCREEN_BUFFER_INFO sbinfo; -static qboolean gotConsole; -static volatile qboolean errorEntered; -static volatile qboolean shouldExit; +static cvar_t *sys_viewlog; +static commandPrompt_t sys_con; +static int sys_hidden; +static CONSOLE_SCREEN_BUFFER_INFO sbinfo; +static qboolean gotConsole; +static volatile qboolean errorEntered; +static volatile qboolean shouldExit; #if !USE_CLIENT -static SERVICE_STATUS_HANDLE statusHandle; +static SERVICE_STATUS_HANDLE statusHandle; #endif -HINSTANCE hGlobalInstance; +HINSTANCE hGlobalInstance; -qboolean iswinnt; +qboolean iswinnt; -cvar_t *sys_basedir; +cvar_t *sys_basedir; cvar_t *sys_libdir; cvar_t *sys_homedir; -static char currentDirectory[MAX_OSPATH]; +static char currentDirectory[MAX_OSPATH]; /* =============================================================================== -SYSTEM IO +CONSOLE I/O =============================================================================== */ -void Sys_DebugBreak( void ) { - DebugBreak(); -} - -/* -================ -Sys_Printf -================ -*/ -void Sys_Printf( const char *fmt, ... ) { - va_list argptr; - char msg[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( msg, sizeof( msg ), fmt, argptr ); - va_end( argptr ); +static void Sys_HideInput( void ) { + DWORD dummy; + int i; - Sys_ConsoleOutput( msg ); + if( !sys_hidden ) { + for( i = 0; i <= sys_con.inputLine.cursorPos; i++ ) { + WriteFile( houtput, "\b \b", 3, &dummy, NULL ); + } + } + sys_hidden++; } -/* -================ -Sys_Error -================ -*/ -void Sys_Error( const char *error, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, error ); - Q_vsnprintf( text, sizeof( text ), error, argptr ); - va_end( argptr ); +static void Sys_ShowInput( void ) { + DWORD dummy; + int i; - errorEntered = qtrue; + if( !sys_hidden ) { + Com_EPrintf( "Sys_ShowInput: not hidden\n" ); + return; + } - Sys_Printf( S_COLOR_RED "********************\n" - "FATAL: %s\n" - "********************\n", text ); -#if !USE_CLIENT - if( !statusHandle ) -#endif - { - if( gotConsole ) { - Sleep( INFINITE ); - } - MessageBoxA( NULL, text, APPLICATION " Fatal Error", MB_ICONERROR | MB_OK ); - } - - exit( 1 ); + sys_hidden--; + if( !sys_hidden ) { + WriteFile( houtput, "]", 1, &dummy, NULL ); + for( i = 0; i < sys_con.inputLine.cursorPos; i++ ) { + WriteFile( houtput, &sys_con.inputLine.text[i], 1, &dummy, NULL ); + } + } } /* ================ -Sys_Quit +Sys_ConsoleInput ================ */ -void Sys_Quit( void ) { - timeEndPeriod( 1 ); +void Sys_RunConsole( void ) { + INPUT_RECORD recs[MAX_CONSOLE_INPUT_EVENTS]; + DWORD dummy; + int ch; + DWORD numread, numevents; + int i; + inputField_t *f; + char *s; + + if( hinput == INVALID_HANDLE_VALUE ) { + return; + } -#if USE_CLIENT - if( dedicated && dedicated->integer ) { - FreeConsole(); + if( !gotConsole ) { + return; } -#else - if( !statusHandle ) -#endif - exit( 0 ); -} -static void Sys_HideInput( void ) { - DWORD dummy; - int i; - - if( !sys_hidden ) { - for( i = 0; i <= sys_con.inputLine.cursorPos; i++ ) { - WriteFile( houtput, "\b \b", 3, &dummy, NULL ); - } - } - sys_hidden++; -} + f = &sys_con.inputLine; + while( 1 ) { + if( !GetNumberOfConsoleInputEvents( hinput, &numevents ) ) { + Com_EPrintf( "Error %lu getting number of console events.\n", GetLastError() ); + gotConsole = qfalse; + return; + } -static void Sys_ShowInput( void ) { - DWORD dummy; - int i; - - if( !sys_hidden ) { - Com_EPrintf( "Sys_ShowInput: not hidden\n" ); - return; - } - - sys_hidden--; - if( !sys_hidden ) { - WriteFile( houtput, "]", 1, &dummy, NULL ); - for( i = 0; i < sys_con.inputLine.cursorPos; i++ ) { - WriteFile( houtput, &sys_con.inputLine.text[i], 1, &dummy, NULL ); - } - } -} + if( numevents <= 0 ) + break; + if( numevents > MAX_CONSOLE_INPUT_EVENTS ) { + numevents = MAX_CONSOLE_INPUT_EVENTS; + } -/* -================ -Sys_ConsoleInput -================ -*/ -void Sys_RunConsole( void ) { - INPUT_RECORD recs[MAX_CONSOLE_INPUT_EVENTS]; - DWORD dummy; - int ch; - DWORD numread, numevents; - int i; - inputField_t *f; - char *s; - - if( hinput == INVALID_HANDLE_VALUE ) { - return; - } - - if( !gotConsole ) { - return; - } - - f = &sys_con.inputLine; - while( 1 ) { - if( !GetNumberOfConsoleInputEvents( hinput, &numevents ) ) { - Com_EPrintf( "Error %lu getting number of console events.\n", GetLastError() ); - gotConsole = qfalse; - return; - } - - if( numevents <= 0 ) - break; - if( numevents > MAX_CONSOLE_INPUT_EVENTS ) { - numevents = MAX_CONSOLE_INPUT_EVENTS; - } - - if( !ReadConsoleInput( hinput, recs, numevents, &numread ) ) { - Com_EPrintf( "Error %lu reading console input.\n", GetLastError() ); - gotConsole = qfalse; - return; - } - - for( i = 0; i < numread; i++ ) { - if( recs[i].EventType == WINDOW_BUFFER_SIZE_EVENT ) { + if( !ReadConsoleInput( hinput, recs, numevents, &numread ) ) { + Com_EPrintf( "Error %lu reading console input.\n", GetLastError() ); + gotConsole = qfalse; + return; + } + + for( i = 0; i < numread; i++ ) { + if( recs[i].EventType == WINDOW_BUFFER_SIZE_EVENT ) { // determine terminal width size_t width = recs[i].Event.WindowBufferSizeEvent.dwSize.X; if( !width ) { Com_EPrintf( "Invalid console buffer width.\n" ); - gotConsole = qfalse; + gotConsole = qfalse; return; } - sys_con.widthInChars = width; + sys_con.widthInChars = width; // figure out input line width width--; @@ -229,82 +157,82 @@ void Sys_RunConsole( void ) { Sys_HideInput(); IF_Init( &sys_con.inputLine, width, width ); Sys_ShowInput(); - continue; - } - if( recs[i].EventType != KEY_EVENT ) { - continue; - } - - if( !recs[i].Event.KeyEvent.bKeyDown ) { - continue; - } - - switch( recs[i].Event.KeyEvent.wVirtualKeyCode ) { - case VK_UP: - Sys_HideInput(); - Prompt_HistoryUp( &sys_con ); - Sys_ShowInput(); - break; - case VK_DOWN: - Sys_HideInput(); - Prompt_HistoryDown( &sys_con ); - Sys_ShowInput(); - break; - case VK_RETURN: - Sys_HideInput(); - s = Prompt_Action( &sys_con ); - if( s ) { - if( *s == '\\' || *s == '/' ) { - s++; - } - Sys_Printf( "]%s\n", s ); + continue; + } + if( recs[i].EventType != KEY_EVENT ) { + continue; + } + + if( !recs[i].Event.KeyEvent.bKeyDown ) { + continue; + } + + switch( recs[i].Event.KeyEvent.wVirtualKeyCode ) { + case VK_UP: + Sys_HideInput(); + Prompt_HistoryUp( &sys_con ); + Sys_ShowInput(); + break; + case VK_DOWN: + Sys_HideInput(); + Prompt_HistoryDown( &sys_con ); + Sys_ShowInput(); + break; + case VK_RETURN: + Sys_HideInput(); + s = Prompt_Action( &sys_con ); + if( s ) { + if( *s == '\\' || *s == '/' ) { + s++; + } + Sys_Printf( "]%s\n", s ); Cbuf_AddText( s ); Cbuf_AddText( "\n" ); - } else { - WriteFile( houtput, "\n", 2, &dummy, NULL ); - } - Sys_ShowInput(); - break; - case VK_BACK: - if( f->cursorPos ) { - f->text[--f->cursorPos] = 0; - WriteFile( houtput, "\b \b", 3, &dummy, NULL ); - } - break; - case VK_TAB: - Sys_HideInput(); - Prompt_CompleteCommand( &sys_con, qfalse ); + } else { + WriteFile( houtput, "\n", 2, &dummy, NULL ); + } + Sys_ShowInput(); + break; + case VK_BACK: + if( f->cursorPos ) { + f->text[--f->cursorPos] = 0; + WriteFile( houtput, "\b \b", 3, &dummy, NULL ); + } + break; + case VK_TAB: + Sys_HideInput(); + Prompt_CompleteCommand( &sys_con, qfalse ); f->cursorPos = strlen( f->text ); - Sys_ShowInput(); - break; - default: - ch = recs[i].Event.KeyEvent.uChar.AsciiChar; - if( ch < 32 ) { - break; - } - if( f->cursorPos < f->maxChars - 1 ) { - WriteFile( houtput, &ch, 1, &dummy, NULL ); - f->text[f->cursorPos] = ch; - f->text[++f->cursorPos] = 0; - } - break; - } - } - } + Sys_ShowInput(); + break; + default: + ch = recs[i].Event.KeyEvent.uChar.AsciiChar; + if( ch < 32 ) { + break; + } + if( f->cursorPos < f->maxChars - 1 ) { + WriteFile( houtput, &ch, 1, &dummy, NULL ); + f->text[f->cursorPos] = ch; + f->text[++f->cursorPos] = 0; + } + break; + } + } + } } -#define FOREGROUND_BLACK 0 -#define FOREGROUND_WHITE (FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED) +#define FOREGROUND_BLACK 0 +#define FOREGROUND_WHITE (FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED) static const WORD textColors[8] = { - FOREGROUND_BLACK, - FOREGROUND_RED, - FOREGROUND_GREEN, - FOREGROUND_RED|FOREGROUND_GREEN, - FOREGROUND_BLUE, - FOREGROUND_BLUE|FOREGROUND_GREEN, - FOREGROUND_RED|FOREGROUND_BLUE, - FOREGROUND_WHITE + FOREGROUND_BLACK, + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_RED|FOREGROUND_GREEN, + FOREGROUND_BLUE, + FOREGROUND_BLUE|FOREGROUND_GREEN, + FOREGROUND_RED|FOREGROUND_BLUE, + FOREGROUND_WHITE }; /* @@ -315,129 +243,129 @@ Print text to the dedicated console ================ */ void Sys_ConsoleOutput( const char *string ) { - DWORD dummy; - char text[MAXPRINTMSG]; - char *maxp, *p; - size_t length; - WORD attr, w; - int c; - - if( houtput == INVALID_HANDLE_VALUE ) { - return; - } - - if( !gotConsole ) { - p = text; - maxp = text + sizeof( text ) - 1; - while( *string ) { - if( Q_IsColorString( string ) ) { - string += 2; - continue; - } - *p++ = *string++ & 127; - if( p == maxp ) { - break; - } - } - - *p = 0; - - length = p - text; - WriteFile( houtput, text, length, &dummy, NULL ); - return; - } - - Sys_HideInput(); - - attr = sbinfo.wAttributes & ~FOREGROUND_WHITE; - - while( *string ) { - if( Q_IsColorString( string ) ) { - c = string[1]; - string += 2; - if( c == COLOR_ALT ) { - w = attr | FOREGROUND_GREEN; - } else if( c == COLOR_RESET ) { - w = sbinfo.wAttributes; - } else { - w = attr | textColors[ ColorIndex( c ) ]; - } - SetConsoleTextAttribute( houtput, w ); - continue; - } - - p = text; - maxp = text + sizeof( text ) - 1; - do { - *p++ = *string++ & 127; - if( p == maxp ) { - break; - } - } while( *string && !Q_IsColorString( string ) ); - - *p = 0; - - length = p - text; - WriteFile( houtput, text, length, &dummy, NULL ); - } - - SetConsoleTextAttribute( houtput, sbinfo.wAttributes ); - - Sys_ShowInput(); + DWORD dummy; + char text[MAXPRINTMSG]; + char *maxp, *p; + size_t length; + WORD attr, w; + int c; + + if( houtput == INVALID_HANDLE_VALUE ) { + return; + } + + if( !gotConsole ) { + p = text; + maxp = text + sizeof( text ) - 1; + while( *string ) { + if( Q_IsColorString( string ) ) { + string += 2; + continue; + } + *p++ = *string++ & 127; + if( p == maxp ) { + break; + } + } + + *p = 0; + + length = p - text; + WriteFile( houtput, text, length, &dummy, NULL ); + return; + } + + Sys_HideInput(); + + attr = sbinfo.wAttributes & ~FOREGROUND_WHITE; + + while( *string ) { + if( Q_IsColorString( string ) ) { + c = string[1]; + string += 2; + if( c == COLOR_ALT ) { + w = attr | FOREGROUND_GREEN; + } else if( c == COLOR_RESET ) { + w = sbinfo.wAttributes; + } else { + w = attr | textColors[ ColorIndex( c ) ]; + } + SetConsoleTextAttribute( houtput, w ); + continue; + } + + p = text; + maxp = text + sizeof( text ) - 1; + do { + *p++ = *string++ & 127; + if( p == maxp ) { + break; + } + } while( *string && !Q_IsColorString( string ) ); + + *p = 0; + + length = p - text; + WriteFile( houtput, text, length, &dummy, NULL ); + } + + SetConsoleTextAttribute( houtput, sbinfo.wAttributes ); + + Sys_ShowInput(); } void Sys_SetConsoleTitle( const char *title ) { - if( gotConsole ) { + if( gotConsole ) { SetConsoleTitle( title ); } } static BOOL WINAPI Sys_ConsoleCtrlHandler( DWORD dwCtrlType ) { - if( errorEntered ) { - exit( 1 ); - } - // 32 bit writes are guranteed to be atomic - shouldExit = qtrue; - return TRUE; + if( errorEntered ) { + exit( 1 ); + } + // 32 bit writes are guranteed to be atomic + shouldExit = qtrue; + return TRUE; } static void Sys_ConsoleInit( void ) { - DWORD mode; + DWORD mode; size_t width; #if USE_CLIENT - if( !AllocConsole() ) { - Com_EPrintf( "Couldn't create system console.\n" ); - return; - } + if( !AllocConsole() ) { + Com_EPrintf( "Couldn't create system console.\n" ); + return; + } #else - if( statusHandle ) { - return; - } + if( statusHandle ) { + return; + } #endif - hinput = GetStdHandle( STD_INPUT_HANDLE ); - houtput = GetStdHandle( STD_OUTPUT_HANDLE ); - if( !GetConsoleScreenBufferInfo( houtput, &sbinfo ) ) { - Com_EPrintf( "Couldn't get console buffer info.\n" ); - return; - } + hinput = GetStdHandle( STD_INPUT_HANDLE ); + houtput = GetStdHandle( STD_OUTPUT_HANDLE ); + if( !GetConsoleScreenBufferInfo( houtput, &sbinfo ) ) { + Com_EPrintf( "Couldn't get console buffer info.\n" ); + return; + } // determine terminal width width = sbinfo.dwSize.X; if( !width ) { - Com_EPrintf( "Invalid console buffer width.\n" ); + Com_EPrintf( "Invalid console buffer width.\n" ); return; } - sys_con.widthInChars = width; - sys_con.printf = Sys_Printf; - gotConsole = qtrue; + sys_con.widthInChars = width; + sys_con.printf = Sys_Printf; + gotConsole = qtrue; - SetConsoleTitle( APPLICATION " console" ); - SetConsoleCtrlHandler( Sys_ConsoleCtrlHandler, TRUE ); - GetConsoleMode( hinput, &mode ); - mode |= ENABLE_WINDOW_INPUT; - SetConsoleMode( hinput, mode ); + SetConsoleTitle( APPLICATION " console" ); + SetConsoleCtrlHandler( Sys_ConsoleCtrlHandler, TRUE ); + GetConsoleMode( hinput, &mode ); + mode |= ENABLE_WINDOW_INPUT; + SetConsoleMode( hinput, mode ); // figure out input line width width--; @@ -446,8 +374,8 @@ static void Sys_ConsoleInit( void ) { } IF_Init( &sys_con.inputLine, width, width ); - Com_DPrintf( "System console initialized (%d cols, %d rows).\n", - sbinfo.dwSize.X, sbinfo.dwSize.Y ); + Com_DPrintf( "System console initialized (%d cols, %d rows).\n", + sbinfo.dwSize.X, sbinfo.dwSize.Y ); } /* @@ -461,132 +389,132 @@ SERVICE CONTROL #if !USE_CLIENT static void Sys_InstallService_f( void ) { - char servicePath[256]; - char serviceName[1024]; - SC_HANDLE scm, service; - DWORD error, length; - char *commandline; - - if( Cmd_Argc() < 3 ) { - Com_Printf( "Usage: %s <servicename> <+command> [...]\n" - "Example: %s test +set net_port 27910 +map q2dm1\n", - Cmd_Argv( 0 ), Cmd_Argv( 0 ) ); - return; - } - - scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS ); - if( !scm ) { - error = GetLastError(); - if( error == ERROR_ACCESS_DENIED ) { - Com_Printf( "Insufficient privileges for opening Service Control Manager.\n" ); - } else { - Com_EPrintf( "%#lx opening Service Control Manager.\n", error ); - } - return; - } - - Q_concat( serviceName, sizeof( serviceName ), "Q2PRO - ", Cmd_Argv( 1 ), NULL ); - - length = GetModuleFileName( NULL, servicePath, MAX_PATH ); - if( !length ) { - error = GetLastError(); - Com_EPrintf( "%#lx getting module file name.\n", error ); - goto fail; - } - commandline = Cmd_RawArgsFrom( 2 ); - if( length + strlen( commandline ) + 10 > sizeof( servicePath ) - 1 ) { - Com_Printf( "Oversize service command line.\n" ); - goto fail; - } - strcpy( servicePath + length, " -service " ); - strcpy( servicePath + length + 10, commandline ); - - service = CreateService( - scm, - serviceName, - serviceName, - SERVICE_START, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_IGNORE, - servicePath, - NULL, - NULL, - NULL, - NULL, - NULL ); - - if( !service ) { - error = GetLastError(); - if( error == ERROR_SERVICE_EXISTS || error == ERROR_DUPLICATE_SERVICE_NAME ) { - Com_Printf( "Service already exists.\n" ); - } else { - Com_EPrintf( "%#lx creating service.\n", error ); - } - goto fail; - } - - Com_Printf( "Service created successfully.\n" ); - - CloseServiceHandle( service ); + char servicePath[256]; + char serviceName[1024]; + SC_HANDLE scm, service; + DWORD error, length; + char *commandline; + + if( Cmd_Argc() < 3 ) { + Com_Printf( "Usage: %s <servicename> <+command> [...]\n" + "Example: %s test +set net_port 27910 +map q2dm1\n", + Cmd_Argv( 0 ), Cmd_Argv( 0 ) ); + return; + } + + scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS ); + if( !scm ) { + error = GetLastError(); + if( error == ERROR_ACCESS_DENIED ) { + Com_Printf( "Insufficient privileges for opening Service Control Manager.\n" ); + } else { + Com_EPrintf( "%#lx opening Service Control Manager.\n", error ); + } + return; + } + + Q_concat( serviceName, sizeof( serviceName ), "Q2PRO - ", Cmd_Argv( 1 ), NULL ); + + length = GetModuleFileName( NULL, servicePath, MAX_PATH ); + if( !length ) { + error = GetLastError(); + Com_EPrintf( "%#lx getting module file name.\n", error ); + goto fail; + } + commandline = Cmd_RawArgsFrom( 2 ); + if( length + strlen( commandline ) + 10 > sizeof( servicePath ) - 1 ) { + Com_Printf( "Oversize service command line.\n" ); + goto fail; + } + strcpy( servicePath + length, " -service " ); + strcpy( servicePath + length + 10, commandline ); + + service = CreateService( + scm, + serviceName, + serviceName, + SERVICE_START, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_IGNORE, + servicePath, + NULL, + NULL, + NULL, + NULL, + NULL ); + + if( !service ) { + error = GetLastError(); + if( error == ERROR_SERVICE_EXISTS || error == ERROR_DUPLICATE_SERVICE_NAME ) { + Com_Printf( "Service already exists.\n" ); + } else { + Com_EPrintf( "%#lx creating service.\n", error ); + } + goto fail; + } + + Com_Printf( "Service created successfully.\n" ); + + CloseServiceHandle( service ); fail: - CloseServiceHandle( scm ); + CloseServiceHandle( scm ); } static void Sys_DeleteService_f( void ) { - char serviceName[256]; - SC_HANDLE scm, service; - DWORD error; - - if( Cmd_Argc() < 2 ) { - Com_Printf( "Usage: %s <servicename>\n", Cmd_Argv( 0 ) ); - return; - } - - scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS ); - if( !scm ) { - error = GetLastError(); - if( error == ERROR_ACCESS_DENIED ) { - Com_Printf( "Insufficient privileges for opening Service Control Manager.\n" ); - } else { - Com_EPrintf( "%#lx opening Service Control Manager.\n", error ); - } - return; - } - - Q_concat( serviceName, sizeof( serviceName ), "Q2PRO - ", Cmd_Argv( 1 ), NULL ); - - service = OpenService( - scm, - serviceName, - DELETE ); - - if( !service ) { - error = GetLastError(); - if( error == ERROR_SERVICE_DOES_NOT_EXIST ) { - Com_Printf( "Service doesn't exist.\n" ); - } else { - Com_EPrintf( "%#lx opening service.\n", error ); - } - goto fail; - } - - if( !DeleteService( service ) ) { - error = GetLastError(); - if( error == ERROR_SERVICE_MARKED_FOR_DELETE ) { - Com_Printf( "Service has already been marked for deletion.\n" ); - } else { - Com_EPrintf( "%#lx deleting service.\n", error ); - } - } else { - Com_Printf( "Service deleted successfully.\n" ); - } - - CloseServiceHandle( service ); + char serviceName[256]; + SC_HANDLE scm, service; + DWORD error; + + if( Cmd_Argc() < 2 ) { + Com_Printf( "Usage: %s <servicename>\n", Cmd_Argv( 0 ) ); + return; + } + + scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS ); + if( !scm ) { + error = GetLastError(); + if( error == ERROR_ACCESS_DENIED ) { + Com_Printf( "Insufficient privileges for opening Service Control Manager.\n" ); + } else { + Com_EPrintf( "%#lx opening Service Control Manager.\n", error ); + } + return; + } + + Q_concat( serviceName, sizeof( serviceName ), "Q2PRO - ", Cmd_Argv( 1 ), NULL ); + + service = OpenService( + scm, + serviceName, + DELETE ); + + if( !service ) { + error = GetLastError(); + if( error == ERROR_SERVICE_DOES_NOT_EXIST ) { + Com_Printf( "Service doesn't exist.\n" ); + } else { + Com_EPrintf( "%#lx opening service.\n", error ); + } + goto fail; + } + + if( !DeleteService( service ) ) { + error = GetLastError(); + if( error == ERROR_SERVICE_MARKED_FOR_DELETE ) { + Com_Printf( "Service has already been marked for deletion.\n" ); + } else { + Com_EPrintf( "%#lx deleting service.\n", error ); + } + } else { + Com_Printf( "Service deleted successfully.\n" ); + } + + CloseServiceHandle( service ); fail: - CloseServiceHandle( scm ); + CloseServiceHandle( scm ); } #endif @@ -600,36 +528,36 @@ HUNK */ void Hunk_Begin( mempool_t *pool, size_t maxsize ) { - // reserve a huge chunk of memory, but don't commit any yet - pool->cursize = 0; - pool->maxsize = ( maxsize + 4095 ) & ~4095; - pool->base = VirtualAlloc( NULL, pool->maxsize, MEM_RESERVE, PAGE_NOACCESS ); - if( !pool->base ) { - Com_Error( ERR_FATAL, + // reserve a huge chunk of memory, but don't commit any yet + pool->cursize = 0; + pool->maxsize = ( maxsize + 4095 ) & ~4095; + pool->base = VirtualAlloc( NULL, pool->maxsize, MEM_RESERVE, PAGE_NOACCESS ); + if( !pool->base ) { + Com_Error( ERR_FATAL, "VirtualAlloc reserve %"PRIz" bytes failed. GetLastError() = %lu", - pool->maxsize, GetLastError() ); - } + pool->maxsize, GetLastError() ); + } } void *Hunk_Alloc( mempool_t *pool, size_t size ) { - void *buf; + void *buf; - // round to cacheline - size = ( size + 31 ) & ~ 31; + // round to cacheline + size = ( size + 31 ) & ~ 31; - pool->cursize += size; - if( pool->cursize > pool->maxsize ) - Com_Error( ERR_FATAL, "%s: couldn't allocate %"PRIz" bytes", __func__, size ); + pool->cursize += size; + if( pool->cursize > pool->maxsize ) + Com_Error( ERR_FATAL, "%s: couldn't allocate %"PRIz" bytes", __func__, size ); - // commit pages as needed - buf = VirtualAlloc( pool->base, pool->cursize, MEM_COMMIT, PAGE_READWRITE ); - if( !buf ) { - Com_Error( ERR_FATAL, + // commit pages as needed + buf = VirtualAlloc( pool->base, pool->cursize, MEM_COMMIT, PAGE_READWRITE ); + if( !buf ) { + Com_Error( ERR_FATAL, "VirtualAlloc commit %"PRIz" bytes failed. GetLastError() = %lu", - pool->cursize, GetLastError() ); - } + pool->cursize, GetLastError() ); + } - return ( byte * )pool->base + pool->cursize - size; + return ( byte * )pool->base + pool->cursize - size; } void Hunk_End( mempool_t *pool ) { @@ -638,14 +566,14 @@ void Hunk_End( mempool_t *pool ) { } void Hunk_Free( mempool_t *pool ) { - if( pool->base ) { - if( !VirtualFree( pool->base, 0, MEM_RELEASE ) ) { - Com_Error( ERR_FATAL, "VirtualFree failed. GetLastError() = %lu", - GetLastError() ); - } - } - - memset( pool, 0, sizeof( *pool ) ); + if( pool->base ) { + if( !VirtualFree( pool->base, 0, MEM_RELEASE ) ) { + Com_Error( ERR_FATAL, "VirtualFree failed. GetLastError() = %lu", + GetLastError() ); + } + } + + memset( pool, 0, sizeof( *pool ) ); } /* @@ -656,50 +584,80 @@ MISC =============================================================================== */ -static inline time_t Sys_FileTimeToUnixTime( FILETIME *f ) { - ULARGE_INTEGER u = *( ULARGE_INTEGER * )f; - return ( time_t )( ( u.QuadPart - 116444736000000000ULL ) / 10000000 ); -} +/* +================ +Sys_Printf +================ +*/ +void Sys_Printf( const char *fmt, ... ) { + va_list argptr; + char msg[MAXPRINTMSG]; -unsigned Sys_Milliseconds( void ) { - return timeGetTime(); -} + va_start( argptr, fmt ); + Q_vsnprintf( msg, sizeof( msg ), fmt, argptr ); + va_end( argptr ); -void Sys_AddDefaultConfig( void ) { + Sys_ConsoleOutput( msg ); } /* ================ -Sys_GetPathInfo +Sys_Error ================ */ -qboolean Sys_GetPathInfo( const char *path, fsFileInfo_t *info ) { - WIN32_FILE_ATTRIBUTE_DATA data; +void Sys_Error( const char *error, ... ) { + va_list argptr; + char text[MAXPRINTMSG]; + + va_start( argptr, error ); + Q_vsnprintf( text, sizeof( text ), error, argptr ); + va_end( argptr ); - if( !GetFileAttributesExA( path, GetFileExInfoStandard, &data ) ) { - return qfalse; - } + errorEntered = qtrue; - if( info ) { - info->size = data.nFileSizeLow; - info->ctime = Sys_FileTimeToUnixTime( &data.ftCreationTime ); - info->mtime = Sys_FileTimeToUnixTime( &data.ftLastWriteTime ); - } + Sys_Printf( S_COLOR_RED "********************\n" + "FATAL: %s\n" + "********************\n", text ); +#if !USE_CLIENT + if( !statusHandle ) +#endif + { + if( gotConsole ) { + Sleep( INFINITE ); + } + MessageBoxA( NULL, text, APPLICATION " Fatal Error", MB_ICONERROR | MB_OK ); + } - return qtrue; + exit( 1 ); } -qboolean Sys_GetFileInfo( FILE *fp, fsFileInfo_t *info ) { - int pos; +/* +================ +Sys_Quit +================ +*/ +void Sys_Quit( void ) { + timeEndPeriod( 1 ); - pos = ftell( fp ); - fseek( fp, 0, SEEK_END ); - info->size = ftell( fp ); - info->ctime = 0; - info->mtime = 0; - fseek( fp, pos, SEEK_SET ); +#if USE_CLIENT + if( dedicated && dedicated->integer ) { + FreeConsole(); + } +#else + if( !statusHandle ) +#endif + exit( 0 ); +} - return qtrue; +void Sys_DebugBreak( void ) { + DebugBreak(); +} + +unsigned Sys_Milliseconds( void ) { + return timeGetTime(); +} + +void Sys_AddDefaultConfig( void ) { } void Sys_FixFPCW( void ) { @@ -716,49 +674,49 @@ Sys_Init ================ */ void Sys_Init( void ) { - OSVERSIONINFO vinfo; - - timeBeginPeriod( 1 ); - - vinfo.dwOSVersionInfoSize = sizeof( vinfo ); - - if( !GetVersionEx( &vinfo ) ) { - Sys_Error( "Couldn't get OS info" ); - } - - iswinnt = qtrue; - if( vinfo.dwMajorVersion < 4 ) { - Sys_Error( APPLICATION " requires windows version 4 or greater" ); - } - if( vinfo.dwPlatformId == VER_PLATFORM_WIN32s ) { - Sys_Error( APPLICATION " doesn't run on Win32s" ); - } else if( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if( vinfo.dwMinorVersion == 0 ) { - Sys_Error( APPLICATION " doesn't run on Win95" ); - } - iswinnt = qfalse; - } - - // basedir <path> - // allows the game to run from outside the data tree - sys_basedir = Cvar_Get( "basedir", currentDirectory, CVAR_NOSET ); - sys_libdir = Cvar_Get( "libdir", currentDirectory, CVAR_NOSET ); + OSVERSIONINFO vinfo; + + timeBeginPeriod( 1 ); + + vinfo.dwOSVersionInfoSize = sizeof( vinfo ); + + if( !GetVersionEx( &vinfo ) ) { + Sys_Error( "Couldn't get OS info" ); + } + + iswinnt = qtrue; + if( vinfo.dwMajorVersion < 4 ) { + Sys_Error( APPLICATION " requires windows version 4 or greater" ); + } + if( vinfo.dwPlatformId == VER_PLATFORM_WIN32s ) { + Sys_Error( APPLICATION " doesn't run on Win32s" ); + } else if( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { + if( vinfo.dwMinorVersion == 0 ) { + Sys_Error( APPLICATION " doesn't run on Win95" ); + } + iswinnt = qfalse; + } + + // basedir <path> + // allows the game to run from outside the data tree + sys_basedir = Cvar_Get( "basedir", currentDirectory, CVAR_NOSET ); + sys_libdir = Cvar_Get( "libdir", currentDirectory, CVAR_NOSET ); - // homedir <path> - // specifies per-user writable directory for demos, screenshots, etc - sys_homedir = Cvar_Get( "homedir", "", CVAR_NOSET ); + // homedir <path> + // specifies per-user writable directory for demos, screenshots, etc + sys_homedir = Cvar_Get( "homedir", "", CVAR_NOSET ); - sys_viewlog = Cvar_Get( "sys_viewlog", "0", CVAR_NOSET ); + sys_viewlog = Cvar_Get( "sys_viewlog", "0", CVAR_NOSET ); #if !USE_CLIENT - Cmd_AddCommand( "installservice", Sys_InstallService_f ); - Cmd_AddCommand( "deleteservice", Sys_DeleteService_f ); + Cmd_AddCommand( "installservice", Sys_InstallService_f ); + Cmd_AddCommand( "deleteservice", Sys_DeleteService_f ); #endif - houtput = GetStdHandle( STD_OUTPUT_HANDLE ); - if( dedicated->integer || sys_viewlog->integer ) { - Sys_ConsoleInit(); - } + houtput = GetStdHandle( STD_OUTPUT_HANDLE ); + if( dedicated->integer || sys_viewlog->integer ) { + Sys_ConsoleInit(); + } } /* @@ -785,31 +743,78 @@ void *Sys_LoadLibrary( const char *path, const char *sym, void **handle ) { *handle = NULL; module = LoadLibraryA( path ); - if( !module ) { - Com_DPrintf( "%s failed: LoadLibrary returned %lu on %s\n", + if( !module ) { + Com_DPrintf( "%s failed: LoadLibrary returned %lu on %s\n", __func__, GetLastError(), path ); - return NULL; - } + return NULL; + } - entry = GetProcAddress( module, sym ); - if( !entry ) { - Com_DPrintf( "%s failed: GetProcAddress returned %lu on %s\n", + entry = GetProcAddress( module, sym ); + if( !entry ) { + Com_DPrintf( "%s failed: GetProcAddress returned %lu on %s\n", __func__, GetLastError(), path ); - FreeLibrary( module ); - return NULL; - } + FreeLibrary( module ); + return NULL; + } *handle = module; - Com_DPrintf( "%s succeeded: %s\n", __func__, path ); + Com_DPrintf( "%s succeeded: %s\n", __func__, path ); - return entry; + return entry; } void *Sys_GetProcAddress( void *handle, const char *sym ) { - return GetProcAddress( handle, sym ); + return GetProcAddress( handle, sym ); +} + +/* +======================================================================== + +FILESYSTEM + +======================================================================== +*/ + +static inline time_t file_time_to_unix( FILETIME *f ) { + ULARGE_INTEGER u = *( ULARGE_INTEGER * )f; + return ( time_t )( ( u.QuadPart - 116444736000000000ULL ) / 10000000 ); +} + +/* +================ +Sys_GetPathInfo +================ +*/ +qboolean Sys_GetPathInfo( const char *path, fsFileInfo_t *info ) { + WIN32_FILE_ATTRIBUTE_DATA data; + + if( !GetFileAttributesExA( path, GetFileExInfoStandard, &data ) ) { + return qfalse; + } + + if( info ) { + info->size = data.nFileSizeLow; + info->ctime = file_time_to_unix( &data.ftCreationTime ); + info->mtime = file_time_to_unix( &data.ftLastWriteTime ); + } + + return qtrue; } -//======================================================================= + +qboolean Sys_GetFileInfo( FILE *fp, fsFileInfo_t *info ) { + int pos; + + pos = ftell( fp ); + fseek( fp, 0, SEEK_END ); + info->size = ftell( fp ); + info->ctime = 0; + info->mtime = 0; + fseek( fp, pos, SEEK_SET ); + + return qtrue; +} + /* ================= @@ -819,68 +824,68 @@ Sys_ListFilteredFiles static void Sys_ListFilteredFiles( void **listedFiles, int *count, const char *path, - const char *filter, + const char *filter, int flags, size_t length ) { - WIN32_FIND_DATAA findInfo; - HANDLE findHandle; - char findPath[MAX_OSPATH]; - char dirPath[MAX_OSPATH]; - char *name; - - if( *count >= MAX_LISTED_FILES ) { - return; - } - - Q_concat( findPath, sizeof( findPath ), path, "\\*", NULL ); - - findHandle = FindFirstFileA( findPath, &findInfo ); - if( findHandle == INVALID_HANDLE_VALUE ) { - return; - } - - do { - if( !strcmp( findInfo.cFileName, "." ) || !strcmp( findInfo.cFileName, ".." ) ) { - continue; - } - - if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { - Q_concat( dirPath, sizeof( dirPath ), path, "\\", findInfo.cFileName, NULL ); - Sys_ListFilteredFiles( listedFiles, count, dirPath, filter, flags, length ); - } - - if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) { - if( !( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { - continue; - } - } else if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_NO ) { - if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { - continue; - } - } - - Q_concat( dirPath, sizeof( dirPath ), path, "\\", findInfo.cFileName, NULL ); - if( !FS_WildCmp( filter, dirPath + length ) ) { - continue; - } - - name = ( flags & FS_SEARCH_SAVEPATH ) ? dirPath + length : findInfo.cFileName; + WIN32_FIND_DATAA findInfo; + HANDLE findHandle; + char findPath[MAX_OSPATH]; + char dirPath[MAX_OSPATH]; + char *name; + + if( *count >= MAX_LISTED_FILES ) { + return; + } + + Q_concat( findPath, sizeof( findPath ), path, "\\*", NULL ); + + findHandle = FindFirstFileA( findPath, &findInfo ); + if( findHandle == INVALID_HANDLE_VALUE ) { + return; + } + + do { + if( !strcmp( findInfo.cFileName, "." ) || !strcmp( findInfo.cFileName, ".." ) ) { + continue; + } + + if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { + Q_concat( dirPath, sizeof( dirPath ), path, "\\", findInfo.cFileName, NULL ); + Sys_ListFilteredFiles( listedFiles, count, dirPath, filter, flags, length ); + } + + if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) { + if( !( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { + continue; + } + } else if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_NO ) { + if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { + continue; + } + } + + Q_concat( dirPath, sizeof( dirPath ), path, "\\", findInfo.cFileName, NULL ); + if( !FS_WildCmp( filter, dirPath + length ) ) { + continue; + } + + name = ( flags & FS_SEARCH_SAVEPATH ) ? dirPath + length : findInfo.cFileName; // reformat it back to quake filesystem style FS_ReplaceSeparators( name, '/' ); - if( flags & FS_SEARCH_EXTRAINFO ) { - time_t ctime = Sys_FileTimeToUnixTime( &findInfo.ftCreationTime ); - time_t mtime = Sys_FileTimeToUnixTime( &findInfo.ftLastWriteTime ); - listedFiles[( *count )++] = FS_CopyInfo( name, findInfo.nFileSizeLow, ctime, mtime ); - } else { - listedFiles[( *count )++] = FS_CopyString( name ); - } + if( flags & FS_SEARCH_EXTRAINFO ) { + time_t ctime = file_time_to_unix( &findInfo.ftCreationTime ); + time_t mtime = file_time_to_unix( &findInfo.ftLastWriteTime ); + listedFiles[( *count )++] = FS_CopyInfo( name, findInfo.nFileSizeLow, ctime, mtime ); + } else { + listedFiles[( *count )++] = FS_CopyString( name ); + } - } while( *count < MAX_LISTED_FILES && FindNextFileA( findHandle, &findInfo ) != FALSE ); + } while( *count < MAX_LISTED_FILES && FindNextFileA( findHandle, &findInfo ) != FALSE ); - FindClose( findHandle ); + FindClose( findHandle ); } /* @@ -894,577 +899,163 @@ void **Sys_ListFiles( const char *rawPath, size_t length, int *numFiles ) { - WIN32_FIND_DATAA findInfo; - HANDLE findHandle; - char path[MAX_OSPATH]; - char findPath[MAX_OSPATH]; - void *listedFiles[MAX_LISTED_FILES]; - int count; - char *name; - - count = 0; - - if( numFiles ) { - *numFiles = 0; - } - - Q_strlcpy( path, rawPath, sizeof( path ) ); - FS_ReplaceSeparators( path, '\\' ); - - if( flags & FS_SEARCH_BYFILTER ) { - Q_strlcpy( findPath, extension, sizeof( findPath ) ); - FS_ReplaceSeparators( findPath, '\\' ); - Sys_ListFilteredFiles( listedFiles, &count, path, findPath, flags, length ); - } else { - if( !extension || strchr( extension, ';' ) ) { - Q_concat( findPath, sizeof( findPath ), path, "\\*", NULL ); - } else { - if( *extension == '.' ) { - extension++; - } - Q_concat( findPath, sizeof( findPath ), path, "\\*.", extension, NULL ); - extension = NULL; // do not check later - } - - findHandle = FindFirstFileA( findPath, &findInfo ); - if( findHandle == INVALID_HANDLE_VALUE ) { - return NULL; - } - - do { - if( !strcmp( findInfo.cFileName, "." ) || !strcmp( findInfo.cFileName, ".." ) ) { - continue; - } - - if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) { - if( !( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { - continue; - } - } else if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_NO ) { - if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { - continue; - } - } - - if( extension && !FS_ExtCmp( extension, findInfo.cFileName ) ) { - continue; - } - - name = ( flags & FS_SEARCH_SAVEPATH ) ? va( "%s\\%s", path, findInfo.cFileName ) : findInfo.cFileName; - - // reformat it back to quake filesystem style - FS_ReplaceSeparators( name, '/' ); - - if( flags & FS_SEARCH_EXTRAINFO ) { - time_t ctime = Sys_FileTimeToUnixTime( &findInfo.ftCreationTime ); - time_t mtime = Sys_FileTimeToUnixTime( &findInfo.ftLastWriteTime ); - listedFiles[count++] = FS_CopyInfo( name, findInfo.nFileSizeLow, ctime, mtime ); - } else { - listedFiles[count++] = FS_CopyString( name ); - } - } while( count < MAX_LISTED_FILES && FindNextFileA( findHandle, &findInfo ) != FALSE ); - - FindClose( findHandle ); - } - - if( !count ) { - return NULL; - } - - if( numFiles ) { - *numFiles = count; - } - - return FS_CopyList( listedFiles, count ); -} - -/* -================= -Sys_GetCurrentDirectory -================= -*/ -char *Sys_GetCurrentDirectory( void ) { - return currentDirectory; -} - -//======================================================================= - -#if ( USE_CLIENT ) && ( USE_ANTICHEAT & 1 ) + WIN32_FIND_DATAA findInfo; + HANDLE findHandle; + char path[MAX_OSPATH]; + char findPath[MAX_OSPATH]; + void *listedFiles[MAX_LISTED_FILES]; + int count; + char *name; + + count = 0; + + if( numFiles ) { + *numFiles = 0; + } -typedef PVOID (*FNINIT)( VOID ); + Q_strlcpy( path, rawPath, sizeof( path ) ); + FS_ReplaceSeparators( path, '\\' ); + + if( flags & FS_SEARCH_BYFILTER ) { + Q_strlcpy( findPath, extension, sizeof( findPath ) ); + FS_ReplaceSeparators( findPath, '\\' ); + Sys_ListFilteredFiles( listedFiles, &count, path, findPath, flags, length ); + } else { + if( !extension || strchr( extension, ';' ) ) { + Q_concat( findPath, sizeof( findPath ), path, "\\*", NULL ); + } else { + if( *extension == '.' ) { + extension++; + } + Q_concat( findPath, sizeof( findPath ), path, "\\*.", extension, NULL ); + extension = NULL; // do not check later + } + + findHandle = FindFirstFileA( findPath, &findInfo ); + if( findHandle == INVALID_HANDLE_VALUE ) { + return NULL; + } -PRIVATE PVOID anticheatApi; -PRIVATE FNINIT anticheatInit; -PRIVATE HMODULE anticheatHandle; + do { + if( !strcmp( findInfo.cFileName, "." ) || !strcmp( findInfo.cFileName, ".." ) ) { + continue; + } -// -// r1ch.net anticheat support -// -qboolean Sys_GetAntiCheatAPI( void ) { - qboolean updated = qfalse; + if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) { + if( !( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { + continue; + } + } else if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_NO ) { + if( findInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { + continue; + } + } - //already loaded, just reinit - if( anticheatInit ) { - anticheatApi = anticheatInit(); - if( !anticheatApi ) { - Com_Printf( S_COLOR_RED "Anticheat failed to reinitialize!\n" ); - FreeLibrary( anticheatHandle ); - anticheatHandle = NULL; - anticheatInit = NULL; - return qfalse; - } - return qtrue; - } - - //windows version check - if( !iswinnt ) { - Com_Printf( S_COLOR_YELLOW - "Anticheat requires Windows 2000/XP/2003.\n" ); - return qfalse; - } - -reInit: - anticheatHandle = LoadLibrary( "anticheat" ); - if( !anticheatHandle ) { - Com_Printf( S_COLOR_RED "Anticheat failed to load.\n" ); - return qfalse; - } + if( extension && !FS_ExtCmp( extension, findInfo.cFileName ) ) { + continue; + } - //this should never fail unless the anticheat.dll is bad - anticheatInit = ( FNINIT )GetProcAddress( - anticheatHandle, "Initialize" ); - if( !anticheatInit ) { - Com_Printf( S_COLOR_RED "Couldn't get API of anticheat.dll!\n" - "Please check you are using a valid " - "anticheat.dll from http://antiche.at/" ); - FreeLibrary( anticheatHandle ); - anticheatHandle = NULL; - return qfalse; + name = ( flags & FS_SEARCH_SAVEPATH ) ? va( "%s\\%s", path, findInfo.cFileName ) : findInfo.cFileName; + + // reformat it back to quake filesystem style + FS_ReplaceSeparators( name, '/' ); + + if( flags & FS_SEARCH_EXTRAINFO ) { + time_t ctime = file_time_to_unix( &findInfo.ftCreationTime ); + time_t mtime = file_time_to_unix( &findInfo.ftLastWriteTime ); + listedFiles[count++] = FS_CopyInfo( name, findInfo.nFileSizeLow, ctime, mtime ); + } else { + listedFiles[count++] = FS_CopyString( name ); + } + } while( count < MAX_LISTED_FILES && FindNextFileA( findHandle, &findInfo ) != FALSE ); + + FindClose( findHandle ); } - anticheatApi = anticheatInit(); - if( anticheatApi ) { - return qtrue; // succeeded + if( !count ) { + return NULL; } - FreeLibrary( anticheatHandle ); - anticheatHandle = NULL; - anticheatInit = NULL; - if( !updated ) { - updated = qtrue; - goto reInit; + if( numFiles ) { + *numFiles = count; } - Com_Printf( S_COLOR_RED "Anticheat failed to initialize.\n" ); - - return qfalse; -} - -#endif /* USE_ANTICHEAT */ - -#if USE_DBGHELP - -typedef DWORD (WINAPI *SETSYMOPTIONS)( DWORD ); -typedef BOOL (WINAPI *SYMGETMODULEINFO64)( HANDLE, DWORD64, PIMAGEHLP_MODULE64 ); -typedef BOOL (WINAPI *SYMINITIALIZE)( HANDLE, PSTR, BOOL ); -typedef BOOL (WINAPI *SYMCLEANUP)( HANDLE ); -typedef BOOL (WINAPI *ENUMERATELOADEDMODULES64)( HANDLE, PENUMLOADED_MODULES_CALLBACK64, PVOID ); -typedef BOOL (WINAPI *STACKWALK64)( DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, - PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, - PTRANSLATE_ADDRESS_ROUTINE64 ); -typedef BOOL (WINAPI *SYMFROMADDR)( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ); -typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS64)( HANDLE, DWORD64 ); -typedef DWORD64 (WINAPI *SYMGETMODULEBASE64)( HANDLE, DWORD64 ); - -typedef HINSTANCE (WINAPI *SHELLEXECUTE)( HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT ); - -PRIVATE SETSYMOPTIONS pSymSetOptions; -PRIVATE SYMGETMODULEINFO64 pSymGetModuleInfo64; -PRIVATE SYMINITIALIZE pSymInitialize; -PRIVATE SYMCLEANUP pSymCleanup; -PRIVATE ENUMERATELOADEDMODULES64 pEnumerateLoadedModules64; -PRIVATE STACKWALK64 pStackWalk64; -PRIVATE SYMFROMADDR pSymFromAddr; -PRIVATE SYMFUNCTIONTABLEACCESS64 pSymFunctionTableAccess64; -PRIVATE SYMGETMODULEBASE64 pSymGetModuleBase64; -PRIVATE SHELLEXECUTE pShellExecute; - -PRIVATE HANDLE processHandle, threadHandle; - -PRIVATE FILE *crashReport; - -PRIVATE CHAR moduleName[MAX_PATH]; - -PRIVATE BOOL CALLBACK EnumModulesCallback( - PTSTR ModuleName, - DWORD64 ModuleBase, - ULONG ModuleSize, - PVOID UserContext ) -{ - IMAGEHLP_MODULE64 moduleInfo; - DWORD64 pc = ( DWORD64 )UserContext; - BYTE buffer[4096]; - PBYTE data; - UINT numBytes; - VS_FIXEDFILEINFO *info; - char version[64]; - char *symbols; - - strcpy( version, "unknown" ); - if( GetFileVersionInfo( ModuleName, 0, sizeof( buffer ), buffer ) ) { - if( VerQueryValue( buffer, "\\", &data, &numBytes ) ) { - info = ( VS_FIXEDFILEINFO * )data; - sprintf( version, "%u.%u.%u.%u", - HIWORD( info->dwFileVersionMS ), - LOWORD( info->dwFileVersionMS ), - HIWORD( info->dwFileVersionLS ), - LOWORD( info->dwFileVersionLS ) ); - } - } - - symbols = "failed"; - moduleInfo.SizeOfStruct = sizeof( moduleInfo ); - if( pSymGetModuleInfo64( processHandle, ModuleBase, &moduleInfo ) ) { - ModuleName = moduleInfo.ModuleName; - switch( moduleInfo.SymType ) { - case SymCoff: symbols = "COFF"; break; - case SymExport: symbols = "export"; break; - case SymNone: symbols = "none"; break; - case SymPdb: symbols = "PDB"; break; - default: symbols = "unknown"; break; - } - } - - fprintf( crashReport, "%p %p %s (version %s, symbols %s) ", - ModuleBase, ModuleBase + ModuleSize, ModuleName, version, symbols ); - if( pc >= ModuleBase && pc < ModuleBase + ModuleSize ) { - strncpy( moduleName, ModuleName, sizeof( moduleName ) - 1 ); - moduleName[ sizeof( moduleName ) - 1 ] = 0; - fprintf( crashReport, "*\n" ); - } else { - fprintf( crashReport, "\n" ); - } - - return TRUE; + return FS_CopyList( listedFiles, count ); } -PRIVATE DWORD Sys_ExceptionHandler( DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo ) { - STACKFRAME64 stackFrame; - PCONTEXT context; - SYMBOL_INFO *symbol; - int count, ret, i, len; - DWORD64 offset; - BYTE buffer[sizeof( SYMBOL_INFO ) + 256 - 1]; - IMAGEHLP_MODULE64 moduleInfo; - char path[MAX_PATH]; - char execdir[MAX_PATH]; - char *p; - HMODULE helpModule, shellModule; - SYSTEMTIME systemTime; - static const char monthNames[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - OSVERSIONINFO vinfo; - -#if USE_CLIENT - Win_Shutdown(); -#endif - - ret = MessageBox( NULL, APPLICATION " has encountered an unhandled " - "exception and needs to be terminated.\n" - "Would you like to generate a crash report?", - "Unhandled Exception", - MB_ICONERROR | MB_YESNO -#if !USE_CLIENT - | MB_SERVICE_NOTIFICATION -#endif - ); - if( ret == IDNO ) { - return EXCEPTION_CONTINUE_SEARCH; - } - - helpModule = LoadLibrary( "dbghelp.dll" ); - if( !helpModule ) { - return EXCEPTION_CONTINUE_SEARCH; - } - -#define GPA( x, y ) \ - do { \ - p ## y = ( x )GetProcAddress( helpModule, #y ); \ - if( !p ## y ) { \ - return EXCEPTION_CONTINUE_SEARCH; \ - } \ - } while( 0 ) - - GPA( SETSYMOPTIONS, SymSetOptions ); - GPA( SYMGETMODULEINFO64, SymGetModuleInfo64 ); - GPA( SYMCLEANUP, SymCleanup ); - GPA( SYMINITIALIZE, SymInitialize ); - GPA( ENUMERATELOADEDMODULES64, EnumerateLoadedModules64 ); - GPA( STACKWALK64, StackWalk64 ); - GPA( SYMFROMADDR, SymFromAddr ); - GPA( SYMFUNCTIONTABLEACCESS64, SymFunctionTableAccess64 ); - GPA( SYMGETMODULEBASE64, SymGetModuleBase64 ); - - pSymSetOptions( SYMOPT_LOAD_ANYTHING|SYMOPT_DEBUG|SYMOPT_FAIL_CRITICAL_ERRORS ); - processHandle = GetCurrentProcess(); - threadHandle = GetCurrentThread(); - - GetModuleFileName( NULL, execdir, sizeof( execdir ) - 1 ); - execdir[sizeof( execdir ) - 1] = 0; - p = strrchr( execdir, '\\' ); - if( !p ) { - return EXCEPTION_CONTINUE_SEARCH; - } - - *p = 0; - len = p - execdir; - if( len + 24 >= MAX_PATH ) { - return EXCEPTION_CONTINUE_SEARCH; - } - - memcpy( path, execdir, len ); - memcpy( path + len, "\\Q2PRO_CrashReportXX.txt", 25 ); - for( i = 0; i < 100; i++ ) { - path[len+18] = '0' + i / 10; - path[len+19] = '0' + i % 10; - if( !Sys_GetPathInfo( path, NULL ) ) { - break; - } - } - crashReport = fopen( path, "w" ); - if( !crashReport ) { - return EXCEPTION_CONTINUE_SEARCH; - } - - pSymInitialize( processHandle, execdir, TRUE ); - - GetSystemTime( &systemTime ); - fprintf( crashReport, "Crash report generated %s %u %u, %02u:%02u:%02u UTC\n", - monthNames[(systemTime.wMonth - 1) % 12], systemTime.wDay, systemTime.wYear, - systemTime.wHour, systemTime.wMinute, systemTime.wSecond ); - fprintf( crashReport, "by " APPLICATION " " VERSION ", built " __DATE__", " __TIME__ "\n" ); - - vinfo.dwOSVersionInfoSize = sizeof( vinfo ); - if( GetVersionEx( &vinfo ) ) { - fprintf( crashReport, "\nWindows version: %u.%u (build %u) %s\n", - vinfo.dwMajorVersion, vinfo.dwMinorVersion, vinfo.dwBuildNumber, vinfo.szCSDVersion ); - } - - strcpy( moduleName, "unknown" ); - - context = exceptionInfo->ContextRecord; - - fprintf( crashReport, "\nLoaded modules:\n" ); - pEnumerateLoadedModules64( processHandle, EnumModulesCallback, -#ifdef _WIN64 - ( PVOID )context->Rip -#else - ( PVOID )context->Eip -#endif - ); - - fprintf( crashReport, "\nException information:\n" ); - fprintf( crashReport, "Code: %08x\n", exceptionCode ); - fprintf( crashReport, "Address: %p (%s)\n", -#ifdef _WIN64 - context->Rip, -#else - context->Eip, -#endif - moduleName ); - - fprintf( crashReport, "\nThread context:\n" ); -#ifdef _WIN64 - fprintf( crashReport, "RIP: %p RBP: %p RSP: %p\n", - context->Rip, context->Rbp, context->Rsp ); - fprintf( crashReport, "RAX: %p RBX: %p RCX: %p\n", - context->Rax, context->Rbx, context->Rcx ); - fprintf( crashReport, "RDX: %p RSI: %p RDI: %p\n", - context->Rdx, context->Rsi, context->Rdi ); -#else - fprintf( crashReport, "EIP: %p EBP: %p ESP: %p\n", - context->Eip, context->Ebp, context->Esp ); - fprintf( crashReport, "EAX: %p EBX: %p ECX: %p\n", - context->Eax, context->Ebx, context->Ecx ); - fprintf( crashReport, "EDX: %p ESI: %p EDI: %p\n", - context->Edx, context->Esi, context->Edi ); -#endif - - memset( &stackFrame, 0, sizeof( stackFrame ) ); -#ifdef _WIN64 - stackFrame.AddrPC.Offset = context->Rip; - stackFrame.AddrFrame.Offset = context->Rbp; - stackFrame.AddrStack.Offset = context->Rsp; -#else - stackFrame.AddrPC.Offset = context->Eip; - stackFrame.AddrFrame.Offset = context->Ebp; - stackFrame.AddrStack.Offset = context->Esp; -#endif - stackFrame.AddrPC.Mode = AddrModeFlat; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrStack.Mode = AddrModeFlat; - - fprintf( crashReport, "\nStack trace:\n" ); - count = 0; - symbol = ( SYMBOL_INFO * )buffer; - symbol->SizeOfStruct = sizeof( SYMBOL_INFO ); - symbol->MaxNameLen = 256; - while( pStackWalk64( -#ifdef _WIN64 - IMAGE_FILE_MACHINE_AMD64, -#else - IMAGE_FILE_MACHINE_I386, -#endif - processHandle, - threadHandle, - &stackFrame, - context, - NULL, - pSymFunctionTableAccess64, - pSymGetModuleBase64, - NULL ) ) - { - fprintf( crashReport, "%d: %p %p %p %p ", - count, - stackFrame.Params[0], - stackFrame.Params[1], - stackFrame.Params[2], - stackFrame.Params[3] ); - - moduleInfo.SizeOfStruct = sizeof( moduleInfo ); - if( pSymGetModuleInfo64( processHandle, stackFrame.AddrPC.Offset, &moduleInfo ) ) { - if( moduleInfo.SymType != SymNone && moduleInfo.SymType != SymExport && - pSymFromAddr( processHandle, stackFrame.AddrPC.Offset, &offset, symbol ) ) - { - fprintf( crashReport, "%s!%s+%#x\n", - moduleInfo.ModuleName, - symbol->Name, offset ); - } else { - fprintf( crashReport, "%s!%#x\n", - moduleInfo.ModuleName, - stackFrame.AddrPC.Offset ); - } - } else { - fprintf( crashReport, "%#x\n", - stackFrame.AddrPC.Offset ); - } - count++; - } - - fclose( crashReport ); - - shellModule = LoadLibrary( "shell32.dll" ); - if( shellModule ) { - pShellExecute = ( SHELLEXECUTE )GetProcAddress( shellModule, "ShellExecuteA" ); - if( pShellExecute ) { - pShellExecute( NULL, "open", path, NULL, execdir, SW_SHOW ); - } - } - - pSymCleanup( processHandle ); - - ExitProcess( 1 ); - return EXCEPTION_CONTINUE_SEARCH; +/* +================= +Sys_GetCurrentDirectory +================= +*/ +char *Sys_GetCurrentDirectory( void ) { + return currentDirectory; } -#if 0 -EXCEPTION_DISPOSITION _ExceptionHandler( - EXCEPTION_RECORD *ExceptionRecord, - void *EstablisherFrame, - CONTEXT *ContextRecord, - void *DispatcherContext ) -{ - return ExceptionContinueSearch; -} +/* +======================================================================== -#ifndef __GNUC__ -#define __try1( handler ) __asm { \ - __asm push handler \ - __asm push fs:[0] \ - __asm mov fs:0, esp \ -} -#define __except1 __asm { \ - __asm mov eax, [esp] \ - __asm mov fs:[0], eax \ - __asm add esp, 8 \ -} -#endif -#endif +MAIN -#endif /* USE_DBGHELP */ +======================================================================== +*/ #if ( _MSC_VER >= 1400 ) -static void msvcrt_sucks( const wchar_t *expr, const wchar_t *func, const wchar_t *file, unsigned int line, uintptr_t unused ) { +static void msvcrt_sucks( const wchar_t *expr, const wchar_t *func, + const wchar_t *file, unsigned int line, uintptr_t unused ) { } #endif static int Sys_Main( int argc, char **argv ) { -#if USE_CLIENT - if( !GetCurrentDirectory( sizeof( currentDirectory ) - 1, currentDirectory ) ) { - return 1; - } - currentDirectory[sizeof( currentDirectory ) - 1] = 0; -#else - if( !GetModuleFileName( NULL, currentDirectory, sizeof( currentDirectory ) - 1 ) ) { - return 1; - } - currentDirectory[sizeof( currentDirectory ) - 1] = 0; - { - char *p = strrchr( currentDirectory, '\\' ); - if( p ) { - *p = 0; - } - if( !SetCurrentDirectory( currentDirectory ) ) { - return 1; - } - } -#endif + char *p; + + // fix current directory to point to the basedir + if( !GetModuleFileName( NULL, currentDirectory, sizeof( currentDirectory ) - 1 ) ) { + return 1; + } + if( ( p = strrchr( currentDirectory, '\\' ) ) != NULL ) { + *p = 0; + } + if( !SetCurrentDirectory( currentDirectory ) ) { + return 1; + } #if USE_DBGHELP -#ifdef _MSC_VER - __try { -#else - __try1( Sys_ExceptionHandler ); + // install our exception handler + __try { #endif -#endif /* USE_DBGHELP */ #if ( _MSC_VER >= 1400 ) - // no, please, don't let strftime kill the whole fucking - // process just because it does not conform to C99 :(( - _set_invalid_parameter_handler( msvcrt_sucks ); + // work around strftime given invalid format string + // killing the whole fucking process :(( + _set_invalid_parameter_handler( msvcrt_sucks ); #endif - Qcommon_Init( argc, argv ); + Qcommon_Init( argc, argv ); - // main program loop - while( !shouldExit ) { - Qcommon_Frame(); - } + // main program loop + while( !shouldExit ) { + Qcommon_Frame(); + } - Com_Quit( NULL ); + Com_Quit( NULL ); #if USE_DBGHELP -#ifdef _MSC_VER - } __except( Sys_ExceptionHandler( GetExceptionCode(), GetExceptionInformation() ) ) { - return 1; - } -#else - __except1; + } __except( Sys_ExceptionHandler( GetExceptionCode(), GetExceptionInformation() ) ) { + return 1; + } #endif -#endif /* USE_DBGHELP */ - // may get here when our service stops + // may get here when our service stops return 0; } - - #if USE_CLIENT -#define MAX_LINE_TOKENS 128 +#define MAX_LINE_TOKENS 128 -static char *sys_argv[MAX_LINE_TOKENS]; -static int sys_argc; +static char *sys_argv[MAX_LINE_TOKENS]; +static int sys_argc; /* =============== @@ -1473,28 +1064,28 @@ Sys_ParseCommandLine =============== */ static void Sys_ParseCommandLine( char *line ) { - sys_argc = 1; + sys_argc = 1; sys_argv[0] = APPLICATION; - while( *line ) { - while( *line && *line <= 32 ) { + while( *line ) { + while( *line && *line <= 32 ) { line++; } if( *line == 0 ) { break; } - sys_argv[sys_argc++] = line; - while( *line > 32 ) { + sys_argv[sys_argc++] = line; + while( *line > 32 ) { line++; } if( *line == 0 ) { break; } - *line = 0; - if( sys_argc == MAX_LINE_TOKENS ) { - break; - } + *line = 0; + if( sys_argc == MAX_LINE_TOKENS ) { + break; + } line++; - } + } } /* @@ -1504,51 +1095,51 @@ WinMain ================== */ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { - // previous instances do not exist in Win32 - if( hPrevInstance ) { - return 1; - } - - hGlobalInstance = hInstance; - Sys_ParseCommandLine( lpCmdLine ); - return Sys_Main( sys_argc, sys_argv ); + // previous instances do not exist in Win32 + if( hPrevInstance ) { + return 1; + } + + hGlobalInstance = hInstance; + Sys_ParseCommandLine( lpCmdLine ); + return Sys_Main( sys_argc, sys_argv ); } #else // USE_CLIENT -static char **sys_argv; -static int sys_argc; +static char **sys_argv; +static int sys_argc; static VOID WINAPI ServiceHandler( DWORD fdwControl ) { - if( fdwControl == SERVICE_CONTROL_STOP ) { - shouldExit = qtrue; - } + if( fdwControl == SERVICE_CONTROL_STOP ) { + shouldExit = qtrue; + } } static VOID WINAPI ServiceMain( DWORD argc, LPTSTR *argv ) { - SERVICE_STATUS status; + SERVICE_STATUS status; - statusHandle = RegisterServiceCtrlHandler( APPLICATION, ServiceHandler ); - if( !statusHandle ) { - return; - } + statusHandle = RegisterServiceCtrlHandler( APPLICATION, ServiceHandler ); + if( !statusHandle ) { + return; + } - memset( &status, 0, sizeof( status ) ); - status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - status.dwCurrentState = SERVICE_RUNNING; - status.dwControlsAccepted = SERVICE_ACCEPT_STOP; - SetServiceStatus( statusHandle, &status ); + memset( &status, 0, sizeof( status ) ); + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + status.dwCurrentState = SERVICE_RUNNING; + status.dwControlsAccepted = SERVICE_ACCEPT_STOP; + SetServiceStatus( statusHandle, &status ); - Sys_Main( sys_argc, sys_argv ); + Sys_Main( sys_argc, sys_argv ); - status.dwCurrentState = SERVICE_STOPPED; - status.dwControlsAccepted = 0; - SetServiceStatus( statusHandle, &status ); + status.dwCurrentState = SERVICE_STOPPED; + status.dwControlsAccepted = 0; + SetServiceStatus( statusHandle, &status ); } static SERVICE_TABLE_ENTRY serviceTable[] = { - { APPLICATION, ServiceMain }, - { NULL, NULL } + { APPLICATION, ServiceMain }, + { NULL, NULL } }; /* @@ -1558,26 +1149,26 @@ main ================== */ int QDECL main( int argc, char **argv ) { - int i; - - hGlobalInstance = GetModuleHandle( NULL ); - - for( i = 1; i < argc; i++ ) { - if( !strcmp( argv[i], "-service" ) ) { - argv[i] = NULL; - sys_argc = argc; - sys_argv = argv; - if( StartServiceCtrlDispatcher( serviceTable ) ) { - return 0; - } - if( GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ) { - break; // fall back to normal server startup - } - return 1; - } - } - - return Sys_Main( argc, argv ); + int i; + + hGlobalInstance = GetModuleHandle( NULL ); + + for( i = 1; i < argc; i++ ) { + if( !strcmp( argv[i], "-service" ) ) { + argv[i] = NULL; + sys_argc = argc; + sys_argv = argv; + if( StartServiceCtrlDispatcher( serviceTable ) ) { + return 0; + } + if( GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ) { + break; // fall back to normal server startup + } + return 1; + } + } + + return Sys_Main( argc, argv ); } #endif // !USE_CLIENT diff --git a/source/win_ac.c b/source/win_ac.c new file mode 100644 index 0000000..02fb9d9 --- /dev/null +++ b/source/win_ac.c @@ -0,0 +1,92 @@ +/* +Copyright (C) 2006 r1ch.net + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// +// r1ch.net anticheat support +// + +#include "win_local.h" + +typedef PVOID (*FNINIT)( VOID ); + +PRIVATE PVOID anticheatApi; +PRIVATE FNINIT anticheatInit; +PRIVATE HMODULE anticheatHandle; + +qboolean Sys_GetAntiCheatAPI( void ) { + qboolean updated = qfalse; + + //already loaded, just reinit + if( anticheatInit ) { + anticheatApi = anticheatInit(); + if( !anticheatApi ) { + Com_Printf( S_COLOR_RED "Anticheat failed to reinitialize!\n" ); + FreeLibrary( anticheatHandle ); + anticheatHandle = NULL; + anticheatInit = NULL; + return qfalse; + } + return qtrue; + } + + //windows version check + if( !iswinnt ) { + Com_Printf( S_COLOR_YELLOW + "Anticheat requires Windows 2000/XP/2003.\n" ); + return qfalse; + } + +reInit: + anticheatHandle = LoadLibrary( "anticheat" ); + if( !anticheatHandle ) { + Com_Printf( S_COLOR_RED "Anticheat failed to load.\n" ); + return qfalse; + } + + //this should never fail unless the anticheat.dll is bad + anticheatInit = ( FNINIT )GetProcAddress( + anticheatHandle, "Initialize" ); + if( !anticheatInit ) { + Com_Printf( S_COLOR_RED "Couldn't get API of anticheat.dll!\n" + "Please check you are using a valid " + "anticheat.dll from http://antiche.at/" ); + FreeLibrary( anticheatHandle ); + anticheatHandle = NULL; + return qfalse; + } + + anticheatApi = anticheatInit(); + if( anticheatApi ) { + return qtrue; // succeeded + } + + FreeLibrary( anticheatHandle ); + anticheatHandle = NULL; + anticheatInit = NULL; + if( !updated ) { + updated = qtrue; + goto reInit; + } + + Com_Printf( S_COLOR_RED "Anticheat failed to initialize.\n" ); + + return qfalse; +} + diff --git a/source/win_dbg.c b/source/win_dbg.c new file mode 100644 index 0000000..8dad6df --- /dev/null +++ b/source/win_dbg.c @@ -0,0 +1,329 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "win_local.h" +#include <dbghelp.h> + +typedef DWORD (WINAPI *SETSYMOPTIONS)( DWORD ); +typedef BOOL (WINAPI *SYMGETMODULEINFO64)( HANDLE, DWORD64, + PIMAGEHLP_MODULE64 ); +typedef BOOL (WINAPI *SYMINITIALIZE)( HANDLE, PSTR, BOOL ); +typedef BOOL (WINAPI *SYMCLEANUP)( HANDLE ); +typedef BOOL (WINAPI *ENUMERATELOADEDMODULES64)( HANDLE, + PENUMLOADED_MODULES_CALLBACK64, PVOID ); +typedef BOOL (WINAPI *STACKWALK64)( DWORD, HANDLE, HANDLE, LPSTACKFRAME64, + PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, + PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64 ); +typedef BOOL (WINAPI *SYMFROMADDR)( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ); +typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS64)( HANDLE, DWORD64 ); +typedef DWORD64 (WINAPI *SYMGETMODULEBASE64)( HANDLE, DWORD64 ); + +typedef HINSTANCE (WINAPI *SHELLEXECUTE)( HWND, LPCSTR, LPCSTR, + LPCSTR, LPCSTR, INT ); + +PRIVATE SETSYMOPTIONS pSymSetOptions; +PRIVATE SYMGETMODULEINFO64 pSymGetModuleInfo64; +PRIVATE SYMINITIALIZE pSymInitialize; +PRIVATE SYMCLEANUP pSymCleanup; +PRIVATE ENUMERATELOADEDMODULES64 pEnumerateLoadedModules64; +PRIVATE STACKWALK64 pStackWalk64; +PRIVATE SYMFROMADDR pSymFromAddr; +PRIVATE SYMFUNCTIONTABLEACCESS64 pSymFunctionTableAccess64; +PRIVATE SYMGETMODULEBASE64 pSymGetModuleBase64; +PRIVATE SHELLEXECUTE pShellExecute; + +PRIVATE HANDLE processHandle, threadHandle; + +PRIVATE FILE *crashReport; + +PRIVATE CHAR moduleName[MAX_PATH]; + +PRIVATE BOOL CALLBACK EnumModulesCallback( + PTSTR ModuleName, + DWORD64 ModuleBase, + ULONG ModuleSize, + PVOID UserContext ) +{ + IMAGEHLP_MODULE64 moduleInfo; + DWORD64 pc = ( DWORD64 )UserContext; + BYTE buffer[4096]; + PBYTE data; + UINT numBytes; + VS_FIXEDFILEINFO *info; + char version[64]; + char *symbols; + + strcpy( version, "unknown" ); + if( GetFileVersionInfo( ModuleName, 0, sizeof( buffer ), buffer ) ) { + if( VerQueryValue( buffer, "\\", &data, &numBytes ) ) { + info = ( VS_FIXEDFILEINFO * )data; + sprintf( version, "%u.%u.%u.%u", + HIWORD( info->dwFileVersionMS ), + LOWORD( info->dwFileVersionMS ), + HIWORD( info->dwFileVersionLS ), + LOWORD( info->dwFileVersionLS ) ); + } + } + + symbols = "failed"; + moduleInfo.SizeOfStruct = sizeof( moduleInfo ); + if( pSymGetModuleInfo64( processHandle, ModuleBase, &moduleInfo ) ) { + ModuleName = moduleInfo.ModuleName; + switch( moduleInfo.SymType ) { + case SymCoff: symbols = "COFF"; break; + case SymExport: symbols = "export"; break; + case SymNone: symbols = "none"; break; + case SymPdb: symbols = "PDB"; break; + default: symbols = "unknown"; break; + } + } + + fprintf( crashReport, "%p %p %s (version %s, symbols %s) ", + ModuleBase, ModuleBase + ModuleSize, ModuleName, version, symbols ); + if( pc >= ModuleBase && pc < ModuleBase + ModuleSize ) { + strncpy( moduleName, ModuleName, sizeof( moduleName ) - 1 ); + moduleName[ sizeof( moduleName ) - 1 ] = 0; + fprintf( crashReport, "*\n" ); + } else { + fprintf( crashReport, "\n" ); + } + + return TRUE; +} + +DWORD Sys_ExceptionHandler( DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo ) { + STACKFRAME64 stackFrame; + PCONTEXT context; + SYMBOL_INFO *symbol; + int count, ret, i, len; + DWORD64 offset; + BYTE buffer[sizeof( SYMBOL_INFO ) + 256 - 1]; + IMAGEHLP_MODULE64 moduleInfo; + char path[MAX_PATH]; + char execdir[MAX_PATH]; + char *p; + HMODULE helpModule, shellModule; + SYSTEMTIME systemTime; + static const char monthNames[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + OSVERSIONINFO vinfo; + +#if USE_CLIENT + Win_Shutdown(); +#endif + + ret = MessageBox( NULL, APPLICATION " has encountered an unhandled " + "exception and needs to be terminated.\n" + "Would you like to generate a crash report?", + "Unhandled Exception", + MB_ICONERROR | MB_YESNO +#if !USE_CLIENT + | MB_SERVICE_NOTIFICATION +#endif + ); + if( ret == IDNO ) { + return EXCEPTION_CONTINUE_SEARCH; + } + + helpModule = LoadLibrary( "dbghelp.dll" ); + if( !helpModule ) { + return EXCEPTION_CONTINUE_SEARCH; + } + +#define GPA( x, y ) \ + do { \ + p ## y = ( x )GetProcAddress( helpModule, #y ); \ + if( !p ## y ) { \ + return EXCEPTION_CONTINUE_SEARCH; \ + } \ + } while( 0 ) + + GPA( SETSYMOPTIONS, SymSetOptions ); + GPA( SYMGETMODULEINFO64, SymGetModuleInfo64 ); + GPA( SYMCLEANUP, SymCleanup ); + GPA( SYMINITIALIZE, SymInitialize ); + GPA( ENUMERATELOADEDMODULES64, EnumerateLoadedModules64 ); + GPA( STACKWALK64, StackWalk64 ); + GPA( SYMFROMADDR, SymFromAddr ); + GPA( SYMFUNCTIONTABLEACCESS64, SymFunctionTableAccess64 ); + GPA( SYMGETMODULEBASE64, SymGetModuleBase64 ); + + pSymSetOptions( SYMOPT_LOAD_ANYTHING|SYMOPT_DEBUG|SYMOPT_FAIL_CRITICAL_ERRORS ); + processHandle = GetCurrentProcess(); + threadHandle = GetCurrentThread(); + + GetModuleFileName( NULL, execdir, sizeof( execdir ) - 1 ); + execdir[sizeof( execdir ) - 1] = 0; + p = strrchr( execdir, '\\' ); + if( !p ) { + return EXCEPTION_CONTINUE_SEARCH; + } + + *p = 0; + len = p - execdir; + if( len + 24 >= MAX_PATH ) { + return EXCEPTION_CONTINUE_SEARCH; + } + + memcpy( path, execdir, len ); + memcpy( path + len, "\\Q2PRO_CrashReportXX.txt", 25 ); + for( i = 0; i < 100; i++ ) { + path[len+18] = '0' + i / 10; + path[len+19] = '0' + i % 10; + if( !Sys_GetPathInfo( path, NULL ) ) { + break; + } + } + crashReport = fopen( path, "w" ); + if( !crashReport ) { + return EXCEPTION_CONTINUE_SEARCH; + } + + pSymInitialize( processHandle, execdir, TRUE ); + + GetSystemTime( &systemTime ); + fprintf( crashReport, "Crash report generated %s %u %u, %02u:%02u:%02u UTC\n", + monthNames[(systemTime.wMonth - 1) % 12], systemTime.wDay, systemTime.wYear, + systemTime.wHour, systemTime.wMinute, systemTime.wSecond ); + fprintf( crashReport, "by " APPLICATION " " VERSION ", built " __DATE__", " __TIME__ "\n" ); + + vinfo.dwOSVersionInfoSize = sizeof( vinfo ); + if( GetVersionEx( &vinfo ) ) { + fprintf( crashReport, "\nWindows version: %u.%u (build %u) %s\n", + vinfo.dwMajorVersion, vinfo.dwMinorVersion, vinfo.dwBuildNumber, vinfo.szCSDVersion ); + } + + strcpy( moduleName, "unknown" ); + + context = exceptionInfo->ContextRecord; + + fprintf( crashReport, "\nLoaded modules:\n" ); + pEnumerateLoadedModules64( processHandle, EnumModulesCallback, +#ifdef _WIN64 + ( PVOID )context->Rip +#else + ( PVOID )context->Eip +#endif + ); + + fprintf( crashReport, "\nException information:\n" ); + fprintf( crashReport, "Code: %08x\n", exceptionCode ); + fprintf( crashReport, "Address: %p (%s)\n", +#ifdef _WIN64 + context->Rip, +#else + context->Eip, +#endif + moduleName ); + + fprintf( crashReport, "\nThread context:\n" ); +#ifdef _WIN64 + fprintf( crashReport, "RIP: %p RBP: %p RSP: %p\n", + context->Rip, context->Rbp, context->Rsp ); + fprintf( crashReport, "RAX: %p RBX: %p RCX: %p\n", + context->Rax, context->Rbx, context->Rcx ); + fprintf( crashReport, "RDX: %p RSI: %p RDI: %p\n", + context->Rdx, context->Rsi, context->Rdi ); +#else + fprintf( crashReport, "EIP: %p EBP: %p ESP: %p\n", + context->Eip, context->Ebp, context->Esp ); + fprintf( crashReport, "EAX: %p EBX: %p ECX: %p\n", + context->Eax, context->Ebx, context->Ecx ); + fprintf( crashReport, "EDX: %p ESI: %p EDI: %p\n", + context->Edx, context->Esi, context->Edi ); +#endif + + memset( &stackFrame, 0, sizeof( stackFrame ) ); +#ifdef _WIN64 + stackFrame.AddrPC.Offset = context->Rip; + stackFrame.AddrFrame.Offset = context->Rbp; + stackFrame.AddrStack.Offset = context->Rsp; +#else + stackFrame.AddrPC.Offset = context->Eip; + stackFrame.AddrFrame.Offset = context->Ebp; + stackFrame.AddrStack.Offset = context->Esp; +#endif + stackFrame.AddrPC.Mode = AddrModeFlat; + stackFrame.AddrFrame.Mode = AddrModeFlat; + stackFrame.AddrStack.Mode = AddrModeFlat; + + fprintf( crashReport, "\nStack trace:\n" ); + count = 0; + symbol = ( SYMBOL_INFO * )buffer; + symbol->SizeOfStruct = sizeof( SYMBOL_INFO ); + symbol->MaxNameLen = 256; + while( pStackWalk64( +#ifdef _WIN64 + IMAGE_FILE_MACHINE_AMD64, +#else + IMAGE_FILE_MACHINE_I386, +#endif + processHandle, + threadHandle, + &stackFrame, + context, + NULL, + pSymFunctionTableAccess64, + pSymGetModuleBase64, + NULL ) ) + { + fprintf( crashReport, "%d: %p %p %p %p ", + count, + stackFrame.Params[0], + stackFrame.Params[1], + stackFrame.Params[2], + stackFrame.Params[3] ); + + moduleInfo.SizeOfStruct = sizeof( moduleInfo ); + if( pSymGetModuleInfo64( processHandle, stackFrame.AddrPC.Offset, &moduleInfo ) ) { + if( moduleInfo.SymType != SymNone && moduleInfo.SymType != SymExport && + pSymFromAddr( processHandle, stackFrame.AddrPC.Offset, &offset, symbol ) ) + { + fprintf( crashReport, "%s!%s+%#x\n", + moduleInfo.ModuleName, + symbol->Name, offset ); + } else { + fprintf( crashReport, "%s!%#x\n", + moduleInfo.ModuleName, + stackFrame.AddrPC.Offset ); + } + } else { + fprintf( crashReport, "%#x\n", + stackFrame.AddrPC.Offset ); + } + count++; + } + + fclose( crashReport ); + + shellModule = LoadLibrary( "shell32.dll" ); + if( shellModule ) { + pShellExecute = ( SHELLEXECUTE )GetProcAddress( shellModule, "ShellExecuteA" ); + if( pShellExecute ) { + pShellExecute( NULL, "open", path, NULL, execdir, SW_SHOW ); + } + } + + pSymCleanup( processHandle ); + + ExitProcess( 1 ); + return EXCEPTION_CONTINUE_SEARCH; +} + diff --git a/source/win_local.h b/source/win_local.h index 7ecbc01..6f2e163 100644 --- a/source/win_local.h +++ b/source/win_local.h @@ -23,17 +23,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "com_local.h" +#if USE_CLIENT #include "key_public.h" #include "in_public.h" #include "vid_public.h" #include "vid_local.h" #include "ref_public.h" +#endif #include "files.h" #include "sys_public.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> +#define PRIVATE static + +#if USE_CLIENT + #define IDI_APP 100 #ifndef WM_MOUSEWHEEL @@ -61,8 +67,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef const GUID *LPCGUID; #endif -#define PRIVATE static - #define MAX_VIDEO_MODES 128 typedef struct { @@ -96,13 +100,21 @@ typedef struct { } mouse; } win_state_t; -extern HINSTANCE hGlobalInstance; extern win_state_t win; -extern qboolean iswinnt; void Win_Init( void ); void Win_Shutdown( void ); void Win_SetMode( void ); void Win_ModeChanged( void ); -void Win_UpdateGamma( const byte *table ); +void Win_UpdateGamma( const byte *table ); + +#endif // USE_CLIENT + +extern HINSTANCE hGlobalInstance; +extern qboolean iswinnt; + +#if USE_DBGHELP +DWORD Sys_ExceptionHandler( DWORD exceptionCode, + LPEXCEPTION_POINTERS exceptionInfo ); +#endif |