You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1308 lines
33 KiB
1308 lines
33 KiB
![]()
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// LOCAL_CMDS.CPP
|
||
|
//
|
||
|
// Local commands ( *xxxx ) executed by this application.
|
||
|
//=====================================================================================//
|
||
|
#include "vxconsole.h"
|
||
|
|
||
|
localCommand_t g_localCommands[] =
|
||
|
{
|
||
|
// Command name, Flags Handler Help string
|
||
|
// console commands
|
||
|
{ "*cls", FN_CONSOLE, lc_cls, ": Clear the screen" },
|
||
|
{ "*connect", FN_CONSOLE, lc_autoConnect, ": Connect and listen until successful" },
|
||
|
{ "*disconnect", FN_CONSOLE, lc_disconnect, ": Terminate Debug Console session" },
|
||
|
{ "*help", FN_CONSOLE, lc_help, "[command] : List commands/usage" },
|
||
|
{ "*quit", FN_CONSOLE, lc_quit, ": Terminate console" },
|
||
|
{ "*run", FN_XBOX, lc_run, "[app.xex] : Run application or Reboot" },
|
||
|
{ "*reset", FN_XBOX, lc_reset, "Reboot" },
|
||
|
{ "*screenshot", FN_XBOX, lc_screenshot, "<file.bmp> : Copy the screen to file.bmp" },
|
||
|
{ "*memory", FN_APP, lc_memory, ": Dump Memory Stats" },
|
||
|
{ "*dir", FN_XBOX, lc_dir, "<filepath> [/s]: Directory listing" },
|
||
|
{ "*del", FN_XBOX, lc_del, "<filepath> [/s] [/q]: Delete file" },
|
||
|
{ "*modules", FN_XBOX, lc_modules, ": Lists currently loaded modules" },
|
||
|
{ "*sections", FN_XBOX, lc_sections, "<module> : Lists the sections in the module" },
|
||
|
{ "*bug", FN_CONSOLE, lc_bug, ": Open bug submission form" },
|
||
|
{ "*clearconfigs", FN_XBOX, lc_ClearConfigs, ": Erase all game configs" },
|
||
|
|
||
|
// xcommands
|
||
|
{ "*break", FN_XBOX, NULL, " addr=<address> | 'Write'/'Read'/'Execute'=<address> size=<DataSize> ['clear']: Sets/Clears a breakpoint" },
|
||
|
// { "*bye", FN_XBOX, NULL, ": Closes connection" },
|
||
|
{ "*continue", FN_XBOX, NULL, " thread=<threadid>: Resumes execution of a thread which has been stopped" },
|
||
|
// { "*delete", FN_XBOX, NULL, " name=<remotefile>: Deletes a file on the Xbox" },
|
||
|
// { "*dirlist", FN_XBOX, NULL, " name=<remotedir>: Lists the items in the directory" },
|
||
|
{ "*getcontext", FN_XBOX, NULL, " thread=<threadid> 'Control' | 'Int' | 'FP' | 'Full': Gets the context of the thread" },
|
||
|
{ "*getfileattributes", FN_XBOX, NULL, " name=<remotefile>: Gets attributes of a file" },
|
||
|
{ "*getmem", FN_XBOX, NULL, " addr=<address> length=<len>: Reads memory from the Xbox" },
|
||
|
{ "*go", FN_XBOX, NULL, ": Resumes suspended title threads" },
|
||
|
{ "*halt", FN_XBOX, NULL, " thread=<threadid> Breaks a thread" },
|
||
|
{ "*isstopped", FN_XBOX, NULL, " thread=<threadid>: Determines if a thread is stopped and why" },
|
||
|
{ "*mkdir", FN_XBOX, NULL, " name=<remotedir>: Creates a new directory on the Xbox" },
|
||
|
{ "*modlong", FN_XBOX, NULL, " name=<module>: Lists the long name of the module" },
|
||
|
// { "*reboot", FN_XBOX, NULL, " [warm] [wait]: Reboots the xbox" },
|
||
|
{ "*rename", FN_XBOX, NULL, " name=<remotefile> newname=<newname>: Renames a file on the Xbox" },
|
||
|
{ "*resume", FN_XBOX, NULL, " thread=<threadid>: Resumes thread execution" },
|
||
|
{ "*setcontext", FN_XBOX, NULL, " thread=<threadid>: Sets the context of the thread." },
|
||
|
{ "*setfileattributes", FN_XBOX, NULL, " <remotefile> <attrs>: Sets attributes of a file" },
|
||
|
{ "*setmem", FN_XBOX, NULL, " addr=<address> data=<rawdata>: Sets memory on the Xbox" },
|
||
|
{ "*stop", FN_XBOX, NULL, ": Stops the process" },
|
||
|
{ "*suspend", FN_XBOX, NULL, " thread=<threadid>: Suspends the thread" },
|
||
|
{ "*systime", FN_XBOX, NULL, ": Gets the system time of the xbox" },
|
||
|
{ "*threadinfo", FN_XBOX, NULL, " thread=<threadid>: Gets thread info" },
|
||
|
{ "*threads", FN_XBOX, lc_threads, ": Gets the thread list" },
|
||
|
// { "*title", FN_XBOX, NULL, " dir=<remotedir> name=<remotexex> [cmdline=<cmdline>]: Sets title to run" },
|
||
|
{ "*xexinfo", FN_XBOX, NULL, " name=<remotexex | 'running'>: Gets info on an xex" },
|
||
|
{ "*crash", FN_XBOX, lc_crashdump, " crash the console, emitting a dump" },
|
||
|
};
|
||
|
const int g_numLocalCommands = sizeof( g_localCommands )/sizeof( g_localCommands[0] );
|
||
|
|
||
|
static BOOL g_bAutoConnectQuiet;
|
||
|
static int g_bAutoConnectWait;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// MatchCommands
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int MatchLocalCommands( char* cmdStr, const char* cmdList[], int maxCmds )
|
||
|
{
|
||
|
int numCommands = 0;
|
||
|
|
||
|
// look in local
|
||
|
int matchLen = strlen( cmdStr );
|
||
|
for ( int i=0; i<g_numLocalCommands; i++ )
|
||
|
{
|
||
|
if ( !strnicmp( cmdStr, g_localCommands[i].strCommand, matchLen ) )
|
||
|
{
|
||
|
cmdList[numCommands++] = g_localCommands[i].strCommand;
|
||
|
if ( numCommands >= maxCmds )
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ( numCommands );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// DecodeRebootArgs
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void DecodeRebootArgs( int argc, char** argv, char* xexPath, char* xexName, char* xexArgs )
|
||
|
{
|
||
|
char drive[MAX_PATH];
|
||
|
char dir[MAX_PATH];
|
||
|
char filename[MAX_PATH];
|
||
|
char extension[MAX_PATH];
|
||
|
|
||
|
xexPath[0] = '\0';
|
||
|
xexName[0] = '\0';
|
||
|
xexArgs[0] = '\0';
|
||
|
|
||
|
if ( !argc )
|
||
|
return;
|
||
|
|
||
|
_splitpath( argv[0], drive, dir, filename, extension );
|
||
|
|
||
|
sprintf( xexPath, "%s%s", drive, dir );
|
||
|
sprintf( xexName, "%s%s", filename, extension );
|
||
|
|
||
|
for ( int i=1; i<argc; i++ )
|
||
|
{
|
||
|
strcat( xexArgs, argv[i] );
|
||
|
if ( i < argc-1 )
|
||
|
strcat( xexArgs, " " );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Helper function. Causes a disconnect, has optional re-connect time.
|
||
|
// A non-zero wait will delay before attempting re-connect.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void DoDisconnect( BOOL bKeepConnection, int waitTime )
|
||
|
{
|
||
|
// save state, user gates auto-connect ability
|
||
|
int autoConnect = g_autoConnect;
|
||
|
|
||
|
// full disconnect, disables autoconnect
|
||
|
lc_disconnect( 0, NULL );
|
||
|
|
||
|
if ( autoConnect && bKeepConnection && waitTime > 0 )
|
||
|
{
|
||
|
// restore autoconnect status
|
||
|
lc_autoConnect( 0, NULL );
|
||
|
|
||
|
// lets the system settle a little between contexts
|
||
|
g_bAutoConnectWait = waitTime;
|
||
|
g_bAutoConnectQuiet = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_bug
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_bug( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( argc != 1 )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 1, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
BugDlg_Open();
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_dir
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_dir( int argc, char* argv[] )
|
||
|
{
|
||
|
fileNode_t *nodePtr;
|
||
|
fileNode_t *pFileList;
|
||
|
int numFiles;
|
||
|
int numDirs;
|
||
|
__int64 totalBytes;
|
||
|
bool recurse;
|
||
|
char dateTimeString[256];
|
||
|
char sizeString[64];
|
||
|
char filePath[MAX_PATH];
|
||
|
char fileName[MAX_PATH];
|
||
|
char targetName[MAX_PATH];
|
||
|
char newPath[MAX_PATH];
|
||
|
SYSTEMTIME systemTime;
|
||
|
SYSTEMTIME localTime;
|
||
|
const char *dirString;
|
||
|
BOOL errCode;
|
||
|
int nPass;
|
||
|
TIME_ZONE_INFORMATION tzInfo;
|
||
|
|
||
|
pFileList = NULL;
|
||
|
errCode = FALSE;
|
||
|
|
||
|
if ( argc < 2 )
|
||
|
{
|
||
|
char* args[2] = {"*dir", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
strcpy( newPath, argv[1] );
|
||
|
|
||
|
// seperate components
|
||
|
Sys_StripFilename( newPath, filePath, sizeof( filePath ) );
|
||
|
Sys_StripPath( newPath, fileName, sizeof( fileName ) );
|
||
|
|
||
|
if ( fileName[0] )
|
||
|
{
|
||
|
if ( !strstr( fileName,"*" ) && !strstr( fileName,"?" ) )
|
||
|
{
|
||
|
// assume filename was a directory name
|
||
|
strcat( newPath, "\\" );
|
||
|
Sys_StripFilename( newPath, filePath, sizeof( filePath ) );
|
||
|
Sys_StripPath( newPath, fileName, sizeof( fileName ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
recurse = false;
|
||
|
if ( argc >= 3 )
|
||
|
{
|
||
|
if ( !stricmp( argv[2], "/s" ) )
|
||
|
recurse = true;
|
||
|
}
|
||
|
|
||
|
if ( !GetTargetFileList_r( filePath, recurse, FA_NORMAL|FA_DIRECTORY|FA_READONLY, 0, &pFileList ) )
|
||
|
{
|
||
|
ConsoleWindowPrintf( RGB( 255,0,0 ), "Bad Target Path '%s'\n", filePath );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nDirectory of %s\n\n", argv[1] );
|
||
|
|
||
|
GetTimeZoneInformation( &tzInfo );
|
||
|
|
||
|
numFiles = 0;
|
||
|
numDirs = 0;
|
||
|
totalBytes = 0;
|
||
|
for ( nPass=0; nPass<2; nPass++ )
|
||
|
{
|
||
|
for ( nodePtr=pFileList; nodePtr; nodePtr=nodePtr->nextPtr )
|
||
|
{
|
||
|
if ( !nPass && !( nodePtr->attributes & FA_DIRECTORY ) )
|
||
|
{
|
||
|
// first pass, dirs only
|
||
|
continue;
|
||
|
}
|
||
|
else if ( nPass && ( nodePtr->attributes & FA_DIRECTORY ) )
|
||
|
{
|
||
|
// second pass, files only
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
Sys_StripPath( nodePtr->filename, targetName, sizeof( targetName ) );
|
||
|
|
||
|
if ( fileName[0] && !Sys_IsWildcardMatch( fileName, targetName, false ) )
|
||
|
continue;
|
||
|
|
||
|
FileTimeToSystemTime( &nodePtr->changeTime, &systemTime );
|
||
|
SystemTimeToTzSpecificLocalTime( &tzInfo, &systemTime, &localTime );
|
||
|
SystemTimeToString( &localTime, dateTimeString, sizeof( dateTimeString ) );
|
||
|
|
||
|
__int64 fullSize = MAKEINT64( nodePtr->sizeHigh, nodePtr->sizeLow );
|
||
|
|
||
|
if ( nodePtr->attributes & FA_DIRECTORY )
|
||
|
{
|
||
|
numDirs++;
|
||
|
dirString = "<DIR>";
|
||
|
sprintf( sizeString, "%s", " " );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
numFiles++;
|
||
|
dirString = " ";
|
||
|
Sys_NumberToCommaString( fullSize, sizeString, sizeof( sizeString ) );
|
||
|
totalBytes += fullSize;
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s %s %12s %s\n", dateTimeString, dirString, sizeString, targetName );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Sys_NumberToCommaString( totalBytes, sizeString, sizeof( sizeString ) );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%9s %d File(s) %s bytes\n", " ", numFiles, sizeString );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%9s %d Dir(s)\n", " ", numDirs );
|
||
|
|
||
|
// success
|
||
|
errCode = TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
if ( pFileList )
|
||
|
FreeTargetFileList( pFileList );
|
||
|
|
||
|
return errCode;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_del
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_del( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
fileNode_t *nodePtr;
|
||
|
fileNode_t *pFileList;
|
||
|
int numDeleted;
|
||
|
int numErrors;
|
||
|
bool recurse;
|
||
|
char filePath[MAX_PATH];
|
||
|
char fileName[MAX_PATH];
|
||
|
char targetName[MAX_PATH];
|
||
|
BOOL errCode;
|
||
|
|
||
|
pFileList = NULL;
|
||
|
errCode = FALSE;
|
||
|
|
||
|
if ( argc < 2 )
|
||
|
{
|
||
|
char* args[2] = {"*del", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// seperate components
|
||
|
Sys_StripFilename( argv[1], filePath, sizeof( filePath ) );
|
||
|
Sys_StripPath( argv[1], fileName, sizeof( fileName ) );
|
||
|
|
||
|
bool bQuiet = false;
|
||
|
recurse = false;
|
||
|
if ( argc >= 3 )
|
||
|
{
|
||
|
for ( int i = 2; i < argc; i++ )
|
||
|
{
|
||
|
if ( !V_stricmp( argv[i], "/s" ) )
|
||
|
{
|
||
|
recurse = true;
|
||
|
}
|
||
|
else if ( !V_stricmp( argv[i], "/q" ) )
|
||
|
{
|
||
|
// silence errors
|
||
|
bQuiet = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !GetTargetFileList_r( filePath, recurse, FA_NORMAL|FA_READONLY|FA_DIRECTORY, 0, &pFileList ) )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_RED, "Bad Target Path '%s'\n", filePath );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
numErrors = 0;
|
||
|
numDeleted = 0;
|
||
|
for ( nodePtr=pFileList; nodePtr; nodePtr=nodePtr->nextPtr )
|
||
|
{
|
||
|
Sys_StripPath( nodePtr->filename, targetName, sizeof( targetName ) );
|
||
|
|
||
|
if ( fileName[0] && !Sys_IsWildcardMatch( fileName, targetName, false ) )
|
||
|
continue;
|
||
|
|
||
|
hr = DmDeleteFile( nodePtr->filename, ( nodePtr->attributes & FA_DIRECTORY ) != 0 );
|
||
|
if ( hr != XBDM_NOERR )
|
||
|
{
|
||
|
if ( !bQuiet )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_RED, "Error Deleting '%s'\n", nodePtr->filename );
|
||
|
}
|
||
|
numErrors++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Deleted '%s'\n", nodePtr->filename );
|
||
|
numDeleted++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !numDeleted && !numErrors )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_RED, "No Files found for '%s'\n", argv[1] );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%d files deleted.\n", numDeleted );
|
||
|
}
|
||
|
|
||
|
// success
|
||
|
errCode = TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
if ( pFileList )
|
||
|
FreeTargetFileList( pFileList );
|
||
|
|
||
|
return errCode;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_memory
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_memory( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = DmAPI_SendCommand( VXCONSOLE_COMMAND_PREFIX "!" "__memory__", true );
|
||
|
if ( FAILED( hr ) )
|
||
|
return FALSE;
|
||
|
|
||
|
// success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_screenshot
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_screenshot( int argc, char* argv[] )
|
||
|
{
|
||
|
char filename[MAX_PATH];
|
||
|
char filepath[MAX_PATH];
|
||
|
static int shot = 0;
|
||
|
struct _stat dummyStat;
|
||
|
|
||
|
if ( argc <= 1 )
|
||
|
{
|
||
|
strcpy( filepath, g_localPath );
|
||
|
Sys_AddFileSeperator( filepath, sizeof( filepath ) );
|
||
|
|
||
|
// spin up to available file
|
||
|
while ( 1 )
|
||
|
{
|
||
|
sprintf( filename, "%sscreenshot_%4.4d.bmp", filepath, shot );
|
||
|
if ( _stat( filename, &dummyStat ) == -1 )
|
||
|
{
|
||
|
// filename not in use
|
||
|
break;
|
||
|
}
|
||
|
shot++;
|
||
|
}
|
||
|
}
|
||
|
else if ( argc == 2 )
|
||
|
{
|
||
|
strcpy( filename, argv[1] );
|
||
|
Sys_AddExtension( ".bmp", filename, sizeof( filename ) );
|
||
|
}
|
||
|
else if ( argc > 2 )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
HRESULT hr = DmScreenShot( filename );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_screenshot(): DmScreenShot() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Screenshot saved to %s\n", filename );
|
||
|
|
||
|
// advance the shot
|
||
|
shot++;
|
||
|
|
||
|
// success
|
||
|
return TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_modules
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_modules( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
PDM_WALK_MODULES pWalkMod = NULL;
|
||
|
CUtlVector< DMN_MODLOAD > list;
|
||
|
|
||
|
// add a fake module at 0xFFFFFFFF to make sorting simple
|
||
|
DMN_MODLOAD modLoad = { 0 };
|
||
|
modLoad.BaseAddress = (VOID*)0xFFFFFFFF;
|
||
|
list.AddToTail( modLoad );
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Modules:\n" );
|
||
|
while ( 1 )
|
||
|
{
|
||
|
hr = DmWalkLoadedModules( &pWalkMod, &modLoad );
|
||
|
if ( hr == XBDM_ENDOFLIST )
|
||
|
{
|
||
|
hr = XBDM_NOERR;
|
||
|
break;
|
||
|
}
|
||
|
else if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_modules(): DmWalkLoadedModules() failure", hr );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// add in ascending address order
|
||
|
for ( int i = 0; i < list.Count(); i++ )
|
||
|
{
|
||
|
if ( modLoad.BaseAddress <= list[i].BaseAddress )
|
||
|
{
|
||
|
list.InsertBefore( i, modLoad );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsigned int total = 0;
|
||
|
for ( int i = 0; i < list.Count()-1; i++ )
|
||
|
{
|
||
|
DMN_MODLOAD *pModule = &list[i];
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Base: 0x%8.8x, Size: %5.2f MB, [%s]\n", pModule->BaseAddress, pModule->Size/( 1024.0f*1024.0f ), pModule->Name );
|
||
|
|
||
|
total += pModule->Size;
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Total: %.2f MB\n\n", total/( 1024.0f*1024.0f ) );
|
||
|
|
||
|
if ( pWalkMod )
|
||
|
{
|
||
|
DmCloseLoadedModules( pWalkMod );
|
||
|
}
|
||
|
|
||
|
if ( !FAILED( hr ) )
|
||
|
{
|
||
|
// success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_sections
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_sections( int argc, char* argv[] )
|
||
|
{
|
||
|
char moduleName[MAX_PATH];
|
||
|
HRESULT hr;
|
||
|
PDM_WALK_MODSECT pWalkModSect = NULL;
|
||
|
DMN_SECTIONLOAD sectLoad;
|
||
|
|
||
|
if ( argc != 2 )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
strcpy( moduleName, argv[1] );
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Sections:\n" );
|
||
|
while ( 1 )
|
||
|
{
|
||
|
hr = DmWalkModuleSections( &pWalkModSect, moduleName, §Load );
|
||
|
if ( hr == XBDM_ENDOFLIST )
|
||
|
{
|
||
|
hr = XBDM_NOERR;
|
||
|
break;
|
||
|
}
|
||
|
else if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_sections(): DmWalkModuleSections() failure", hr );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "[%s]:\n", sectLoad.Name );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, " Base: 0x%8.8x\n", sectLoad.BaseAddress );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, " Size: %.2f MB ( %d bytes )\n", sectLoad.Size/( 1024.0f*1024.0f ), sectLoad.Size );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, " Index: %d\n", sectLoad.Index );
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "End.\n\n" );
|
||
|
|
||
|
if ( pWalkModSect )
|
||
|
DmCloseModuleSections( pWalkModSect );
|
||
|
|
||
|
if ( !FAILED( hr ) )
|
||
|
{
|
||
|
// success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
cleanUp:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_threads
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_threads( int argc, char* argv[] )
|
||
|
{
|
||
|
char nameBuff[256];
|
||
|
char suspendBuff[32];
|
||
|
|
||
|
DWORD threadList[256];
|
||
|
DWORD numThreads = 256;
|
||
|
memset( &threadList, 0, sizeof( threadList ) );
|
||
|
HRESULT hr = DmGetThreadList( threadList, &numThreads );
|
||
|
if ( FAILED( hr ) )
|
||
|
return FALSE;
|
||
|
|
||
|
// enumerate threads and display sorted by processor
|
||
|
DM_THREADINFOEX threadInfoEx;
|
||
|
for ( int core = 0; core < 3; core++ )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\n--- CORE %d ---\n", core );
|
||
|
|
||
|
for ( int unit = 0; unit < 2; unit++ )
|
||
|
{
|
||
|
for ( int i = 0; i < (int)numThreads; i++ )
|
||
|
{
|
||
|
threadInfoEx.Size = sizeof( DM_THREADINFOEX );
|
||
|
hr = DmGetThreadInfoEx( threadList[i], &threadInfoEx );
|
||
|
if ( FAILED( hr ) )
|
||
|
return FALSE;
|
||
|
|
||
|
if ( threadInfoEx.CurrentProcessor != core*2 + unit )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
nameBuff[0] = '\0';
|
||
|
DmGetMemory( threadInfoEx.ThreadNameAddress, threadInfoEx.ThreadNameLength, nameBuff, NULL );
|
||
|
if ( !nameBuff[0] )
|
||
|
{
|
||
|
strcpy( nameBuff, "???" );
|
||
|
}
|
||
|
|
||
|
suspendBuff[0] = '\0';
|
||
|
if ( threadInfoEx.SuspendCount )
|
||
|
{
|
||
|
sprintf( suspendBuff, "(Suspend: %d)", threadInfoEx.SuspendCount );
|
||
|
}
|
||
|
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, " Id: 0x%8.8x Pri: %2d Proc: %1d Stack: %7.2f KB [%s] %s\n",
|
||
|
threadList[i],
|
||
|
threadInfoEx.Priority,
|
||
|
threadInfoEx.CurrentProcessor,
|
||
|
(float)( (unsigned int)threadInfoEx.StackBase - (unsigned int)threadInfoEx.StackLimit )/1024.0f,
|
||
|
nameBuff,
|
||
|
suspendBuff );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_run
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_run( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
char xexDrive[MAX_PATH];
|
||
|
char xexPath[MAX_PATH];
|
||
|
char xexName[MAX_PATH];
|
||
|
char xexArgs[MAX_PATH];
|
||
|
|
||
|
if ( !argc )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// copy args
|
||
|
g_rebootArgc = argc-1;
|
||
|
for ( int i=1; i<argc; i++ )
|
||
|
{
|
||
|
if ( i==1 )
|
||
|
{
|
||
|
strcpy( xexPath, argv[i] );
|
||
|
Sys_AddExtension( ".xex", xexPath, sizeof( xexPath ) );
|
||
|
_splitpath( xexPath, xexDrive, NULL, NULL, NULL );
|
||
|
if ( !xexDrive[0] )
|
||
|
{
|
||
|
char szTempPath[MAX_PATH];
|
||
|
V_strncpy( szTempPath, "e:\\", sizeof( szTempPath ) );
|
||
|
V_strncat( szTempPath, xexPath, sizeof( szTempPath ) );
|
||
|
V_strncpy( xexPath, szTempPath, sizeof( xexPath ) );
|
||
|
}
|
||
|
|
||
|
g_rebootArgv[i-1] = Sys_CopyString( xexPath );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_rebootArgv[i-1] = Sys_CopyString( argv[i] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !g_rebootArgc )
|
||
|
{
|
||
|
// reboot
|
||
|
hr = DmReboot( DMBOOT_COLD );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DecodeRebootArgs( g_rebootArgc, g_rebootArgv, xexPath, xexName, xexArgs );
|
||
|
|
||
|
// trial set title - ensure title is present
|
||
|
hr = DmSetTitle( xexPath, xexName, xexArgs );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_Run(): DmSetTitle() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// reboot - wait for 15s to connect and run title
|
||
|
hr = DmReboot( DMBOOT_WAIT );
|
||
|
}
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_Run(): DmReboot() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// set reboot state
|
||
|
g_reboot = true;
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
// free args
|
||
|
for ( int i=0; i<g_rebootArgc; i++ )
|
||
|
Sys_Free( g_rebootArgv[i] );
|
||
|
g_rebootArgc = 0;
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_reset
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_reset( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( !argc )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 2, args );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT hr = DmReboot( DMBOOT_COLD );
|
||
|
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_Run(): DmReboot() failure", hr );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// set reboot state
|
||
|
g_reboot = true;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_help
|
||
|
//
|
||
|
// Handles the "help" command. If no args, prints a list of built-in
|
||
|
// and remote commands ( remote only if connected ). If a command
|
||
|
// is specified, prints detailed help for that command
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_help( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( argc <= 1 )
|
||
|
{
|
||
|
// no arguments - print out our list of commands
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\n" );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Console Commands:\n" );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "---------------\n" );
|
||
|
for ( int i = 0; i < g_numLocalCommands; i++ )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s\n", g_localCommands[i].strCommand );
|
||
|
}
|
||
|
|
||
|
if ( g_connectedToApp )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Remote Commands: ( %d )\n", g_numRemoteCommands );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "----------------\n" );
|
||
|
if ( !g_numRemoteCommands )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "( None )\n" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for ( int i=0; i<g_numRemoteCommands; i++ )
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s\n", g_remoteCommands[i]->strCommand );
|
||
|
}
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\n" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// match as many as possible
|
||
|
int cch = lstrlenA( argv[1] );
|
||
|
|
||
|
// print help description for all local matches
|
||
|
for ( int i=0; i<g_numLocalCommands; i++ )
|
||
|
{
|
||
|
if ( !_strnicmp( g_localCommands[i].strCommand, argv[1], cch ) && g_localCommands[i].strHelp )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s %s\n", g_localCommands[i].strCommand, g_localCommands[i].strHelp );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// print help description for all remote matches
|
||
|
if ( g_connectedToApp )
|
||
|
{
|
||
|
for ( int i=0; i<g_numRemoteCommands; i++ )
|
||
|
{
|
||
|
if ( !_strnicmp( g_remoteCommands[i]->strCommand, argv[1], cch ) && g_remoteCommands[i]->strHelp )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s %s\n", g_remoteCommands[i]->strCommand, g_remoteCommands[i]->strHelp );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\n" );
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_cls
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_cls( int argc, char* argv[] )
|
||
|
{
|
||
|
SetWindowText( g_hwndOutputWindow, "" );
|
||
|
|
||
|
// non't let the compiler complain about unused parameters
|
||
|
( VOID )argc;
|
||
|
( VOID )argv;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_connect
|
||
|
//
|
||
|
// Connect to XBox
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_connect( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
BOOL connected = FALSE;
|
||
|
|
||
|
if ( g_connectedToXBox )
|
||
|
{
|
||
|
if ( !lc_disconnect( 0, NULL ) )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if ( argc >= 1 && argv[0][0] )
|
||
|
{
|
||
|
hr = DmSetXboxName( argv[0] );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
char message[255];
|
||
|
sprintf( message, "ConnectToXBox(): DmSetXboxName( %s ) failure", argv[0] );
|
||
|
DmAPI_DisplayError( message, hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// open connection
|
||
|
hr = DmOpenConnection( &g_pdmConnection );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "ConnectToXBox(): DmOpenConnection() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
connected = TRUE;
|
||
|
|
||
|
DWORD namelen = MAX_XBOXNAMELEN;
|
||
|
hr = DmGetXboxName( g_xboxName, &namelen );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "ConnectToXBox(): DmGetXboxName() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
hr = DmResolveXboxName( &g_xboxAddress );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "ConnectToXBox(): DmResolveXboxName() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// success
|
||
|
g_connectedToXBox = TRUE;
|
||
|
g_connectFailure = 0;
|
||
|
|
||
|
if ( !g_connectCount )
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Connected To: '%s'(%d.%d.%d.%d)\n", g_xboxName, ( ( byte* )&g_xboxAddress )[3], ( ( byte* )&g_xboxAddress )[2], ( ( byte* )&g_xboxAddress )[1], ( ( byte* )&g_xboxAddress )[0] );
|
||
|
g_connectCount++;
|
||
|
|
||
|
SetConnectionIcon( ICON_CONNECTED_XBOX );
|
||
|
|
||
|
if ( g_connectCount == 1 )
|
||
|
{
|
||
|
// inital connect
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
if ( connected )
|
||
|
DmCloseConnection( g_pdmConnection );
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_listen
|
||
|
//
|
||
|
// Open listen session with App
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_listen( int argc, char* argv[] )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
BOOL success;
|
||
|
BOOL sessionStarted;
|
||
|
BOOL sessionValid;
|
||
|
char *args[1];
|
||
|
char cmdStr[256];
|
||
|
|
||
|
if ( g_connectedToXBox || g_connectedToApp )
|
||
|
{
|
||
|
if ( !lc_disconnect( 0, NULL ) )
|
||
|
return ( FALSE );
|
||
|
}
|
||
|
|
||
|
if ( !g_connectedToXBox )
|
||
|
{
|
||
|
// connect to xbox
|
||
|
args[0] = g_xboxTargetName;
|
||
|
if ( !lc_connect( 1, args ) )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// until otherwise
|
||
|
success = FALSE;
|
||
|
sessionStarted = FALSE;
|
||
|
sessionValid = FALSE;
|
||
|
|
||
|
// init session
|
||
|
hr = DmOpenNotificationSession( 0, &g_pdmnSession );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_session(): DmOpenNotificationSession() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
sessionStarted = TRUE;
|
||
|
|
||
|
// get notifications of app debugging output
|
||
|
hr = DmNotify( g_pdmnSession, DM_DEBUGSTR, Remote_NotifyDebugString );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_session(): DmNotify() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// get command notifications
|
||
|
hr = DmRegisterNotificationProcessor( g_pdmnSession, VXCONSOLE_COMMAND_PREFIX, Remote_NotifyCommandFunc );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_session(): DmRegisterNotificationProcessor() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// get print notifications
|
||
|
hr = DmRegisterNotificationProcessor( g_pdmnSession, VXCONSOLE_PRINT_PREFIX, Remote_NotifyPrintFunc );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
DmAPI_DisplayError( "lc_session(): DmRegisterNotificationProcessor() failure", hr );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
sessionValid = TRUE;
|
||
|
|
||
|
// Send initial connect command to the External Command Processor so it knows we're here
|
||
|
sprintf( cmdStr, "%s %d", VXCONSOLE_COMMAND_PREFIX "!" "__connect__", VXCONSOLE_PROTOCOL_VERSION );
|
||
|
hr = DmAPI_SendCommand( cmdStr, true );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
if ( !g_autoConnect )
|
||
|
ConsoleWindowPrintf( RGB( 255,0,0 ), "Couldn't Find Application\n" );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// connected
|
||
|
success = TRUE;
|
||
|
g_connectedToApp = TRUE;
|
||
|
g_connectedTime = Sys_GetSystemTime();
|
||
|
SetConnectionIcon( ICON_CONNECTED_APP1 );
|
||
|
|
||
|
if ( g_clsOnConnect )
|
||
|
{
|
||
|
if ( g_bPlayTestMode )
|
||
|
{
|
||
|
// demarcate the log
|
||
|
ConsoleWindowPrintf( CLR_DEFAULT, "\n******** CONNECTION ********\n" );
|
||
|
}
|
||
|
|
||
|
lc_cls( 0, NULL );
|
||
|
CpuProfile_Clear();
|
||
|
TimeStampLog_Clear();
|
||
|
}
|
||
|
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
cleanUp:
|
||
|
if ( !success )
|
||
|
{
|
||
|
if ( sessionValid )
|
||
|
DmNotify( g_pdmnSession, DM_NONE, NULL );
|
||
|
|
||
|
if ( sessionStarted )
|
||
|
DmCloseNotificationSession( g_pdmnSession );
|
||
|
}
|
||
|
|
||
|
return ( success );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// AutoConnectTimerProc
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AutoConnectTimerProc( HWND hwnd, UINT_PTR idEvent )
|
||
|
{
|
||
|
static BOOL busy;
|
||
|
int icon;
|
||
|
char* cmdStr;
|
||
|
BOOL bKeepConnection = TRUE;
|
||
|
|
||
|
// blink the connection icon
|
||
|
if ( g_connectedToApp && (! g_bSuppressBlink ) )
|
||
|
{
|
||
|
if ( g_currentIcon == ICON_CONNECTED_APP0 )
|
||
|
icon = ICON_CONNECTED_APP1;
|
||
|
else
|
||
|
icon = ICON_CONNECTED_APP0;
|
||
|
SetConnectionIcon( icon );
|
||
|
}
|
||
|
|
||
|
if ( busy )
|
||
|
{
|
||
|
// not ready for new tick
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( g_bAutoConnectWait > 0 )
|
||
|
{
|
||
|
if ( g_bAutoConnectWait && !g_bAutoConnectQuiet )
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Waiting... %d seconds remaining\n", g_bAutoConnectWait );
|
||
|
g_bAutoConnectWait--;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// no more ticks until ready
|
||
|
busy = TRUE;
|
||
|
|
||
|
if ( !g_connectedToApp )
|
||
|
{
|
||
|
// looking for application - must force re-connect every time
|
||
|
if ( g_connectedToXBox )
|
||
|
{
|
||
|
// temporary "partial" disconnect
|
||
|
DmCloseConnection( g_pdmConnection );
|
||
|
g_connectedToXBox = FALSE;
|
||
|
}
|
||
|
|
||
|
// attempt to start or re-establish connection and session
|
||
|
lc_listen( 0, NULL );
|
||
|
|
||
|
if ( !g_connectedToXBox )
|
||
|
{
|
||
|
SetConnectionIcon( ICON_DISCONNECTED );
|
||
|
g_connectFailure++;
|
||
|
}
|
||
|
|
||
|
if ( g_reboot && g_connectedToXBox )
|
||
|
{
|
||
|
char xexPath[MAX_PATH];
|
||
|
char xexName[MAX_PATH];
|
||
|
char xexArgs[MAX_PATH];
|
||
|
|
||
|
DecodeRebootArgs( g_rebootArgc, g_rebootArgv, xexPath, xexName, xexArgs );
|
||
|
|
||
|
if ( g_rebootArgc )
|
||
|
{
|
||
|
// free args
|
||
|
for ( int i=0; i<g_rebootArgc; i++ )
|
||
|
Sys_Free( g_rebootArgv[i] );
|
||
|
g_rebootArgc = 0;
|
||
|
|
||
|
HRESULT hr = DmSetTitle( xexPath, xexName, xexArgs );
|
||
|
if ( FAILED( hr ) )
|
||
|
DmAPI_DisplayError( "Reboot: DmSetTitle() failure", hr );
|
||
|
else
|
||
|
{
|
||
|
hr = DmGo();
|
||
|
if ( FAILED( hr ) )
|
||
|
DmAPI_DisplayError( "Reboot: DmGo() failure", hr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g_reboot = false;
|
||
|
}
|
||
|
|
||
|
if ( !g_connectFailure )
|
||
|
{
|
||
|
// quietly attempt re-connection or ping every 3 seconds
|
||
|
g_bAutoConnectWait = 3;
|
||
|
g_bAutoConnectQuiet = TRUE;
|
||
|
busy = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( g_connectFailure == 1 )
|
||
|
{
|
||
|
// console may be rebooting, allow sufficient dvd boot up delay, then attempt re-connection
|
||
|
// 5 seconds barely covers the xbox splash
|
||
|
g_bAutoConnectWait = 15;
|
||
|
g_bAutoConnectQuiet = FALSE;
|
||
|
busy = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// a sustained connection failure means the xbox is just not there
|
||
|
// re-trying is too cpu intensive and causes pc to appear locked
|
||
|
// warn and stop auto connecting, user must fix
|
||
|
bKeepConnection = FALSE;
|
||
|
goto disconnect;
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// try to send ping across open connection at an idle interval
|
||
|
cmdStr = VXCONSOLE_COMMAND_PREFIX "!";
|
||
|
HRESULT hr = DmAPI_SendCommand( cmdStr, false );
|
||
|
if ( FAILED( hr ) && hr != XBDM_UNDEFINED )
|
||
|
goto disconnect;
|
||
|
|
||
|
// quietly ping
|
||
|
g_bAutoConnectWait = 3;
|
||
|
g_bAutoConnectQuiet = TRUE;
|
||
|
busy = FALSE;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
disconnect:
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Connection To Xbox Lost.\n" );
|
||
|
|
||
|
DoDisconnect( bKeepConnection, 3 );
|
||
|
|
||
|
busy = FALSE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_autoConnect
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_autoConnect( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( !g_autoConnect )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Enabling Auto Connect.\n" );
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Looking for Connection...\n" );
|
||
|
g_autoConnect = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// already enabled
|
||
|
return ( TRUE );
|
||
|
}
|
||
|
|
||
|
if ( !g_autoConnectTimer )
|
||
|
{
|
||
|
UINT_PTR timer = TIMERID_AUTOCONNECT;
|
||
|
g_autoConnectTimer = SetTimer( g_hDlgMain, timer, 1000, NULL );
|
||
|
}
|
||
|
|
||
|
return ( TRUE );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_disconnect
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_disconnect( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( g_autoConnect )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Disabling Auto Connect.\n" );
|
||
|
if ( g_autoConnectTimer )
|
||
|
{
|
||
|
UINT_PTR timer = TIMERID_AUTOCONNECT;
|
||
|
KillTimer( g_hDlgMain, timer );
|
||
|
}
|
||
|
g_autoConnectTimer = 0;
|
||
|
g_autoConnect = FALSE;
|
||
|
}
|
||
|
|
||
|
if ( g_connectedToApp )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Closing Session.\n" );
|
||
|
|
||
|
DmAPI_SendCommand( VXCONSOLE_COMMAND_PREFIX "!" "__disconnect__", false );
|
||
|
|
||
|
// close session
|
||
|
DmNotify( g_pdmnSession, DM_NONE, NULL );
|
||
|
DmCloseNotificationSession( g_pdmnSession );
|
||
|
|
||
|
g_connectedToApp = FALSE;
|
||
|
}
|
||
|
|
||
|
if ( g_connectedToXBox )
|
||
|
{
|
||
|
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Closing Connection.\n" );
|
||
|
|
||
|
// close connection
|
||
|
DmCloseConnection( g_pdmConnection );
|
||
|
|
||
|
// set the command ready mutex
|
||
|
SetEvent( g_hCommandReadyEvent );
|
||
|
|
||
|
g_connectedToXBox = FALSE;
|
||
|
g_xboxName[0] = '\0';
|
||
|
g_xboxAddress = 0;
|
||
|
}
|
||
|
|
||
|
SetConnectionIcon( ICON_DISCONNECTED );
|
||
|
|
||
|
g_connectCount = 0;
|
||
|
|
||
|
// free remote commands
|
||
|
Remote_DeleteCommands();
|
||
|
|
||
|
// Don't let the compiler complain about unused parameters
|
||
|
( VOID )argc;
|
||
|
( VOID )argv;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_crashdump
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_crashdump( int argc, char* argv[] )
|
||
|
{
|
||
|
DmCrashDump();
|
||
|
|
||
|
// Don't let the compiler complain about unused parameters
|
||
|
( VOID )argc;
|
||
|
( VOID )argv;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_quit
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_quit( int argc, char* argv[] )
|
||
|
{
|
||
|
PostMessage( g_hDlgMain, WM_CLOSE, 0, 0 );
|
||
|
|
||
|
// don't let the compiler complain about unused parameters
|
||
|
( VOID )argc;
|
||
|
( VOID )argv;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// lc_ClearConfigs
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL lc_ClearConfigs( int argc, char* argv[] )
|
||
|
{
|
||
|
if ( argc != 1 )
|
||
|
{
|
||
|
char* args[2] = {"*help", argv[0]};
|
||
|
lc_help( 1, args );
|
||
|
goto cleanUp;
|
||
|
}
|
||
|
|
||
|
// delete any configurations (ignore errors)
|
||
|
char szTempFilename[MAX_PATH];
|
||
|
V_ComposeFileName( "HDD:\\Content", "*.*", szTempFilename, sizeof( szTempFilename ) );
|
||
|
char *pArgs[4];
|
||
|
pArgs[0] = "*del";
|
||
|
pArgs[1] = szTempFilename;
|
||
|
pArgs[2] = "/s";
|
||
|
pArgs[3] = "/q";
|
||
|
lc_del( 4, pArgs );
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
cleanUp:
|
||
|
return FALSE;
|
||
|
}
|