memspy/CommandLine/Source/MemSpyCommandLine.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 16:45:49 +0300
branchRCL_3
changeset 43 ca8a1b6995f6
parent 0 a03f92240627
child 44 52e343bb8f80
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/

#include "MemSpyCommandLine.h"

// System includes
#include <bacline.h>
#include <bautils.h>
#include <memspyengineclientinterface.h>
#include <memspysession.h>
#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>

// User includes
#include "MemSpyCommands.h"

/*
CMemSpyCommandLine::CMemSpyCommandLine()
    {	
    }
*/

CMemSpyCommandLine::CMemSpyCommandLine( CConsoleBase& aConsole )
	: CActive( EPriorityHigh ), iConsole( aConsole )
    {	
	CActiveScheduler::Add( this );
    }

CMemSpyCommandLine::~CMemSpyCommandLine()
    {
	Cancel();
	
    if ( iMemSpySession )
        {
        iMemSpySession->Close();
        }
    delete iMemSpySession;
    iFsSession.Close();
    }


void CMemSpyCommandLine::ConstructL()
    {
    User::LeaveIfError( iFsSession.Connect() );   
    iMemSpySession = new(ELeave) RMemSpySession();
    ConnectToMemSpyL();                    
    }

CMemSpyCommandLine* CMemSpyCommandLine::NewLC( CConsoleBase& aConsole )
    {
    CMemSpyCommandLine* self = new(ELeave) CMemSpyCommandLine( aConsole );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

void CMemSpyCommandLine::PerformOpL( const CCommandLineArguments& aCommandLine )
    {
    const TInt count = aCommandLine.Count();
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - START - arg count: %d, this: 0x%08x", count, this ) );

    if  ( count >= 1 )
        {
        // Get main command
        TBuf<KMemSpyCommandLineMaxLength> command;
        command.Copy( aCommandLine.Arg( 1 ) );
        command.UpperCase();

        // Extract arguments into array
        CDesCArrayFlat* args = new(ELeave) CDesCArrayFlat(4);
        CleanupStack::PushL( args );
        for( TInt i=2; i<count; i++ )
            {
            args->AppendL( aCommandLine.Arg( i ) );
            }

        // Perform op
        PerformSingleOpL( command, *args );

        // Tidy up
        CleanupStack::PopAndDestroy( args );
        }
    else
        {
        User::Leave( KErrUnderflow );
        }
    }


void CMemSpyCommandLine::PerformSingleOpL( const TDesC& aCommand, const CDesCArray& aParameters )
    {
    // Record duration
    TTime timeStart; 
    timeStart.HomeTime();
    const TInt paramCount = aParameters.Count();

#ifdef _DEBUG
    TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - START - command: %S, paramCount: %d, this: 0x%08x"), &aCommand, paramCount, this ) );
    for( TInt i=0; i<paramCount; i++ )
        {
        const TPtrC pParam( aParameters[ i ] );
        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - param[%02d] = [%S]"), i, &pParam ) );
        }
#else
    RDebug::Print( _L("[MemSpyCmdLine] COMMAND: [%S] {%02d}..."), &aCommand, paramCount );
#endif

    TFileName batchFile;
    batchFile.Append( aCommand );
    
    TInt err = KErrNotSupported;
    TInt error = KErrNotSupported;
    
    // --- HELP
    if ( aCommand.CompareF( KMemSpyCmdHelp1) == 0 || 
    	 aCommand.CompareF( KMemSpyCmdHelp2) == 0 ||
    	 aCommand.CompareF( KMemSpyCmdHelp3) == 0 ||
    	 aCommand.CompareF( KMemSpyCmdHelp4) == 0 )
    	{
		iConsole.Write( KHelpMessage );
		iConsole.Write( KMemSpyCLINewLine );		
		iConsole.Write( KHelpOutputCommand );
		iConsole.Write( KHelpOutputToFileCommand );
		iConsole.Write( KHelpHeapDumpCommand );
		iConsole.Write( KHelpSwmtCommand );
		iConsole.Write( KHelpKillServerCommand );
		iConsole.Write( KMemSpyCLINewLine );
		iConsole.Write( KHelpCommand );

	    // Show input prompt.
	    iCommandPromptPos = iConsole.CursorPos();
	    RedrawInputPrompt();
	    WaitForInput();
	    
	    CActiveScheduler::Start();
    	}
    // --- OUTPUT
    //TODO: directory option to be added
    else if  ( aCommand.CompareF( KMemSpyCmdOutput ) == 0 )	//change output mode   
    	{    						
		if( paramCount >= 1 )
			{
			if( aParameters[0].CompareF( KMemSpyCmdOutputParameterFile ) == 0 )
				{
				if( paramCount == 2 )
					{
					TBuf<KMaxFileName> directory;
					directory.Copy( aParameters[1] );
					iMemSpySession->SwitchOutputToFileL( directory );
					}
				else
					{
					iMemSpySession->SwitchOutputToFileL( KNullDesC );
					}
				}
			else if( aParameters[0].CompareF( KMemSpyCmdOutputParameterTrace ) == 0)
				{
				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output Trace", this ) );
				iMemSpySession->SwitchOutputToTraceL();
				}
			}		           
    	}    	
    // --- HEAP DUMP    
    else if ( aCommand.CompareF( KMemSpyCmdHeapDump) == 0 )    	
		{		
		RedrawStatusMessage( KHeapDumpMessage );
		
		if( paramCount == 0 ) // no parameter - dump all heap data + kernel heap at the end
			{		
		
			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (all threads)", this ) );			
			// Dump heap data for all threads - Thread agnostic operation					
			iMemSpySession->OutputHeapData();
			// Dump kernel heap data
			iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );					
			}
		else if( paramCount >= 1)
			{
			if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterAll ) == 0 )
				{
				iMemSpySession->OutputHeapData();				
				iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );				
				}
			else if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterKernel ) == 0 )
				{
				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_DumpKernel", this ) );
				iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );				
				}
			else
				{				
				// Dump heap data for named thread - filter
				const TPtrC pThreadName( aParameters[0] );
				TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (%S)"), this, &pThreadName ) );				
				iMemSpySession->OutputThreadHeapDataL( pThreadName );
				}
  			}
		}
    
    // --- SYSTEM WIDE MEMORY TRACKING    
    else if( aCommand.CompareF( KMemSpyCmdSwmt ) == 0 )
    	{    
		RedrawStatusMessage( KSWMTMessage );
    		
		TInt categories( 0 );
		TName threadNameFilter;
		
		if( paramCount == 0 ) //default state -> "dumpnow" command with "all" categories
			{
			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - dumpnow command", this ) );
			TInt category = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
			iMemSpySession->SetSwmtCategoriesL( category );			
			iMemSpySession->ForceSwmtUpdateL();			
			}
		else if( paramCount >= 1)
			{
			const TPtrC pParam( aParameters[0] );
			if( pParam.CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 ) // "starttimer" - start tracking
				{
				TInt result(0);
				categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
				iMemSpySession->SetSwmtTimerIntervalL( KMemSpySysMemTrackerConfigMinTimerPeriod );
				
				if( paramCount >= 2 ) // user gave some optional parameters - <categories> or <value in seconds>
					{					
					TLex lex( aParameters[1] );
				    if ( lex.Val( result ) == KErrNone ) //if 2nd parameter is not number, then parse parameters
				    	{
						if( result >= KMemSpySysMemTrackerConfigMinTimerPeriod && result <= KMemSpySysMemTrackerConfigMaxTimerPeriod )
							{
							iMemSpySession->SetSwmtTimerIntervalL( result );							;
							}											
				    	}				   
				    TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
					}																				
				
				//if( !err )
				//	{
					/*
					_LIT( KPressS, "Press 's' to stop the timer " );
					iConsole.Write( KPressS );
					
					iCommandPromptPos = iConsole.CursorPos();					
					RedrawInputPrompt();					
					WaitForInput();
					*/
					    
					iMemSpySession->StartSwmtTimerL();
					
					//CActiveScheduler::Start();									
				//	}	
				}
			else if( pParam.CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 ) // "stoptime" - stop tracking
				{
				iMemSpySession->StopSwmtTimerL();
				}
			else if( pParam.CompareF( KMemSpyCmdSwmtParameterDumpnow ) == 0 ) // "dumpnow" - runs one tracking cycle (CmdSWMT_ForceUpdate before)
				{
				categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
				if( paramCount >= 2 ) // user gave some optional parameters - <categories>
					{
					TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
					}				
																
				if( !err )
					{
					iMemSpySession->SetSwmtCategoriesL( categories );
					iMemSpySession->ForceSwmtUpdateL();
					}												
				}							
			else //no parameters ("starttimer / stoptimer / dumpnow"), just categories / thread filter
				 //so dumpnow is used as default with category / thread specified
				{
				TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
				if( !err )
					{
					iMemSpySession->SetSwmtCategoriesL( categories );
					if( threadNameFilter.Length() > 0 )
						{
						iMemSpySession->SetSwmtFilter( threadNameFilter );
						}
					}								
					iMemSpySession->ForceSwmtUpdateL();				
				}
			}
    	}
    // --- KILL SERVER
    else if ( aCommand.CompareF( KMemSpyCmdKillServer ) == 0 )
    	{    
    	}
    
   // RedrawStatusMessage();   
    
    TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - END - err: %d, this: 0x%08x, cmd: %S" ), err, this, &aCommand ) );

    // Calculate duration
    TTime timeEnd;
    timeEnd.HomeTime();
    TTimeIntervalSeconds interval( 0 );
    timeEnd.SecondsFrom( timeStart, interval );

    // Print some info
    if  ( err != KErrNone )
        {
        RDebug::Print( _L("[MemSpyCmdLine] COMMAND: [%S] {%02d} {%08d sec} => ERROR: %d"), &aCommand, paramCount, interval.Int(), err );
        }
    else
        {
        RDebug::Print( _L("[MemSpyCmdLine] COMMAND: [%S] {%02d} {%08d sec} => OK"), &aCommand, paramCount, interval.Int() );
        }

    // Spacer
    RDebug::Printf( " " );
    }


void CMemSpyCommandLine::ConnectToMemSpyL()
    {
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - START - this: 0x%08x", this ) );

    TInt err = iMemSpySession->Connect();
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - connect #1 err: %d, this: 0x%08x", err, this ) );

    if  ( err == KErrNotFound )
        {
        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - launching MemSpy... - this: 0x%08x", this ) );
        LaunchMemSpyL();

        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - launched MemSpy - this: 0x%08x", this ) );
        err = iMemSpy->Connect();

        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - connect #2 err: %d, this: 0x%08x", err, this ) );
        }

    User::LeaveIfError( err );

    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - END - ok - this: 0x%08x", this ) );
    }


void CMemSpyCommandLine::LaunchMemSpyL()
    {
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - START - this: 0x%08x", this ) );

    TInt err = KErrGeneral;
    RProcess proc;
    
    // Try to run server first
    err = proc.Create( KMemSpyProcessName0, KNullDesC );
    if ( err == KErrNone )
    	{
		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create server process successfully... - this: 0x%08x", this ) );

		TRequestStatus status;
		proc.Rendezvous( status );
		proc.Resume();

		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );

		User::WaitForRequest( status );
		err = status.Int();
		proc.Close();

		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
    	}

    // If server is not available, try with s60 UI
    if ( err != KErrNone )
    	{
		err = proc.Create( KMemSpyProcessName1, KNullDesC );
		if  ( err == KErrNone )
			{
			TFullName fullName;
			proc.FullName( fullName );
			TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create S60 UI process successfully... - this: 0x%08x, name: %S"), this, &fullName ) );
	
			TRequestStatus status;
			proc.Rendezvous( status );
			proc.Resume();
	
			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
			User::WaitForRequest( status );
			err = status.Int();
			proc.Close();
	
			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
			}
    	}

    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - final error: %d, this: 0x%08x", err, this ) );
    User::LeaveIfError( err );
    User::After( 10 * 1000000 );

    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - END - ok - this: 0x%08x", this ) );
    }


CDesCArray* CMemSpyCommandLine::ReadLinesL( RFile& aFile )
    {
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - START - this: 0x%08x", this ) );
    CDesCArrayFlat* lines = new(ELeave) CDesCArrayFlat( 10 );
    CleanupStack::PushL( lines );

    TInt size = 0;
    User::LeaveIfError( aFile.Size( size ) );
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x, file size: %d", this, size ) );

    // Read file
    HBufC8* narrowBuf = HBufC8::NewLC( size );
    TPtr8 pBufNarrow( narrowBuf->Des() );
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x, reading file..." ) );
    User::LeaveIfError( aFile.Read( pBufNarrow ) );
    if  ( pBufNarrow.Length() <= 2 )
        {
        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x - BAD FILE LENGTH", this ) );
        User::Leave( KErrCorrupt );
        }

    // Look for BOM and convert to unicode
    HBufC* unicodeText = HBufC::NewL( size );
    TPtr pUnicodeText( unicodeText->Des() );
    if  ( pBufNarrow[0] == 0xFF && pBufNarrow[1] == 0xFE )
        {
        // It's unicode... and we don't want the BOM, hence -2
        const TInt textLength = size - 2;
        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x - UNICODE TEXT - textLength: %d", this, textLength / 2 ) );
        Mem::Copy( (TUint8 *)pUnicodeText.Ptr(), pBufNarrow.Ptr() + 2, textLength );
        pUnicodeText.SetLength( textLength / 2 );
        }
    else
        {
        // It's ASCII, convert it to unicode...
        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x - ASCII TEXT - textLength: %d", this, size ) );
        for (TInt i = 0; i<size; i++ )
            {
            pUnicodeText.Append( pBufNarrow[ i ] );
            }
        }

    // Discard old narrow text
    CleanupStack::PopAndDestroy( narrowBuf );
    CleanupStack::PushL( unicodeText );

    // Try to extract lines of text...
    HBufC* line = HBufC::NewLC( 1024 );
    TPtr pLine( line->Des() );
    const TInt length = unicodeText->Length();
    for( TInt i=0; i<length; i++ )
        {
        const TChar c( pUnicodeText[ i ] );
        //
        if  ( c == '\r' || c == '\n' )
            {
            pLine.Trim();
            if  ( pLine.Length() )
                {
                TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x - LINE[%03d] %S"), this, lines->Count(), line ) );
                lines->AppendL( pLine );
                }

            pLine.Zero();
            }
        else
            {
            pLine.Append( c );
            }
        }

    // Save last line, just in cae it didn't end with a CR/LF
    pLine.Trim();
    if ( pLine.Length() )
        {
        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - this: 0x%08x - LINE[%03d] %S"), this, lines->Count(), line ) );
        lines->AppendL( pLine );
        }

    CleanupStack::PopAndDestroy( 2, unicodeText ); // line & unicodeText
    CleanupStack::Pop( lines );
    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ReadLinesL() - END - this: 0x%08x", this ) );

    return lines;
    }


void CMemSpyCommandLine::ParseSWMTParametersL( const CDesCArray& aParameters, TInt& aCategories, TDes& aFilter )
    {
    TInt result(0);
    // Check if the first parameter is a number.
    // In that case other parameters are ignored.
    TLex lex( aParameters[ 0 ] );
    if ( lex.Val( result ) != KErrNone )
        {		
        // Parameters were given in text form:
        const TInt count( aParameters.Count() );
        for ( TInt i = 0; i < count ; i++ )
            {
			lex = aParameters[ i ]; //check if num.
            if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeHeap ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap |
                          TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeChunk ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryLocalChunks |
                          TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalChunks;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeCode ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryRAMLoadedCode;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeStack ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeGlobalData ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeRamDrive ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryRAMDrive;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeOpenFile ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryOpenFiles;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeDiskSpace ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryDiskusage;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeFbserv ) == 0 ) // enables both FABS and BITM 
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeHandleGeneric ) == 0 ) // enables both HGEN and HPAS
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHandles;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeFileServerCache ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryFileServerCache;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeSystemMemory ) == 0 )
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategorySystemMemory;
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeWindowGroup ) == 0 )            	
                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups;            
            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeAll) == 0 ) //"all" category added
            	result = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
            else if ( aParameters[i].CompareF( KMemSpyCmdSwmtParameterDumpnow) == 0 || 
            		aParameters[i].CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 || 
            		aParameters[i].CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 )
            	{    
				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: command parameter") );
            	}
            else if ( lex.Val( result ) == KErrNone )
            	{
				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: number - timer period") );
            	}
            else// if ( aParameters[i].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
                {				
                aFilter.Copy( aParameters[i].Right( aParameters[i].Length() -11 ) );              
                }
          /*  else
            	{
                //User::Leave( KErrNotSupported );            	            
            	}*/
            }
        }
    else if ( aParameters.Count() > 1 )//&& aParameters[1].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
        {
        aFilter.Copy( aParameters[1].Right( aParameters[1].Length() -11 ) );
        }
    aCategories = result;
    }


TInt CMemSpyCommandLine::FindBatchFile( TDes &aFileName )
    {
    if ( BaflUtils::FileExists( iFsSession, aFileName )) return KErrNone;
    if ( !FindFile( aFileName, _L("\\") ) ) return KErrNone;
    if ( !FindFile( aFileName, _L("\\data\\") ) ) return KErrNone;
    if ( !FindFile( aFileName, _L("\\documents\\") ) ) return KErrNone;
    if ( !FindFile( aFileName, _L("\\temp\\") ) ) return KErrNone;
    if ( !FindFile( aFileName, _L("\\system\\temp\\") ) ) return KErrNone;
    // if ( !FindFile( aFileName, _L("\\private\\1000484b\\") ) ) return KErrNone; // Mail folder KErrPermissionDenied  
    return KErrNotFound;
    }


TInt CMemSpyCommandLine::FindFile( TDes &aFileName, const TDesC &aDirPath )
    {
    TFindFile fileFinder( iFsSession );
    TInt err = fileFinder.FindByDir( aFileName, aDirPath );
    if ( !err )
        {
        aFileName.Copy( fileFinder.File() );
        }
    return err;
    }


//CLI status messages methods
void CMemSpyCommandLine::RedrawInputPrompt()
    {
    iConsole.SetCursorPosAbs( iCommandPromptPos );
    iConsole.ClearToEndOfLine();
    iConsole.Printf( KMemSpyCLIInputPrompt, &iCommandBuffer );
    }


void CMemSpyCommandLine::RedrawStatusMessage()
    {
    RedrawStatusMessage( KNullDesC );
    }


void CMemSpyCommandLine::RedrawStatusMessage( const TDesC& aMessage )
    {
    iConsole.SetCursorPosAbs( iStatusMessagePos );
    iConsole.ClearToEndOfLine();
    iConsole.Write( aMessage );
    iConsole.Write( KMemSpyCLINewLine );
    }

void CMemSpyCommandLine::WaitForInput()
    {
    ASSERT( !IsActive() );
    iConsole.Read( iStatus );
    SetActive();
    }

void CMemSpyCommandLine::DoCancel()
    {
    iConsole.ReadCancel();
    }

void CMemSpyCommandLine::RunL()
    {
    TKeyCode key = iConsole.KeyCode();
    //
    if  ( key == EKeyEnter || key == KMemSpyUiS60KeyCodeButtonOk || key == KMemSpyUiS60KeyCodeRockerEnter )
        {
        TRAP_IGNORE( ProcessCommandBufferL() );
        }
    else
        {
        TChar character( key );
        if  ( character.IsPrint() )
            {
            if  ( iCommandBuffer.Length() < iCommandBuffer.MaxLength() )
                {
                iCommandBuffer.Append( TChar( key ) );
                }

            RedrawInputPrompt();
            }
        }

    WaitForInput();
    }

TInt CMemSpyCommandLine::RunError( TInt aError )
	{	
	return KErrNone;
	}

void CMemSpyCommandLine::ProcessCommandBufferL()
    {
    iCommandBuffer.Trim();
    //
#ifdef _DEBUG
    RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::ProcessCommandBufferL() - cmd: [%S]"), &iCommandBuffer );
#endif
    //
    TBool validCommand = EFalse;
    if  ( iCommandBuffer.Length() == 1 )
        {
        // Reset if not recognised...
        validCommand = ETrue;

        const TChar cmd = iCommandBuffer[ 0 ]; 
        switch( cmd )
            {
        	case 's':
        	case 'S':
        		{
        		iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop );
        		
        		CActiveScheduler::Stop();
        		return;
        		}
        	case 'c':
        	case 'C':
        		CActiveScheduler::Stop();
        		return;            
        	default:
        		validCommand = EFalse;
        		break;
            }
        }    
    if  ( !validCommand )
        {
        _LIT( KInvalidEntry, "*** ERROR - Invalid Command ***" );
        RedrawStatusMessage( KInvalidEntry );
        RedrawInputPrompt();
        }
    }