analyzetool/storageserver/server/src/atstorageserversession.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 19 da2cedce4920
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Definitions and constants for the class CATStorageServerSession
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    <utf.h>
       
    22 #include    <analyzetool/analyzetooltraceconstants.h>
       
    23 #include    "atstorageserversession.h"
       
    24 #include    "atstorageserver.h"
       
    25 #include    "atstorageservercommon.h"
       
    26 #include    "atmemoryentry.h"
       
    27 #include    "atlog.h"
       
    28 #include    "atdynprocessinfo.h"
       
    29 #include    "atdriveinfo.h"
       
    30 
       
    31 // CONSTANTS
       
    32 
       
    33 // New file name start and end index.
       
    34 const TInt KNameIndexStart = 1;
       
    35 const TInt KNameIndexEnd = 100;
       
    36 
       
    37 // ==================== MEMBER FUNCTIONS for TAllocInfo ========================
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 // TAllocInfo::TAllocInfo
       
    41 // Implementation for the constructor of the class TAllocInfo
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 TAllocInfo::TAllocInfo( TUint32 aMemAddress, TInt aAllocSize ) :
       
    45     iMemAddress( aMemAddress ),
       
    46     iAllocSize( aAllocSize )
       
    47     {
       
    48     }
       
    49 
       
    50 
       
    51 // ============== MEMBER FUNCTIONS for CATStorageServerSession =================
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CATStorageServerSession::CATStorageServerSession
       
    55 // C++ default constructor. It Does not contain any code that
       
    56 // might leave.
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 CATStorageServerSession::CATStorageServerSession( CATStorageServer& aStorageServer ) :
       
    60     iStorageServer( aStorageServer ),
       
    61     iError( 0 ),
       
    62     iLeakArray( KLeakArrayGranularity ),
       
    63     iProcessId( KNullProcessId ),
       
    64     iLoggingOngoing( EFalse ),
       
    65     iLogOption( KDefaultLoggingMode ),
       
    66     iCurAllocSize( 0 ),
       
    67     iMaxAllocs( 0 ),
       
    68     iMaxAllocSize( 0 ),
       
    69     iLogFile( KEmpty() ),
       
    70     iIsUdeb( 1 )
       
    71     {
       
    72     LOGSTR1( "STSE CATStorageServerSession::CATStorageServerSession()" );
       
    73     
       
    74     // Initialize iMicroSecondsAt1970
       
    75     TTime time( KJanuaryFirst1970 );
       
    76     iMicroSecondsAt1970 = time.Int64();
       
    77     
       
    78     // Increment the server's session count by one (1)
       
    79     iStorageServer.IncSessionCount();
       
    80     }
       
    81 
       
    82 // -----------------------------------------------------------------------------
       
    83 // CATStorageServerSession::ConstructL
       
    84 // Symbian 2nd phase constructor can leave.
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 void CATStorageServerSession::ConstructL()
       
    88     {
       
    89     // Intentionally left empty
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // CATStorageServerSession::NewL
       
    94 // Two-phased constructor.
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 CATStorageServerSession* CATStorageServerSession::NewL( CATStorageServer& aStorageServer )
       
    98     { 
       
    99     CATStorageServerSession* self = NewLC( aStorageServer );
       
   100     CleanupStack::Pop( self );
       
   101     
       
   102     return self;
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CATStorageServerSession::NewLC
       
   107 // Two-phased constructor.
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 CATStorageServerSession* CATStorageServerSession::NewLC( CATStorageServer& aStorageServer )
       
   111     { 
       
   112     CATStorageServerSession* self = new ( ELeave ) CATStorageServerSession( aStorageServer );
       
   113     
       
   114     CleanupStack::PushL( self );
       
   115     self->ConstructL();
       
   116     return self;
       
   117     }
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CATStorageServerSession::~CATStorageServerSession
       
   121 // Destructor
       
   122 // -----------------------------------------------------------------------------
       
   123 CATStorageServerSession::~CATStorageServerSession()
       
   124     {
       
   125     LOGSTR1( "STSE CATStorageServerSession::~CATStorageServerSession()" );
       
   126       
       
   127     // Empty the array and delete the referenced objects
       
   128     iLeakArray.ResetAndDestroy();
       
   129   
       
   130     // Close the leak array
       
   131     iLeakArray.Close();
       
   132     
       
   133     // Close the allocation info array
       
   134     iAllocInfoArray.Close();
       
   135     
       
   136     // Check if process closed abnormal
       
   137     if ( iProcessId != KNullProcessId && 
       
   138          iLoggingOngoing && iLogOption != EATLoggingOff && 
       
   139          iError != KErrNoMemory )
       
   140         {
       
   141         LogAbnormalEnd();
       
   142         }
       
   143     
       
   144     // Close the file and the handle to the file server
       
   145     CloseFsAndFile();
       
   146     
       
   147     // Remove the process with the current PID from the server's array of processes
       
   148     TRAP_IGNORE( iStorageServer.RemoveProcessL( iProcessId ) );
       
   149     
       
   150     // Decrement the server's session count by one (1)
       
   151     iStorageServer.DecSessionCount();
       
   152     }
       
   153     
       
   154 // -----------------------------------------------------------------------------
       
   155 // CATStorageServerSession::ServiceL
       
   156 // This function is called by the client/server framework
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 void CATStorageServerSession::ServiceL( const RMessage2& aMessage )
       
   160     {
       
   161     LOGSTR1( "STSE void CATStorageServerSession::ServiceL()" );
       
   162     
       
   163     // If logging has been cancelled for this session, return immediately
       
   164     if( iLogOption == EATLoggingOff )
       
   165         {
       
   166         aMessage.Complete( KErrCancel );
       
   167         return;
       
   168         }
       
   169     
       
   170     switch ( aMessage.Function() )
       
   171         {
       
   172         case CATStorageServer::EProcessStarted:
       
   173             {
       
   174             // If logging is not ongoing, set the log option
       
   175             if( !iLoggingOngoing )
       
   176                 {
       
   177                 // Set the operation mode
       
   178                 SetLogOption( aMessage );
       
   179                 }
       
   180 
       
   181             switch ( iLogOption )
       
   182                 {
       
   183                 case EATLogToTrace:
       
   184                     {
       
   185                     iError = LogProcessStartTraceL( aMessage );
       
   186                     }
       
   187                 break;
       
   188                 
       
   189                 case EATLogToFile:
       
   190                     {
       
   191                     iError = LogProcessStartedL( aMessage );
       
   192                     }
       
   193                 break;
       
   194                 
       
   195                 default:
       
   196                     {
       
   197                     // Panic the client and set iError KErrCancel, because being
       
   198                     // here implies that an illegal log option has been given.
       
   199                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   200                     iError = KErrCancel;
       
   201                     }
       
   202                 break;
       
   203                 }
       
   204             } 
       
   205         break;
       
   206         
       
   207         
       
   208         case CATStorageServer::EDllLoaded:
       
   209             {
       
   210             switch ( iLogOption )
       
   211                 {
       
   212                 case EATLogToTrace:
       
   213                     {
       
   214                     iError = LogDllLoadTraceL( aMessage );
       
   215                     }
       
   216                 break;
       
   217                 
       
   218                 case EATLogToFile:
       
   219                     {
       
   220                     iError = LogDllLoadedL( aMessage );
       
   221                     }
       
   222                 break;
       
   223                 
       
   224                 default:
       
   225                     {
       
   226                     // Panic the client and set iError KErrCancel, because being
       
   227                     // here implies that an illegal log option has been given.
       
   228                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   229                     iError = KErrCancel;
       
   230                     }
       
   231                 break;
       
   232                 }
       
   233             }
       
   234         break;
       
   235         
       
   236         
       
   237         case CATStorageServer::EDllUnloaded:
       
   238             {
       
   239             switch ( iLogOption )
       
   240                 {
       
   241                 case EATLogToTrace:
       
   242                     {
       
   243                     iError = LogDllUnloadTraceL( aMessage );
       
   244                     }
       
   245                 break;
       
   246                 
       
   247                 case EATLogToFile:
       
   248                     {
       
   249                     iError = LogDllUnloadedL( aMessage );
       
   250                     }
       
   251                 break;
       
   252                 
       
   253                 default:
       
   254                     {
       
   255                     // Panic the client and set iError KErrCancel, because being
       
   256                     // here implies that an illegal log option has been given.
       
   257                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   258                     iError = KErrCancel;
       
   259                     }
       
   260                 break;
       
   261                 }
       
   262             }
       
   263         break;
       
   264         
       
   265         
       
   266         case CATStorageServer::EMemoryAllocated:
       
   267             {
       
   268             switch ( iLogOption )
       
   269                 {
       
   270                 case EATLogToTrace:
       
   271                     {
       
   272                     iError = LogMemoryAllocTraceL( aMessage );
       
   273                     }
       
   274                 break;
       
   275                 
       
   276                 case EATLogToFile:
       
   277                     {
       
   278                     iError = LogMemoryAllocatedL( aMessage );
       
   279                     }
       
   280                 break;
       
   281                 
       
   282                 default:
       
   283                     {
       
   284                     // Panic the client and set iError KErrCancel, because being
       
   285                     // here implies that an illegal log option has been given.
       
   286                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   287                     iError = KErrCancel;
       
   288                     }
       
   289                 break;
       
   290                 }
       
   291             }
       
   292         break;
       
   293         
       
   294         
       
   295         case CATStorageServer::EMemoryFreed:
       
   296             {
       
   297             switch ( iLogOption )
       
   298                 {
       
   299                 case EATLogToTrace:
       
   300                     {
       
   301                     iError = LogMemoryFreedTraceL( aMessage );
       
   302                     }
       
   303                 break;
       
   304                 
       
   305                 case EATLogToFile:
       
   306                     {
       
   307                     iError = LogMemoryFreedL( aMessage );
       
   308                     }
       
   309                 break;
       
   310                 
       
   311                 default:
       
   312                     {
       
   313                     // Panic the client and set iError KErrCancel, because being
       
   314                     // here implies that an illegal log option has been given.
       
   315                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   316                     iError = KErrCancel;
       
   317                     }
       
   318                 break;
       
   319                 }
       
   320             }
       
   321         break;
       
   322         
       
   323         
       
   324         case CATStorageServer::EProcessEnded:
       
   325             {
       
   326             switch ( iLogOption )
       
   327                 {
       
   328                 case EATLogToTrace:
       
   329                     {
       
   330                     iError = LogProcessEndTraceL( aMessage );
       
   331                     }
       
   332                 break;
       
   333                 
       
   334                 case EATLogToFile:
       
   335                     {
       
   336                     iError = LogProcessEndedL( aMessage );
       
   337                     }
       
   338                 break;
       
   339                 
       
   340                 default:
       
   341                     {
       
   342                     // Panic the client and set iError KErrCancel, because being
       
   343                     // here implies that an illegal log option has been given.
       
   344                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   345                     iError = KErrCancel;
       
   346                     }
       
   347                 break;
       
   348                 }
       
   349             }
       
   350         break;
       
   351         
       
   352         
       
   353         case CATStorageServer::EMemoryCheck:
       
   354             {
       
   355             switch ( iLogOption )
       
   356                 {
       
   357                 case EATLogToTrace:
       
   358                     {
       
   359                     iError = CheckMemoryAddressTrace( aMessage );
       
   360                     }
       
   361                 break;
       
   362                 
       
   363                 case EATLogToFile:
       
   364                     {
       
   365                     iError = CheckMemoryAddressL( aMessage );
       
   366                     }
       
   367                 break;
       
   368                 
       
   369                 default:
       
   370                     {
       
   371                     // Panic the client and set iError KErrCancel, because being
       
   372                     // here implies that an illegal log option has been given.
       
   373                     PanicClient( EAToolIllegalLogOption, aMessage );
       
   374                     iError = KErrCancel;
       
   375                     }
       
   376                 break;
       
   377                 }
       
   378             }
       
   379         break;
       
   380         
       
   381         
       
   382         case CATStorageServer::EGetProcesses:
       
   383             {
       
   384             iError = GetProcessesL( aMessage );
       
   385             }
       
   386         break;
       
   387         
       
   388         
       
   389         case CATStorageServer::EGetDlls:
       
   390             {
       
   391             iError = GetDllsL( aMessage );
       
   392             }
       
   393         break;
       
   394         
       
   395         case CATStorageServer::EGetLoggingMode:
       
   396             {
       
   397             iError = GetLoggingModeL( aMessage );
       
   398             }
       
   399         break;
       
   400         
       
   401         case CATStorageServer::ESubtestStart:
       
   402             {
       
   403             iError = StartSubtestL( aMessage );
       
   404             }
       
   405         break;
       
   406         
       
   407         case CATStorageServer::ESubtestStop:
       
   408             {
       
   409             iError = StopSubtestL( aMessage );
       
   410             }
       
   411         break;
       
   412         
       
   413         case CATStorageServer::ESubtestStart2:
       
   414             {
       
   415             iError = StartSubtest2L( aMessage );
       
   416             }
       
   417         break;
       
   418                
       
   419         case CATStorageServer::ESubtestStop2:
       
   420             {
       
   421             iError = StopSubtest2( aMessage );
       
   422             }
       
   423         break;
       
   424         
       
   425         case CATStorageServer::EGetCurrentAllocs:
       
   426             {
       
   427             iError = GetCurrentAllocsL( aMessage );
       
   428             }
       
   429         break;
       
   430         
       
   431         case CATStorageServer::EGetMaxAllocs:
       
   432             {
       
   433             iError = GetMaxAllocsL( aMessage );
       
   434             }
       
   435         break;
       
   436         
       
   437         case CATStorageServer::ECancelLogging:
       
   438             {
       
   439             iError = CancelLoggingL( aMessage );
       
   440             }
       
   441         break;
       
   442 
       
   443         case CATStorageServer::EGetUdeb:
       
   444             {
       
   445             iError = GetUdebL( aMessage );
       
   446             }
       
   447         break;
       
   448         
       
   449         case CATStorageServer::EGetLoggingFile:
       
   450             {
       
   451             iError = GetLoggingFileL( aMessage );
       
   452             }
       
   453         break;
       
   454 
       
   455         case CATStorageServer::EProcessUdeb:
       
   456             {
       
   457             SetUdeb( aMessage );
       
   458             }
       
   459         break;
       
   460         
       
   461         case CATStorageServer::EIsMemoryAdded:
       
   462             {
       
   463             iError = IsMemoryAdded( aMessage );
       
   464             LOGSTR2( "STSE > IsMemoryAdded err = %i", iError );
       
   465             }
       
   466         break;       
       
   467         
       
   468         default:
       
   469             {
       
   470             // Panic both the client and server, because being here implies
       
   471             // that there is an internal error in the client/server.
       
   472             PanicClient( EAToolBadRequest, aMessage );
       
   473             StorageServerPanic( KCategoryServer, EAToolBadRequest );
       
   474             }
       
   475         break;
       
   476             
       
   477         }
       
   478     
       
   479     // Complete the message, if it has not been already cancelled.
       
   480     if ( iError != KErrCancel )
       
   481         {
       
   482         // Log the error code. Only KErrNoMemory errors are logged.
       
   483         if ( iLogOption == EATLogToFile && iError == KErrNoMemory  )
       
   484             {
       
   485             HandleError( iError );
       
   486             }
       
   487         else if ( iLogOption == EATLogToTrace && iError == KErrNoMemory )
       
   488             {
       
   489             HandleErrorTrace( iError );
       
   490             }
       
   491                
       
   492         // Complete serving the message 
       
   493         aMessage.Complete( iError );
       
   494         }
       
   495     }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // CATStorageServerSession::LogProcessStartedL()
       
   499 // Opens a logging file with the requested name and then writes information
       
   500 // on process start into the file.
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 TInt CATStorageServerSession::LogProcessStartedL( const RMessage2& aMessage )
       
   504     {
       
   505     LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartedL()" );
       
   506     
       
   507     // Panic the client and return, if this method has already been called for this
       
   508     // session object (and a logging file has been opened)
       
   509     if ( iLoggingOngoing )
       
   510         {
       
   511         PanicClient( EAToolNotAllowed, aMessage );
       
   512         return KErrCancel;
       
   513         }
       
   514     
       
   515     iError = KErrNone;
       
   516     
       
   517     LOGMEM;
       
   518     
       
   519     // READ THE FIRST ARGUMENT (descriptor)  
       
   520     
       
   521     // Length of the first argument (index 0)
       
   522     TInt length = aMessage.GetDesLength( 0 );
       
   523     
       
   524     LOGSTR2( "STSE length of the fileName: %i", length );
       
   525     
       
   526     // Return if errors
       
   527     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   528         {
       
   529         return length;
       
   530         }
       
   531     
       
   532     // Construct a buffer for file name, and leave the pointer on Cleanup Stack
       
   533     HBufC* fileName = HBufC::NewLC( length );
       
   534     TPtr fileNamePtr( fileName->Des() );
       
   535      
       
   536     // Read the client side's descriptor at index 0
       
   537     iError = aMessage.Read( 0, fileNamePtr );
       
   538     
       
   539     if ( iError != KErrNone )
       
   540         {
       
   541         CleanupStack::PopAndDestroy( fileName );
       
   542         return iError;
       
   543         }
       
   544     
       
   545     // READ THE SECOND ARGUMENT (descriptor)  
       
   546     
       
   547     // Length of the second argument (index 1)   
       
   548     length = aMessage.GetDesLength( 1 );
       
   549     
       
   550     LOGSTR2( "STSE length of the processName: %i", length );
       
   551     
       
   552     // Return if errors
       
   553     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   554         {
       
   555         CleanupStack::PopAndDestroy( fileName );
       
   556         return length;
       
   557         }
       
   558     
       
   559     HBufC8* processName = HBufC8::NewL( length );
       
   560     TPtr8 bufPtr( processName->Des() );
       
   561 
       
   562     // Read the client side's descriptor at index 1 
       
   563     iError = aMessage.Read( 1, bufPtr );
       
   564   
       
   565     if ( iError != KErrNone )
       
   566         {
       
   567         delete processName;
       
   568         CleanupStack::PopAndDestroy( fileName );
       
   569         return iError;
       
   570         }
       
   571     
       
   572     // READ THE THIRD ARGUMENT (integer, a process ID)    
       
   573     TInt processId = aMessage.Int2();
       
   574     
       
   575     // Open a file server session and a file. The file
       
   576     // will be opened with the name received from the client
       
   577     iError = OpenFsAndFile( *fileName, *processName );
       
   578     CleanupStack::PopAndDestroy( fileName );
       
   579     // Return without logging, if an error occured
       
   580     if ( iError != KErrNone )
       
   581         {
       
   582         // Delete the local objects
       
   583         delete processName;
       
   584         return iError;
       
   585         }
       
   586     
       
   587     // Get the home time for the configuration UI
       
   588     iTime.HomeTime();
       
   589     
       
   590     // Add the process into the server's array of processes
       
   591     iError = iStorageServer.AddProcessL( *processName,
       
   592                                         processId,
       
   593                                         this,
       
   594                                         iTime.Int64() );
       
   595 
       
   596     // Return without logging, if an error occured
       
   597     if ( iError )
       
   598         {
       
   599         // Remove, if something was added regardless of the error
       
   600         // However, we must not remove an existing process
       
   601         if ( iError != KErrAlreadyExists )
       
   602             {
       
   603             iStorageServer.RemoveProcessL( processId );
       
   604             }
       
   605         return iError;
       
   606         }
       
   607       
       
   608     // Make a buffer that will be logged into the opened logging file
       
   609     TBuf8<KProcessStartBufLength> loggingBuf;
       
   610     loggingBuf.Format( KProcessStart, processName, processId );
       
   611     
       
   612     delete processName;
       
   613     
       
   614     // Get the current universal time       
       
   615     TInt64 timeFrom1970( GetTime() );
       
   616     
       
   617     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
   618     // format
       
   619     loggingBuf.AppendNum( timeFrom1970, EHex );
       
   620     
       
   621     // Append udeb/urel information to the process start
       
   622     loggingBuf.Append( KSpace );  
       
   623     loggingBuf.AppendNum( iIsUdeb, EHex );
       
   624     
       
   625     // Append trace version information
       
   626     loggingBuf.Append( KSpace );
       
   627     loggingBuf.AppendNum( KATTraceVersion, EHex );
       
   628     
       
   629     // Append a new line
       
   630     loggingBuf.Append( KNewLine );
       
   631     
       
   632     // Write the buffer into the file  
       
   633     iError = iFile.Write( loggingBuf );
       
   634     
       
   635     // Return, if an error occured
       
   636     if ( iError )
       
   637         {
       
   638         iStorageServer.RemoveProcessL( processId );
       
   639         return iError;
       
   640         }
       
   641     
       
   642     LOGMEM;
       
   643     
       
   644     // Set the process ID value for this logging session
       
   645     iProcessId = processId;
       
   646     // Set logging session started
       
   647     iLoggingOngoing = ETrue;
       
   648     
       
   649     return iError;
       
   650     }
       
   651     
       
   652 // -----------------------------------------------------------------------------
       
   653 // CATStorageServerSession::LogProcessStartTraceL()
       
   654 // -----------------------------------------------------------------------------
       
   655 //    
       
   656 TInt CATStorageServerSession::LogProcessStartTraceL( const RMessage2& aMessage )
       
   657     {
       
   658     LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartTraceL()" );
       
   659     
       
   660     // Panic the client and return, if this method has already been called for this
       
   661     // session object
       
   662     if ( iLoggingOngoing )
       
   663         {
       
   664         PanicClient( EAToolNotAllowed, aMessage );
       
   665         return KErrCancel;
       
   666         }
       
   667     
       
   668     iError = KErrNone;
       
   669     
       
   670     LOGMEM;
       
   671     
       
   672     // READ THE SECOND ARGUMENT (descriptor)
       
   673     // The first argument, file name, is ignored when logging thru trace  
       
   674     
       
   675     // Length of the second argument (index 1)
       
   676     TInt length = aMessage.GetDesLength( 1 );
       
   677     
       
   678     LOGSTR2( "STSE length of the processName: %i", length );
       
   679 
       
   680     // Return if errors
       
   681     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   682         {
       
   683         return length;
       
   684         }
       
   685 
       
   686     HBufC8* processName = HBufC8::NewL( length );
       
   687     TPtr8 bufPtr( processName->Des() );
       
   688 
       
   689     // Read the client side's descriptor at index 1 
       
   690     iError = aMessage.Read( 1, bufPtr );
       
   691   
       
   692     if ( iError != KErrNone )
       
   693         {
       
   694         // Delete local objects and return
       
   695         delete processName;
       
   696         return iError;
       
   697         }
       
   698     
       
   699     // READ THE THIRD ARGUMENT (integer, a process ID)    
       
   700     TInt processId = aMessage.Int2();
       
   701 
       
   702     // Get the home time for the configuration UI
       
   703     iTime.HomeTime();
       
   704     
       
   705     // Add the process into the server's array of processes
       
   706     iError = iStorageServer.AddProcessL( *processName, processId, this,
       
   707                                              iTime.Int64() );
       
   708     
       
   709     // Return without logging, if an error occured
       
   710     if ( iError )
       
   711         {
       
   712         // Remove, if something was added regardless of the error
       
   713         // However, we must not remove an existing process
       
   714         if ( iError != KErrAlreadyExists )
       
   715             {
       
   716             iStorageServer.RemoveProcessL( processId );
       
   717             }
       
   718         return iError;
       
   719         }
       
   720 
       
   721     // Make a buffer that will be logged
       
   722     TBuf8<KProcessStartBufLength> loggingBuf;
       
   723     
       
   724     loggingBuf.Format( KProcessStart, processName, processId );
       
   725     
       
   726     delete processName;
       
   727     
       
   728     // Get the current universal time      
       
   729     TInt64 timeFrom1970( GetTime() );
       
   730     
       
   731     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
   732     // format
       
   733     loggingBuf.AppendNum( timeFrom1970, EHex );
       
   734     
       
   735     // Append udeb/urel information to the process start
       
   736     loggingBuf.Append( KSpace );
       
   737     loggingBuf.AppendNum( iIsUdeb, EHex );
       
   738     
       
   739     // Append version number
       
   740     loggingBuf.Append( KSpace );  
       
   741     loggingBuf.AppendNum( KATTraceVersion, EHex );
       
   742     
       
   743     // Append a new line
       
   744     loggingBuf.Append( KNewLine );
       
   745     
       
   746     // Log to trace
       
   747     TBuf<KProcessStartBufLength> traceBuf;
       
   748     traceBuf.Copy( loggingBuf );
       
   749     RDebug::Print( KTraceMessage, processId ,&traceBuf );
       
   750     
       
   751     LOGMEM;
       
   752     
       
   753     // Set the process ID value for this logging session
       
   754     iProcessId = processId;
       
   755     // Set logging session started
       
   756     iLoggingOngoing = ETrue;
       
   757     
       
   758     return KErrNone;
       
   759     }
       
   760 
       
   761 // -----------------------------------------------------------------------------
       
   762 // CATStorageServerSession::LogDllLoadedL()
       
   763 // Logs to the file opened by the function LogProcessStartedL()
       
   764 // -----------------------------------------------------------------------------
       
   765 //
       
   766 TInt CATStorageServerSession::LogDllLoadedL( const RMessage2& aMessage )
       
   767     {
       
   768     LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadedL()" );
       
   769     
       
   770     // Panic the client and return, if a logging session is not ongoing
       
   771     // ( can be started by calling the client's LogProcessStarted() )
       
   772     if ( !iLoggingOngoing )
       
   773         {
       
   774         PanicClient( EAToolNotAllowed, aMessage );
       
   775         return KErrCancel;
       
   776         }
       
   777     
       
   778     iError = KErrNone;
       
   779     
       
   780     // Read the length of the first argument (index 0)   
       
   781     TInt length = aMessage.GetDesLength( 0 );
       
   782     
       
   783     // Return if errors
       
   784     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   785         {
       
   786         return length;
       
   787         }
       
   788     
       
   789     HBufC8* dllName = HBufC8::NewL( length );
       
   790     TPtr8 bufPtr( dllName->Des() );
       
   791 
       
   792     // Read the client side's descriptor (the argument 0) 
       
   793     iError = aMessage.Read( 0, bufPtr );
       
   794   
       
   795     if ( iError != KErrNone )
       
   796         {
       
   797         delete dllName;
       
   798         return iError;
       
   799         }
       
   800     
       
   801     // Get the current universal time
       
   802 	TInt64 timeFrom1970( GetTime() );
       
   803         
       
   804     // Add this dll into the server's array
       
   805     TUint32 startAddress( aMessage.Int1() );        
       
   806     TUint32 endAddress( aMessage.Int2() );
       
   807     iError = iStorageServer.AddDllL( iProcessId, 
       
   808     		TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
       
   809     
       
   810     // Return without logging, if an error occured
       
   811     if ( iError )
       
   812         {
       
   813         delete dllName;
       
   814         return iError;
       
   815         }
       
   816     
       
   817     // Make a buffer that will be logged into the opened logging file
       
   818     TBuf8<KDllLoadBufLength> loggingBuf;
       
   819     loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
       
   820     
       
   821     delete dllName;
       
   822     
       
   823     // Write the buffer into a file and return the error code   
       
   824     return iFile.Write( loggingBuf );
       
   825     }
       
   826     
       
   827 // -----------------------------------------------------------------------------
       
   828 // CATStorageServerSession::LogDllLoadTraceL()
       
   829 // -----------------------------------------------------------------------------
       
   830 //    
       
   831 TInt CATStorageServerSession::LogDllLoadTraceL( const RMessage2& aMessage )
       
   832     {
       
   833     LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadTraceL()" );
       
   834     
       
   835     // Panic the client and return, if a logging session is not ongoing
       
   836     // ( can be started by calling the client's LogProcessStarted() )
       
   837     if ( !iLoggingOngoing )
       
   838         {
       
   839         PanicClient( EAToolNotAllowed, aMessage );
       
   840         return KErrCancel;
       
   841         }
       
   842     
       
   843     iError = KErrNone;
       
   844     
       
   845     // Read the length of the first argument (index 0)
       
   846     TInt length = aMessage.GetDesLength( 0 );
       
   847     
       
   848     // Return if errors
       
   849     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   850         {
       
   851         return length;
       
   852         }
       
   853     
       
   854     HBufC8* dllName = HBufC8::NewL( length );
       
   855     TPtr8 bufPtr( dllName->Des() );
       
   856 
       
   857     // Read the client side's descriptor (the argument 0) 
       
   858     iError = aMessage.Read( 0, bufPtr );
       
   859   
       
   860     if ( iError != KErrNone )
       
   861         {
       
   862         delete dllName;
       
   863         return iError;
       
   864         }
       
   865     // Get the current universal time
       
   866 	TInt64 timeFrom1970( GetTime() );
       
   867     	
       
   868     TUint32 startAddress( aMessage.Int1() );
       
   869     TUint32 endAddress( aMessage.Int2() );
       
   870         
       
   871     // Add this dll into the server's array 
       
   872     iError = iStorageServer.AddDllL( iProcessId, 
       
   873     		TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
       
   874     
       
   875     // Return without logging, if an error occured
       
   876     if ( iError )
       
   877         {
       
   878         delete dllName;
       
   879         return iError;
       
   880         }
       
   881     
       
   882     // Make a buffer that will be logged
       
   883     TBuf8<KDllLoadBufLength> loggingBuf;
       
   884     loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
       
   885     
       
   886     delete dllName;
       
   887     
       
   888     TBuf<KDllLoadBufLength> traceBuf;
       
   889     traceBuf.Copy( loggingBuf );
       
   890     RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
       
   891     return iError;
       
   892     }
       
   893     
       
   894 // -----------------------------------------------------------------------------
       
   895 // CATStorageServerSession::LogDllUnloadedL()
       
   896 // Logs to the file opened by the function LogProcessStartedL()
       
   897 // -----------------------------------------------------------------------------
       
   898 //
       
   899 TInt CATStorageServerSession::LogDllUnloadedL( const RMessage2& aMessage )
       
   900     {
       
   901     LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadedL()" );
       
   902     
       
   903     // Panic the client and return, if a logging session is not ongoing
       
   904     // ( can be started by calling the client's LogProcessStarted() )
       
   905     if ( !iLoggingOngoing )
       
   906         {
       
   907         PanicClient( EAToolNotAllowed, aMessage );
       
   908         return KErrCancel;
       
   909         }
       
   910     
       
   911     iError = KErrNone;
       
   912     
       
   913     // Read the length of the first argument (index 0)   
       
   914     TInt length = aMessage.GetDesLength( 0 );
       
   915     
       
   916     LOGSTR2( "STSE length %i", length );
       
   917     
       
   918     // Return if errors
       
   919     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   920         {
       
   921         return length;
       
   922         }
       
   923     
       
   924     HBufC8* dllName = HBufC8::NewL( length );
       
   925     TPtr8 bufPtr( dllName->Des() );
       
   926 
       
   927     // Read the client side's descriptor (the argument 0) 
       
   928     iError = aMessage.Read( 0, bufPtr );
       
   929   
       
   930     if ( iError != KErrNone )
       
   931         {
       
   932         delete dllName;
       
   933         return iError;
       
   934         }
       
   935        
       
   936     TUint32 startAddress = aMessage.Int1();
       
   937     TUint32 endAddress = aMessage.Int2();
       
   938     
       
   939     // Get the current universal time
       
   940     TInt64 timeFrom1970( GetTime() );
       
   941         
       
   942     // Make a buffer that will be logged into the opened logging file
       
   943     TBuf8<KDllUnloadBufLength> loggingBuf;
       
   944     loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
       
   945     
       
   946     // Remove this dll from the server's array
       
   947     iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
       
   948     
       
   949     delete dllName;
       
   950     
       
   951     // Return without logging, if an error occured
       
   952     if ( iError )
       
   953         {
       
   954         return iError;
       
   955         }
       
   956      
       
   957     // Write the buffer into a file and return the error code   
       
   958     return iFile.Write( loggingBuf );
       
   959     }
       
   960  
       
   961 // -----------------------------------------------------------------------------
       
   962 // CATStorageServerSession::LogDllUnloadTraceL()
       
   963 // -----------------------------------------------------------------------------
       
   964 //    
       
   965 TInt CATStorageServerSession::LogDllUnloadTraceL( const RMessage2& aMessage )
       
   966     {
       
   967     LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadTraceL()" );
       
   968     
       
   969     // Panic the client and return, if a logging session is not ongoing
       
   970     // ( can be started by calling the client's LogProcessStarted() )
       
   971     if ( !iLoggingOngoing )
       
   972         {
       
   973         PanicClient( EAToolNotAllowed, aMessage );
       
   974         return KErrCancel;
       
   975         }
       
   976         
       
   977     iError = KErrNone;
       
   978     
       
   979     // Read the length of the first argument (index 0)   
       
   980     TInt length = aMessage.GetDesLength( 0 );
       
   981     
       
   982     LOGSTR2( "STSE length %i", length );
       
   983     
       
   984     // Return if errors
       
   985     if ( length == KErrArgument || length == KErrBadDescriptor )
       
   986         {
       
   987         return length;
       
   988         }
       
   989     
       
   990     HBufC8* dllName = HBufC8::NewL( length );
       
   991     TPtr8 bufPtr( dllName->Des() );
       
   992 
       
   993     // Read the client side's descriptor (the argument 0) 
       
   994     iError = aMessage.Read( 0, bufPtr );
       
   995   
       
   996     if ( iError != KErrNone )
       
   997         {
       
   998         delete dllName;
       
   999         return iError;
       
  1000         }
       
  1001     
       
  1002     TUint32 startAddress = aMessage.Int1();
       
  1003     TUint32 endAddress = aMessage.Int2();
       
  1004     
       
  1005     // Get the current universal time
       
  1006     TInt64 timeFrom1970( GetTime() );
       
  1007         
       
  1008     // Make a buffer that will be logged
       
  1009     TBuf8<KDllUnloadBufLength> loggingBuf;
       
  1010     loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
       
  1011     
       
  1012     // Remove this dll from the server's array
       
  1013     iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
       
  1014     
       
  1015     delete dllName;
       
  1016     
       
  1017     // Return without logging, if an error occured
       
  1018     if ( iError )
       
  1019         {
       
  1020         return iError;
       
  1021         }
       
  1022     
       
  1023     TBuf<KDllLoadBufLength> traceBuf;
       
  1024     traceBuf.Copy( loggingBuf );
       
  1025     RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
       
  1026     return iError;
       
  1027     }
       
  1028     
       
  1029 // -----------------------------------------------------------------------------
       
  1030 // CATStorageServerSession::LogMemoryAllocatedL()
       
  1031 // Constructs a CATMemoryEntry object and appends it into iLeakArray.
       
  1032 // -----------------------------------------------------------------------------
       
  1033 //
       
  1034 TInt CATStorageServerSession::LogMemoryAllocatedL( const RMessage2& aMessage )
       
  1035     {
       
  1036     LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocatedL()" );
       
  1037     
       
  1038     // Panic the client and return, if a logging session is not ongoing
       
  1039     // ( can be started by calling the client's LogProcessStarted() )
       
  1040     if ( !iLoggingOngoing )
       
  1041         {
       
  1042         PanicClient( EAToolNotAllowed, aMessage );
       
  1043         return KErrCancel;
       
  1044         }     
       
  1045     
       
  1046     // A pointer to a buffer of call stack's memory addresses
       
  1047     CBufFlat* stackBuf = NULL;
       
  1048     
       
  1049     iError = KErrNone;
       
  1050     
       
  1051     // Get the current universal time
       
  1052     TInt64 timeFrom1970( GetTime() );
       
  1053     
       
  1054     // Read the first argument (index 0)
       
  1055     TUint32 memAddress = aMessage.Int0();
       
  1056     if ( memAddress == 0 )
       
  1057         {
       
  1058         return KErrNotSupported;
       
  1059         }
       
  1060     
       
  1061     // Read the length of the descriptor argument (index 1) that should include
       
  1062     // call stack memory addresses associated with this memory allocation
       
  1063     TInt bufferLength = aMessage.GetDesLength( 1 );
       
  1064     
       
  1065     // Construct a buffer for aCallstack
       
  1066     stackBuf = CBufFlat::NewL( bufferLength );
       
  1067     CleanupStack::PushL( stackBuf );
       
  1068     
       
  1069     // Buffer position
       
  1070     TInt pos = 0;
       
  1071     
       
  1072     stackBuf->ExpandL( pos, bufferLength );
       
  1073 
       
  1074     TPtr8 bufPtr = stackBuf->Ptr( pos );
       
  1075 
       
  1076     // Read the descriptor argument into the buffer
       
  1077     aMessage.ReadL( 1, bufPtr );
       
  1078 
       
  1079     // Read the third argument (index 2) that tells the size of this allocation
       
  1080     TInt size = aMessage.Int2();
       
  1081     
       
  1082     // Construct a new CATMemoryEntry object.   
       
  1083     // The ownership of the current stackBuf object is given to the "entry" object.
       
  1084     CATMemoryEntry* entry = 
       
  1085         new (ELeave) CATMemoryEntry( memAddress, stackBuf, timeFrom1970, size );
       
  1086     
       
  1087     // Pop stackBuf from CleanupStack and set it to NULL, because it is not used anymore.
       
  1088     CleanupStack::Pop( stackBuf );
       
  1089     stackBuf = NULL;
       
  1090     
       
  1091     // Make sure that the same memory area is not tryed to be allocated a second time
       
  1092     TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
       
  1093 
       
  1094     TInt index = iLeakArray.Find( entry, matcher );
       
  1095     
       
  1096     if ( index == KErrNotFound )
       
  1097         {
       
  1098         TLinearOrder<CATMemoryEntry> order( CATMemoryEntry::Compare );
       
  1099         
       
  1100         // Insert the "entry" object into "iLeakArray". The ownership of
       
  1101         // the "entry" object is given to the array.
       
  1102         iError = iLeakArray.InsertInOrderAllowRepeats( entry, order );
       
  1103                
       
  1104         // If an insertion to the array was not successful, delete the created
       
  1105         // entry manually and return.
       
  1106         if ( iError )
       
  1107             {
       
  1108             delete entry;
       
  1109             return iError;
       
  1110             }
       
  1111         
       
  1112         // Make a TAllocInfo object, and give values for its members.
       
  1113         TAllocInfo allocInfo( memAddress, size );
       
  1114 
       
  1115         // Insert the allocInfo object into iAllocInfoArray
       
  1116         iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
       
  1117     
       
  1118         // If an insertion to the array was not successful, delete the created entry
       
  1119         // and remove its pointer from iLeakArray.
       
  1120         if ( iError )
       
  1121             {
       
  1122             index = iLeakArray.Find( entry, matcher );
       
  1123             // Delete the entry object and remove remove the pointer from the array
       
  1124             delete entry;
       
  1125             // The index should be in a legal range, because the earlier insertion of
       
  1126             // the entry was successful
       
  1127             iLeakArray.Remove( index );
       
  1128             }
       
  1129         
       
  1130         // Otherwise update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables
       
  1131         
       
  1132         iCurAllocSize += size;
       
  1133         
       
  1134         // The count can never be negative => associate it to an unsigned int
       
  1135         TUint allocCount = iAllocInfoArray.Count();
       
  1136         if ( allocCount > iMaxAllocs )
       
  1137             {
       
  1138             iMaxAllocs = allocCount;
       
  1139             }
       
  1140         
       
  1141         if ( iCurAllocSize > iMaxAllocSize )
       
  1142             {
       
  1143             iMaxAllocSize = iCurAllocSize;
       
  1144             }
       
  1145         
       
  1146         return iError;
       
  1147         }
       
  1148         
       
  1149     // This shouldn't happen, because the same memory area shouldn't be allocated
       
  1150     // more than once (without deallocating it first)
       
  1151     else
       
  1152         {
       
  1153         delete entry;
       
  1154         return KErrAlreadyExists;
       
  1155         }
       
  1156     }
       
  1157     
       
  1158 // -----------------------------------------------------------------------------
       
  1159 // CATStorageServerSession::LogMemoryAllocTraceL()
       
  1160 // -----------------------------------------------------------------------------
       
  1161 //    
       
  1162 TInt CATStorageServerSession::LogMemoryAllocTraceL( const RMessage2& aMessage )
       
  1163     {
       
  1164     LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL()" );
       
  1165     
       
  1166     // Panic the client and return, if a logging session is not ongoing
       
  1167     // ( can be started by calling the client's LogProcessStarted() )
       
  1168     if ( !iLoggingOngoing )
       
  1169         {
       
  1170         PanicClient( EAToolNotAllowed, aMessage );
       
  1171         return KErrCancel;
       
  1172         }
       
  1173     
       
  1174     // Read the first argument (index 0)
       
  1175     TUint32 memAddress = aMessage.Int0();
       
  1176     if ( memAddress == 0 )
       
  1177         {
       
  1178         return KErrNotSupported;
       
  1179         }
       
  1180     
       
  1181     // Read the third argument (index 2) that tells the size of this allocation
       
  1182     TInt size = aMessage.Int2();
       
  1183     
       
  1184     // Append this allocation into the iAllocInfoArray array. This array is for
       
  1185     // providing the configuration UI with information on allocations
       
  1186     
       
  1187     // Make a TAllocInfo object, and give values for its members.
       
  1188     TAllocInfo allocInfo( memAddress, size );
       
  1189 
       
  1190     // Insert the allocInfo object into iAllocInfoArray
       
  1191     iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
       
  1192     
       
  1193     // Log debug message if duplicated allocation.
       
  1194     if ( iError == KErrAlreadyExists )
       
  1195         {
       
  1196         LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL() Error, duplicate allocation :%i", memAddress );
       
  1197         }
       
  1198 
       
  1199     // A pointer to a buffer of call stack's memory addresses
       
  1200     CBufFlat* stackBuf = NULL;
       
  1201     
       
  1202     // Get the current universal time           
       
  1203     TInt64 timeFrom1970( GetTime() );     
       
  1204     
       
  1205     // Read the length of the descriptor argument (index 1) that should include
       
  1206     // call stack memory addresses associated with this memory allocation
       
  1207     TInt bufferLength = aMessage.GetDesLength( 1 );
       
  1208     
       
  1209     // Construct a buffer for aCallstack
       
  1210     stackBuf = CBufFlat::NewL( bufferLength );
       
  1211     CleanupStack::PushL( stackBuf );
       
  1212     
       
  1213     // Buffer position
       
  1214     TInt pos( 0 );    
       
  1215     stackBuf->ExpandL( pos, bufferLength );
       
  1216     
       
  1217     TPtr8 bufPtr = stackBuf->Ptr( pos );
       
  1218     
       
  1219     // Read the descriptor argument (index 1) into the buffer
       
  1220     aMessage.ReadL( 1, bufPtr );
       
  1221     
       
  1222     // Variable for the number of memory addresses in the call stack
       
  1223     TInt addrCount( 0 );    
       
  1224     TUint32 callStackAddr;
       
  1225     
       
  1226     // Read the first word of the buffer. This includes the number of
       
  1227     // memory addresses stored in the current stackBuf   
       
  1228     stackBuf->Read( pos, &addrCount, KWordSize );
       
  1229     
       
  1230     // Move the position one word onwards.    
       
  1231     pos += KWordSize;
       
  1232     
       
  1233     // Create a 16-bit buffer, and a pointer descriptor for it    
       
  1234     // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count> 
       
  1235     // <Call stack address> <Call stack address> ...
       
  1236     HBufC* traceBuf = HBufC::NewL( KMemAllocBufLength );
       
  1237     TPtr tracePtr( traceBuf->Des() );
       
  1238     
       
  1239     // Pop stackBuf from CleanupStack, since no leavable operations will be done
       
  1240     // anymore
       
  1241     CleanupStack::Pop( stackBuf );
       
  1242     
       
  1243     // Append the tag implying a memory allocation line in the data file
       
  1244     tracePtr.Append( KMemoryAllocHeader );
       
  1245     
       
  1246     // Append the start address of this allocation in the 32-bit (max 8 characters)
       
  1247     // hexadecimal text format.
       
  1248     tracePtr.AppendNum( memAddress, EHex );
       
  1249     
       
  1250     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  1251     // format
       
  1252     tracePtr.Append( KSpaceTrace );
       
  1253     tracePtr.AppendNum( timeFrom1970, EHex );
       
  1254     
       
  1255     // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
       
  1256     // text format.
       
  1257     tracePtr.Append( KSpaceTrace );
       
  1258     tracePtr.AppendNum( size, EHex );
       
  1259     
       
  1260     // Append call stack address count
       
  1261     tracePtr.Append( KSpaceTrace );
       
  1262     tracePtr.AppendNum( addrCount, EHex );
       
  1263     
       
  1264     // Calculate last item length
       
  1265     TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
       
  1266             KSpaceLength + KNewlineLength );
       
  1267     
       
  1268     TUint packetNumber( 1 );
       
  1269     
       
  1270     // Go through all call stack's memory addresses associated with
       
  1271     // this memory allocation 
       
  1272     for ( TInt j = 0; j < addrCount; j++ )
       
  1273         {
       
  1274         // ALLOCF <Memory address> <Time stamp> <Packet number> 
       
  1275         // <Call stack address> <Call stack address> ...
       
  1276         if ( tracePtr.Length() <= 0 )
       
  1277             {                
       
  1278             // Create alloc fragment message header
       
  1279             tracePtr.Append( KMemoryAllocFragment );
       
  1280             tracePtr.AppendNum( memAddress, EHex );
       
  1281             tracePtr.Append( KSpaceTrace );
       
  1282             tracePtr.AppendNum( timeFrom1970, EHex );
       
  1283             tracePtr.Append( KSpaceTrace );        
       
  1284             tracePtr.AppendNum( packetNumber, EHex );
       
  1285             // Increase packet number
       
  1286             packetNumber++;
       
  1287             }
       
  1288         
       
  1289         // Read the next call stack's memory address stored in the buffer.
       
  1290         stackBuf->Read( pos, &callStackAddr, KWordSize );
       
  1291         
       
  1292         // Append the read memory address as a hexadecimal number
       
  1293         tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
       
  1294         
       
  1295         // Move the pos variable one word onwards.
       
  1296         pos += KWordSize;
       
  1297         
       
  1298         // Check if buffer max length exceed
       
  1299         if ( lastItemLength + tracePtr.Length() >= KMemAllocBufLength )
       
  1300             {
       
  1301             tracePtr.Append( KNewLineTrace );
       
  1302             // Log through debug channel 
       
  1303             RDebug::Print( KTraceMessage, iProcessId, traceBuf );
       
  1304             // Empty trace buffer
       
  1305             tracePtr.Delete( 0, tracePtr.MaxLength() );
       
  1306             }
       
  1307         }
       
  1308     
       
  1309     // Send the last message if exists
       
  1310     if ( tracePtr.Length() > 0 )
       
  1311         {
       
  1312         tracePtr.Append( KNewLineTrace );
       
  1313         
       
  1314         // Log through debug channel 
       
  1315         RDebug::Print( KTraceMessage, iProcessId, traceBuf );
       
  1316         }
       
  1317     
       
  1318     delete traceBuf;
       
  1319     delete stackBuf;
       
  1320     
       
  1321     // Update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables            
       
  1322     iCurAllocSize += size;
       
  1323     
       
  1324     // The count can never be negative => associate it to an unsigned int
       
  1325     TUint allocCount = iAllocInfoArray.Count();
       
  1326     if ( allocCount > iMaxAllocs )
       
  1327         {
       
  1328         iMaxAllocs = allocCount;
       
  1329         }
       
  1330     
       
  1331     if ( iCurAllocSize > iMaxAllocSize )
       
  1332         {
       
  1333         iMaxAllocSize = iCurAllocSize;
       
  1334         }
       
  1335     
       
  1336     return KErrNone;    
       
  1337     }    
       
  1338     
       
  1339 // -----------------------------------------------------------------------------
       
  1340 // CATStorageServerSession::LogMemoryFreedL()
       
  1341 // Removes a TATMemoryEntry object with the specified memory address from 
       
  1342 // iLeakArray, if found.
       
  1343 // -----------------------------------------------------------------------------
       
  1344 //
       
  1345 TInt CATStorageServerSession::LogMemoryFreedL( const RMessage2& aMessage )
       
  1346     {
       
  1347     LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedL()" );
       
  1348     
       
  1349     // Panic the client and return, if a logging session is not ongoing
       
  1350     // ( can be started by calling the client's LogProcessStarted() )
       
  1351     if ( !iLoggingOngoing )
       
  1352         {
       
  1353         PanicClient( EAToolNotAllowed, aMessage );
       
  1354         return KErrCancel;
       
  1355         }
       
  1356     
       
  1357     // Get the memory address
       
  1358     TUint32 memAddress = aMessage.Int0();
       
  1359     
       
  1360     // Remove this memory allocation from the leak array
       
  1361     TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
       
  1362     CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
       
  1363     TInt index = iLeakArray.Find( entry, matcher );
       
  1364     delete entry;
       
  1365     
       
  1366     // Return, if the requested memory address was not found
       
  1367     // (had not been allocated)
       
  1368     if ( index == KErrNotFound )
       
  1369         {
       
  1370         return index;
       
  1371         }
       
  1372     
       
  1373     // Delete the CATMemoryEntry object at "index" and remove from the array
       
  1374     delete iLeakArray[index];
       
  1375     iLeakArray.Remove( index );
       
  1376     
       
  1377     // Remove this memory allocation also from the allocation info array
       
  1378     // Make a TAllocInfo object for a "find" operation
       
  1379     TAllocInfo allocInfo( memAddress, 0 );
       
  1380     index = iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo );
       
  1381     
       
  1382     // The index should not be KErrNotFound, because an object with this memory address
       
  1383     // was found in the iLeakArray array. If the index is out of range, something is
       
  1384     // badly wrong, so it would be alright to panic in that case.
       
  1385     if ( index == KErrNotFound )
       
  1386         {
       
  1387         PanicClient( EAToolInternalError, aMessage );
       
  1388         return KErrCancel;
       
  1389         }
       
  1390     
       
  1391     // Decrease the current alloc size and remove the requested allocation
       
  1392     // from iAllocInfoArray
       
  1393     iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
       
  1394     iAllocInfoArray.Remove( index );
       
  1395     
       
  1396     // If we are here, everything has gone alright
       
  1397     return KErrNone;
       
  1398     }
       
  1399 
       
  1400 // -----------------------------------------------------------------------------
       
  1401 // CATStorageServerSession::IsMemoryAdded()
       
  1402 // Check a memory allocation (memory address) from an internal array.
       
  1403 // -----------------------------------------------------------------------------
       
  1404 //    
       
  1405 TInt CATStorageServerSession::IsMemoryAdded( const RMessage2& aMessage, 
       
  1406     const TBool aRemoveAlloc )
       
  1407     {
       
  1408     LOGSTR1( "STSE TInt CATStorageServerSession::IsMemoryAdded()" );
       
  1409     
       
  1410     // Panic the client and return, if a logging session is not ongoing
       
  1411     // ( can be started by calling the client's LogProcessStarted() )
       
  1412     if ( !iLoggingOngoing )
       
  1413         {
       
  1414         PanicClient( EAToolNotAllowed, aMessage );
       
  1415         return KErrCancel;
       
  1416         }
       
  1417         
       
  1418     // Read the first argument (index 0)
       
  1419     TUint32 memAddress = aMessage.Int0();
       
  1420     
       
  1421     // Try to find this memory allocation from the allocation info array
       
  1422     
       
  1423     // Make a TAllocInfo object for a "find" operation
       
  1424     TAllocInfo allocInfo( memAddress, 0 );
       
  1425     TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
       
  1426     
       
  1427     if ( index == KErrNotFound )
       
  1428         {
       
  1429         return index;
       
  1430         }
       
  1431     else if ( aRemoveAlloc )
       
  1432         {
       
  1433         // Otherwise decrease the current alloc size and remove the requested allocation
       
  1434         // from iAllocInfoArray
       
  1435         iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
       
  1436         iAllocInfoArray.Remove( index );
       
  1437         }
       
  1438     
       
  1439     return KErrNone;
       
  1440     }
       
  1441 
       
  1442 // -----------------------------------------------------------------------------
       
  1443 // CATStorageServerSession::LogMemoryFreedTraceL()
       
  1444 // -----------------------------------------------------------------------------
       
  1445 //    
       
  1446 TInt CATStorageServerSession::LogMemoryFreedTraceL( const RMessage2& aMessage )
       
  1447     {
       
  1448     LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedTraceL()" );
       
  1449     
       
  1450     // Panic the client and return, if a logging session is not ongoing
       
  1451     // ( can be started by calling the client's LogProcessStarted() )
       
  1452     if ( !iLoggingOngoing )
       
  1453         {
       
  1454         PanicClient( EAToolNotAllowed, aMessage );
       
  1455         return KErrCancel;
       
  1456         }
       
  1457     
       
  1458     // A pointer to a buffer of call stack's memory addresses
       
  1459     CBufFlat* stackBuf = NULL;        
       
  1460     iError = KErrNone;    
       
  1461     
       
  1462     // Read the first argument (index 0)
       
  1463     TUint32 memAddress = aMessage.Int0();
       
  1464 
       
  1465     // Remove address from allocation table and its size from alloc size,
       
  1466     // if found from table.
       
  1467     TAllocInfo allocInfo( memAddress, 0 ); // Dummy info for search.
       
  1468     TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
       
  1469     if ( index != KErrNotFound )
       
  1470         {
       
  1471         // Decrease the current alloc size and remove the requested allocation
       
  1472         // from table.
       
  1473         iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
       
  1474         iAllocInfoArray.Remove( index );
       
  1475         }
       
  1476     else
       
  1477         {
       
  1478         LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryFreedTrace() Error, cannot find alloc for free: %i", memAddress );
       
  1479         }
       
  1480     
       
  1481     // Read the length of the descriptor argument (index 1) that should include
       
  1482     // call stack memory addresses associated with this memory allocation
       
  1483     TInt bufferLength = aMessage.GetDesLength( 1 );
       
  1484     
       
  1485     // Construct a buffer for aCallstack
       
  1486     stackBuf = CBufFlat::NewL( bufferLength );
       
  1487     CleanupStack::PushL( stackBuf );
       
  1488     
       
  1489     // Buffer position
       
  1490     TInt pos = 0;
       
  1491     
       
  1492     stackBuf->ExpandL( pos, bufferLength );
       
  1493 
       
  1494     TPtr8 bufPtr = stackBuf->Ptr( pos );
       
  1495 
       
  1496     // Read the descriptor argument (index 1) into the buffer
       
  1497     aMessage.ReadL( 1, bufPtr );
       
  1498     
       
  1499     // Variable for the number of memory addresses in the call stack
       
  1500     TInt addrCount( 0 );    
       
  1501     TUint32 callStackAddr( 0 );
       
  1502 
       
  1503     // Read the first word of the buffer. This includes the number of
       
  1504     // memory addresses stored in the current stackBuf
       
  1505     stackBuf->Read( pos, &addrCount, KWordSize );
       
  1506 
       
  1507     // Move the position one word onwards.
       
  1508     pos += KWordSize;
       
  1509     
       
  1510     // Create a 16-bit buffer, and a pointer descriptor for it
       
  1511     HBufC* traceBuf = HBufC::NewL( KMemFreedBufLength );
       
  1512     TPtr tracePtr( traceBuf->Des() );
       
  1513     
       
  1514     // Pop stackBuf from CleanupStack, since no leavable operations will be done
       
  1515     // anymore
       
  1516     CleanupStack::Pop( stackBuf );
       
  1517     
       
  1518 	// Get the current universal time		
       
  1519 	TInt64 timeFrom1970( GetTime() );
       
  1520 			
       
  1521     // Memory deallocation header message.
       
  1522     // FREEH <Memory address> <Time stamp> <Call stack address count> <Call stack address>
       
  1523     // <Call stack address> ...
       
  1524 
       
  1525     // Append the tag implying a memory free line in the data file
       
  1526     tracePtr.Append( KMemoryFreedHeader );
       
  1527     
       
  1528     // Append the start address of this allocation in the 32-bit (max 8 characters)
       
  1529     // hexadecimal text format.
       
  1530     tracePtr.AppendNum( memAddress, EHex );    
       
  1531     
       
  1532 	// Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  1533 	// format
       
  1534 	tracePtr.Append( KSpaceTrace );
       
  1535 	tracePtr.AppendNum( timeFrom1970, EHex );
       
  1536 			
       
  1537     // Append call stack address count
       
  1538     tracePtr.Append( KSpaceTrace );
       
  1539     tracePtr.AppendNum( addrCount, EHex );
       
  1540     
       
  1541     // Packet number
       
  1542     TUint packetNumber( 1 );
       
  1543     
       
  1544     // Calculate last item length
       
  1545     TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
       
  1546             KSpaceLength + KNewlineLength );
       
  1547     
       
  1548     // Go through all call stack's memory addresses associated with
       
  1549     // this memory allocation 
       
  1550     for ( TInt j = 0; j < addrCount; j++ )
       
  1551         {
       
  1552         if ( tracePtr.Length() <= 0 )
       
  1553             {
       
  1554             // Memory deallocation fragment message.
       
  1555             // FREEF <Memory address> <Time stamp> <Packet number> <Call stack address count>
       
  1556             // <Call stack address>...
       
  1557             // Create free fragment message header
       
  1558             tracePtr.Append( KMemoryFreedFragment );
       
  1559             tracePtr.AppendNum( memAddress, EHex );
       
  1560             tracePtr.Append( KSpaceTrace );    
       
  1561 			tracePtr.AppendNum( timeFrom1970, EHex );
       
  1562 			tracePtr.Append( KSpaceTrace );	
       
  1563             tracePtr.AppendNum( packetNumber, EHex );
       
  1564             // Increase packet number
       
  1565             packetNumber++;
       
  1566             }
       
  1567         
       
  1568         // Read the next call stack's memory address stored in the buffer.
       
  1569         stackBuf->Read( pos, &callStackAddr, KWordSize );
       
  1570         
       
  1571         // Append the read memory address as a hexadecimal number
       
  1572         tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
       
  1573         
       
  1574         // Move the pos variable one word onwards.
       
  1575         pos += KWordSize;
       
  1576         
       
  1577         // Check if buffer max length exceed
       
  1578         if ( lastItemLength + tracePtr.Length() >= KMemFreedBufLength )
       
  1579             {
       
  1580             tracePtr.Append( KNewLineTrace );
       
  1581             // Log through debug channel 
       
  1582             RDebug::Print( KTraceMessage, iProcessId, traceBuf );
       
  1583             // Empty trace buffer
       
  1584             tracePtr.Delete( 0, tracePtr.MaxLength() );
       
  1585             }
       
  1586         }
       
  1587     
       
  1588     // Send the last message if exists
       
  1589     if ( tracePtr.Length() > 0 )
       
  1590         {
       
  1591         tracePtr.Append( KNewLineTrace );
       
  1592         
       
  1593         // Log through debug channel 
       
  1594         RDebug::Print( KTraceMessage, iProcessId, traceBuf );
       
  1595         }
       
  1596         
       
  1597     delete traceBuf;
       
  1598     delete stackBuf;
       
  1599     // If we are here, everything has gone alright
       
  1600     return KErrNone;
       
  1601     }
       
  1602 
       
  1603 // -----------------------------------------------------------------------------
       
  1604 // CATStorageServerSession::LogProcessEndedL()
       
  1605 // Prints memory leaks and information on process end into a file opened by the
       
  1606 // function LogProcessStartedL()
       
  1607 // -----------------------------------------------------------------------------
       
  1608 //
       
  1609 TInt CATStorageServerSession::LogProcessEndedL( const RMessage2& aMessage )
       
  1610     {
       
  1611     LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL()" );
       
  1612     
       
  1613     // Panic the client and return, if a logging session is not ongoing
       
  1614     // ( can be started by calling the client's LogProcessStarted() )
       
  1615     if ( !iLoggingOngoing )
       
  1616         {
       
  1617         PanicClient( EAToolNotAllowed, aMessage );
       
  1618         return KErrCancel;
       
  1619         }
       
  1620     
       
  1621     iError = KErrNone;
       
  1622     
       
  1623     // Read the sent process ID
       
  1624     TUint processId = aMessage.Int0();
       
  1625  
       
  1626     // The process ID got from the client should equal iProcessId.
       
  1627     // If it does not, return KErrNotSupported
       
  1628     if ( processId != iProcessId )
       
  1629         {
       
  1630         return KErrNotSupported;
       
  1631         }
       
  1632     
       
  1633     //////////////////////////////////////////////
       
  1634     // Log memory leaks
       
  1635     //////////////////////////////////////////////  
       
  1636     
       
  1637     // Print the information on the memory allocations that were never freed
       
  1638     iError = PrintLeaksL( aMessage );
       
  1639     
       
  1640     if ( iError != KErrNone )
       
  1641         {
       
  1642         return iError;
       
  1643         }    
       
  1644     
       
  1645     //////////////////////////////////////////////
       
  1646     // Log handle leaks
       
  1647     ////////////////////////////////////////////// 
       
  1648 
       
  1649     TUint handleLeakCount = aMessage.Int1();
       
  1650     
       
  1651     if( handleLeakCount == 0 )
       
  1652         {
       
  1653         LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL() No handle leaks to report" );
       
  1654         }
       
  1655     else
       
  1656         {
       
  1657         // Make a buffer that will be logged
       
  1658         TBuf8<KHandleLeakBufLength> loggingBuf;
       
  1659         
       
  1660         // Set handle leak module name to unknown since it can not be defined.
       
  1661         // Write the handle leak count from aMessage.
       
  1662         loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
       
  1663     
       
  1664         // Write the constructed string into the data file and return if error
       
  1665         iError = iFile.Write( loggingBuf );
       
  1666     
       
  1667         if ( iError != KErrNone )
       
  1668             {
       
  1669             return iError;
       
  1670             }
       
  1671         }
       
  1672     
       
  1673     //////////////////////////////////////////////
       
  1674     // Log process end
       
  1675     //////////////////////////////////////////////
       
  1676            
       
  1677     // Make a buffer that will be logged into the opened logging file
       
  1678     TBufC8<KProcessEndBufLength> processEndBuf;
       
  1679     
       
  1680     TPtr8 bufPtr = processEndBuf.Des();
       
  1681     
       
  1682     bufPtr.AppendFormat( KProcessEnd, iProcessId );
       
  1683     
       
  1684     // Get the current universal time       
       
  1685     TInt64 timeFrom1970( GetTime() );
       
  1686     
       
  1687     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  1688     // format         
       
  1689     bufPtr.AppendNum( timeFrom1970, EHex );
       
  1690     
       
  1691     // Append a new line
       
  1692     bufPtr.Append( KNewLine );
       
  1693     
       
  1694     // Write the buffer into a file and return the error code   
       
  1695     iError = iFile.Write( processEndBuf );
       
  1696     
       
  1697     // Close the file and the handle to the file server
       
  1698     CloseFsAndFile();
       
  1699     
       
  1700     // Remove the process from the server's array of processes
       
  1701     iError = iStorageServer.RemoveProcessL( processId );
       
  1702     
       
  1703     // Reset iProcesssId and set the logging flag false
       
  1704     iProcessId = KNullProcessId;
       
  1705     iLoggingOngoing = EFalse;
       
  1706     
       
  1707     return iError;
       
  1708     }
       
  1709 
       
  1710 // -----------------------------------------------------------------------------
       
  1711 // CATStorageServerSession::LogProcessEndTraceL()
       
  1712 // -----------------------------------------------------------------------------
       
  1713 //    
       
  1714 TInt CATStorageServerSession::LogProcessEndTraceL( const RMessage2& aMessage )
       
  1715     {
       
  1716     LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL()" );
       
  1717     
       
  1718     // Panic the client and return, if a logging session is not ongoing
       
  1719     // ( can be started by calling the client's LogProcessStarted() )
       
  1720     if ( !iLoggingOngoing )
       
  1721         {
       
  1722         PanicClient( EAToolNotAllowed, aMessage );
       
  1723         return KErrCancel;
       
  1724         }
       
  1725     
       
  1726     iError = KErrNone;
       
  1727     
       
  1728     // Read the sent process ID
       
  1729     TUint processId = aMessage.Int0();
       
  1730  
       
  1731     // The process ID got from the client should equal iProcessId.
       
  1732     // If it does not, return KErrNotSupported
       
  1733     if ( processId != iProcessId )
       
  1734         {
       
  1735         return KErrNotSupported;
       
  1736         }
       
  1737     
       
  1738     //////////////////////////////////////////////
       
  1739     // Log handle leaks
       
  1740     ////////////////////////////////////////////// 
       
  1741 
       
  1742     TUint handleLeakCount = aMessage.Int1();
       
  1743 
       
  1744     if( handleLeakCount == 0 )
       
  1745         {
       
  1746         LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL() No handle leaks to report" );
       
  1747         }
       
  1748     else
       
  1749         {
       
  1750         // Make a buffer that will be logged
       
  1751         TBuf8<KHandleLeakBufLength> loggingBuf;
       
  1752         
       
  1753         // Make a 16-bit buffer that can be logged using RDebug
       
  1754         TBuf<KHandleLeakBufLength> traceBuf;
       
  1755         
       
  1756         // Set handle leak module name to unknown since it can not be defined.
       
  1757         // Write the handle leak count from aMessage.
       
  1758         loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
       
  1759         
       
  1760         traceBuf.Copy( loggingBuf );
       
  1761     
       
  1762         // Log through debug channel 
       
  1763         RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
       
  1764         }
       
  1765 
       
  1766     //////////////////////////////////////////////
       
  1767     // Log process end
       
  1768     //////////////////////////////////////////////
       
  1769     
       
  1770     // Make a buffer that will be logged
       
  1771     TBuf<KProcessEndBufLength> processEndBuf;    
       
  1772     processEndBuf.AppendFormat( KProcessEndTrace, iProcessId );
       
  1773     
       
  1774     // Get the current universal time
       
  1775     TInt64 timeFrom1970( GetTime() );
       
  1776     
       
  1777     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  1778     // format
       
  1779     processEndBuf.AppendNum( timeFrom1970, EHex );
       
  1780     
       
  1781     // Append a new line
       
  1782     processEndBuf.Append( KNewLineTrace );
       
  1783     
       
  1784     // Log through debug channel
       
  1785     RDebug::Print( KTraceMessage, iProcessId, &processEndBuf );
       
  1786 
       
  1787     // Remove the process from the server's array of processes
       
  1788     iError = iStorageServer.RemoveProcessL( iProcessId );
       
  1789 
       
  1790     // Reset iProcesssId and set the logging flag false
       
  1791     iProcessId = KNullProcessId;
       
  1792     iLoggingOngoing = EFalse;
       
  1793     
       
  1794     return iError;
       
  1795     }
       
  1796 
       
  1797 // -----------------------------------------------------------------------------
       
  1798 // CATStorageServerSession::CheckMemoryAddressL()
       
  1799 // Checks if given memory address can be found
       
  1800 // -----------------------------------------------------------------------------
       
  1801 //
       
  1802 TInt CATStorageServerSession::CheckMemoryAddressL( const RMessage2& aMessage )
       
  1803     {
       
  1804     LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressL()" );
       
  1805     
       
  1806     // Panic the client and return, if a logging session is not ongoing
       
  1807     // ( can be started by calling the client's LogProcessStarted() )
       
  1808     if ( !iLoggingOngoing )
       
  1809         {
       
  1810         PanicClient( EAToolNotAllowed, aMessage );
       
  1811         return KErrCancel;
       
  1812         }
       
  1813     
       
  1814     iError = KErrNone;
       
  1815     
       
  1816     // Check if memory address can be found in iLeakArray
       
  1817     TUint32 memAddress = aMessage.Int0();
       
  1818     TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
       
  1819     CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
       
  1820     
       
  1821     // Get the index or an error code
       
  1822     iError = iLeakArray.Find( entry, matcher );
       
  1823     delete entry;
       
  1824     
       
  1825     return iError;
       
  1826     }
       
  1827 
       
  1828 // -----------------------------------------------------------------------------
       
  1829 // CATStorageServerSession::CheckMemoryAddressTrace()
       
  1830 // Checks if some memory address can be found
       
  1831 // -----------------------------------------------------------------------------
       
  1832 //
       
  1833 TInt CATStorageServerSession::CheckMemoryAddressTrace( const RMessage2& aMessage )
       
  1834     {
       
  1835     LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressTrace()" );
       
  1836     
       
  1837     // Panic the client and return, if a logging session is not ongoing
       
  1838     // ( can be started by calling the client's LogProcessStarted() )
       
  1839     if ( !iLoggingOngoing )
       
  1840         {
       
  1841         PanicClient( EAToolNotAllowed, aMessage );
       
  1842         return KErrCancel;
       
  1843         }
       
  1844     
       
  1845     // Always return KErrNone in this mode
       
  1846     return KErrNone;
       
  1847     }
       
  1848  
       
  1849 // -----------------------------------------------------------------------------
       
  1850 // CATStorageServerSession::GetProcessesL()
       
  1851 // Checks if some memory address can be found
       
  1852 // -----------------------------------------------------------------------------
       
  1853 //
       
  1854 TInt CATStorageServerSession::GetProcessesL( const RMessage2& aMessage )
       
  1855     {
       
  1856     LOGSTR1( "STSE TInt CATStorageServerSession::GetProcessesL()" );
       
  1857     
       
  1858     iError = KErrNone;
       
  1859     
       
  1860     TInt processInfoSize = sizeof( TATProcessInfo );
       
  1861     
       
  1862     CBufFlat* processInfoBuf;
       
  1863     
       
  1864     // Buffer position
       
  1865     TInt pos( 0 );
       
  1866     
       
  1867     // Calculate the length of the buffer to be constructed for processes
       
  1868     // One word will be reserved for the length of the array.
       
  1869     TInt bufferLength = KWordSize + KATMaxProcesses * processInfoSize;
       
  1870     
       
  1871     // Construct processInfoBuf and expand it before the beginning (index 0)
       
  1872     processInfoBuf = CBufFlat::NewL( bufferLength );
       
  1873     CleanupStack::PushL( processInfoBuf );
       
  1874     processInfoBuf->ExpandL( pos, bufferLength );
       
  1875     
       
  1876     RArray<TATProcessInfo> processArray = iStorageServer.ProcessInfoArray();
       
  1877 
       
  1878     // Variable for the number of TATProcessInfo objects in processArray
       
  1879     TInt count = processArray.Count();
       
  1880     
       
  1881     // The count cannot be greater than KATMaxProcesses, because the client
       
  1882     // has reserved a buffer of this size to be filled by the server
       
  1883     if ( count > KATMaxProcesses )
       
  1884         {
       
  1885         count = KATMaxProcesses;
       
  1886         }
       
  1887 
       
  1888     // Write the count (4 bytes) into the beginning of processInfoBuf
       
  1889     processInfoBuf->Write( pos, &count, KWordSize );
       
  1890     
       
  1891     // Move the position one word onwards.    
       
  1892     pos += KWordSize;
       
  1893     
       
  1894     // Write all the process info objects into the buffer 
       
  1895     for ( TInt i = 0; i < count; i++ )
       
  1896         {
       
  1897         TATProcessInfo& processInfo = processArray[i];
       
  1898         
       
  1899         // Write the current process info into the buffer
       
  1900         processInfoBuf->Write( pos, &processInfo, processInfoSize );
       
  1901         
       
  1902         // Move the pos variable onwards.
       
  1903         pos += processInfoSize;
       
  1904         }
       
  1905     
       
  1906     // Make a pointer descriptor pointing to the start of processInfoBuf
       
  1907     TPtr8 bufPtr( processInfoBuf->Ptr(0) );
       
  1908     
       
  1909     // Write the buffer into aMessage at index 0 for the client
       
  1910     aMessage.WriteL( 0, bufPtr );
       
  1911     
       
  1912     CleanupStack::PopAndDestroy( processInfoBuf );
       
  1913     
       
  1914     return iError;
       
  1915     }
       
  1916 
       
  1917 // -----------------------------------------------------------------------------
       
  1918 // CATStorageServerSession::GetDllsL()
       
  1919 // Checks if some memory address can be found
       
  1920 // -----------------------------------------------------------------------------
       
  1921 //
       
  1922 TInt CATStorageServerSession::GetDllsL( const RMessage2& aMessage )
       
  1923     {
       
  1924     LOGSTR1( "STSE TInt CATStorageServerSession::GetDllsL()" );
       
  1925     
       
  1926     // Read the process ID at index 0
       
  1927     TUint processId = aMessage.Int0();
       
  1928     
       
  1929     // Size of a DLL descriptor
       
  1930     TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> );
       
  1931     
       
  1932     // Buffer position
       
  1933     TInt pos( 0 );
       
  1934     
       
  1935     // Calculate the length of the buffer to be constructed for DLL names.
       
  1936     // One word will be reserved for the length of the array.
       
  1937     TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc;
       
  1938     
       
  1939     CBufFlat* dllBuf;
       
  1940     // Construct dllBuf and expand it before the beginning (index 0)
       
  1941     dllBuf = CBufFlat::NewL( bufferLength );
       
  1942     CleanupStack::PushL( dllBuf );
       
  1943     dllBuf->ExpandL( pos, bufferLength );
       
  1944 
       
  1945     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  1946                                              iStorageServer.DynProcessInfoArray();
       
  1947     
       
  1948     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  1949     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  1950     
       
  1951     // Find the index of a CATDynProcessInfo object with the given process ID
       
  1952     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  1953     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  1954     delete dynProcessInfo;
       
  1955     dynProcessInfo = NULL;
       
  1956     
       
  1957     // Return, if a process with the requested process ID was not found 
       
  1958     if ( index == KErrNotFound )
       
  1959         {
       
  1960         CleanupStack::PopAndDestroy( dllBuf );
       
  1961         return index;
       
  1962         }
       
  1963     
       
  1964     // Get the wanted dynamic process info 
       
  1965     dynProcessInfo = dynProcessArray[index];
       
  1966  
       
  1967     // Fetch a reference to the desired DLL array
       
  1968     RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
       
  1969     
       
  1970     // Take the count of names in the array 
       
  1971     TInt count = dllArray.Count();
       
  1972 
       
  1973     // The count cannot be greater than KATMaxDlls, because the client
       
  1974     // has reserved a buffer of this size to be filled by the server
       
  1975     if ( count > KATMaxDlls )
       
  1976         {
       
  1977         count = KATMaxDlls;
       
  1978         }
       
  1979 
       
  1980     // Write the count (4 bytes) into the beginning of dllBuf
       
  1981     dllBuf->Write( pos, &count, KWordSize );
       
  1982     
       
  1983     // Move the position one word onwards.
       
  1984     pos += KWordSize;
       
  1985 
       
  1986     // Go through all DLL names objects sent to the server 
       
  1987     for ( TInt i = 0; i < count; i++ )
       
  1988         {
       
  1989         TBuf8<KMaxLibraryName>& dllName = dllArray[i].iName;
       
  1990         
       
  1991         // Write the current DLL name into the buffer
       
  1992         dllBuf->Write( pos, &dllName, sizeOfDllDesc );
       
  1993         
       
  1994         // Move the pos variable onwards.
       
  1995         pos += sizeOfDllDesc;
       
  1996         }  
       
  1997     
       
  1998     // Make a pointer descriptor pointing to the start of dllBuf
       
  1999     TPtr8 bufPtr( dllBuf->Ptr(0) );
       
  2000     
       
  2001     // Write the whole buffer into aMessage at index 1 for the client
       
  2002     aMessage.WriteL( 1, bufPtr );
       
  2003     
       
  2004     CleanupStack::PopAndDestroy( dllBuf );
       
  2005 
       
  2006     // The dynProcessInfo object will not be deleted, because it is still owned by the
       
  2007     // server object's dynamic process info array.  
       
  2008     dynProcessInfo = NULL;
       
  2009     
       
  2010     return KErrNone;
       
  2011     }
       
  2012 
       
  2013 // -----------------------------------------------------------------------------
       
  2014 // CATStorageServerSession::GetLoggingModeL()
       
  2015 // -----------------------------------------------------------------------------
       
  2016 //    
       
  2017 TInt CATStorageServerSession::GetLoggingModeL( const RMessage2& aMessage )
       
  2018     {
       
  2019     LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingModeL()" );
       
  2020     
       
  2021     iError = KErrNone;
       
  2022     
       
  2023     // Read the process ID at index 0
       
  2024     TUint processId = aMessage.Int0();
       
  2025     
       
  2026     // Buffer position
       
  2027     TInt pos( 0 );
       
  2028     
       
  2029     // The length of the buffer to be constructed for logging mode
       
  2030     TInt bufferLength = KWordSize;
       
  2031     
       
  2032     // Get the dynamic process info array
       
  2033     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2034                                              iStorageServer.DynProcessInfoArray();
       
  2035     
       
  2036     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2037     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2038     
       
  2039     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2040     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2041     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2042     delete dynProcessInfo;
       
  2043     dynProcessInfo = NULL;
       
  2044     
       
  2045     // Return, if a process with the requested process ID was not found 
       
  2046     if ( index == KErrNotFound )
       
  2047         {
       
  2048         return index;
       
  2049         }
       
  2050     
       
  2051     // Otherwise get the wanted dynamic process info
       
  2052     dynProcessInfo = dynProcessArray[index];
       
  2053 
       
  2054     // Get the desired process's associated session object
       
  2055     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2056     CBufFlat* loggingModeBuf;
       
  2057     // Construct allocInfoBuf and expand it before the beginning (index 0)
       
  2058     loggingModeBuf = CBufFlat::NewL( bufferLength );
       
  2059     CleanupStack::PushL( loggingModeBuf );
       
  2060     loggingModeBuf->ExpandL( 0, bufferLength );
       
  2061     
       
  2062     // Write the current logging mode of the requested process into the buffer.
       
  2063     loggingModeBuf->Write( pos, &sessionObject->iLogOption, KWordSize );
       
  2064     
       
  2065     // Make a pointer descriptor that points to the data of allocInfoBuf
       
  2066     TPtr8 bufPtr( loggingModeBuf->Ptr(0) );
       
  2067     
       
  2068     // Write the whole buffer into aMessage at index 1 for the client
       
  2069     aMessage.WriteL( 1, bufPtr );
       
  2070     
       
  2071     CleanupStack::PopAndDestroy( loggingModeBuf );
       
  2072     
       
  2073     return iError;
       
  2074     }
       
  2075 
       
  2076 // -----------------------------------------------------------------------------
       
  2077 // CATStorageServerSession::StartSubtestL()
       
  2078 // -----------------------------------------------------------------------------
       
  2079 //    
       
  2080 TInt CATStorageServerSession::StartSubtestL( const RMessage2& aMessage )
       
  2081     {
       
  2082     LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtestL()" );
       
  2083     
       
  2084     iError = KErrNone;
       
  2085     
       
  2086     // Read the process ID at index 0
       
  2087     TUint processId = aMessage.Int0();
       
  2088     
       
  2089     // Read the sub test ID at index 1
       
  2090     TBuf8<KATMaxSubtestIdLength> subTestName;
       
  2091     iError = aMessage.Read( 1, subTestName );
       
  2092     
       
  2093     // Return if reading was not successful
       
  2094     if ( iError != KErrNone )
       
  2095         {
       
  2096         return iError;
       
  2097         }
       
  2098     
       
  2099     // Create another (non-8-bit) descriptor for logging to trace
       
  2100     // and copy the contents
       
  2101     TBuf<KATMaxSubtestIdLength> subTestNameTrace;
       
  2102     subTestNameTrace.Copy( subTestName );
       
  2103 
       
  2104     // Read the handle count at index 2
       
  2105     TInt handleCount = aMessage.Int2();
       
  2106     
       
  2107     // FIND THE REQUESTED PROCESS
       
  2108     
       
  2109     // Get the dynamic process array
       
  2110     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2111                                              iStorageServer.DynProcessInfoArray();
       
  2112     
       
  2113     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2114     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2115     
       
  2116     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2117     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2118     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2119     delete dynProcessInfo;
       
  2120     dynProcessInfo = NULL;
       
  2121     
       
  2122     // Return, if a process with the requested process ID was not found
       
  2123     if ( index == KErrNotFound )
       
  2124         {
       
  2125         return index;
       
  2126         }
       
  2127     
       
  2128     // Get the wanted dynamic process info
       
  2129     dynProcessInfo = dynProcessArray[index];
       
  2130     
       
  2131     // Get the desired process's associated session object
       
  2132     const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2133   
       
  2134     // Make a buffer for logging thru trace
       
  2135     TBuf<KTestStartBufLength> loggingBuf;
       
  2136     
       
  2137     // Copy the line tag into the buffer  
       
  2138     loggingBuf.Copy( KSubtestStart );
       
  2139     
       
  2140     // Get the current universal time
       
  2141     TInt64 timeFrom1970( GetTime() );
       
  2142     
       
  2143     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2144     // format
       
  2145     loggingBuf.AppendNum( timeFrom1970, EHex );
       
  2146     
       
  2147     // Append a space
       
  2148     loggingBuf.Append( KSpaceTrace );
       
  2149     
       
  2150     // Append the sub test ID
       
  2151     loggingBuf.Append( subTestNameTrace );
       
  2152 
       
  2153     // Append a space
       
  2154     loggingBuf.Append( KSpaceTrace );
       
  2155     
       
  2156     // Append current handle leak count
       
  2157     loggingBuf.AppendNum( handleCount );
       
  2158     
       
  2159     // Append a new line
       
  2160     loggingBuf.Append( KNewLineTrace );
       
  2161     
       
  2162     // Log the string through trace
       
  2163     iError = sessionObject->LogThroughTrace( loggingBuf );
       
  2164         
       
  2165     // *******************
       
  2166     // Send loaded DLL's
       
  2167     // *******************
       
  2168     
       
  2169     // Fetch a reference to the desired DLL array
       
  2170 	RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
       
  2171 	
       
  2172 	// Take the count of dll info items
       
  2173 	TInt count( dllArray.Count() );
       
  2174 	LOGSTR2( "STSE > dllArray.Count( %i )", count );
       
  2175 	
       
  2176 	// Create buffers
       
  2177 	TBuf<KDllLoadBufLength> traceBuf;
       
  2178 	TBuf8<KDllLoadBufLength> dllBuf;
       
  2179 	
       
  2180 	for ( TInt x = 0; x < count; x++ )
       
  2181 		{
       
  2182 		dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
       
  2183 				dllArray[x].iStartAddress, dllArray[x].iEndAddress );
       
  2184 		traceBuf.Copy( dllBuf );
       
  2185 		
       
  2186 		// Log the string through trace
       
  2187 		iError = sessionObject->LogThroughTrace( traceBuf );
       
  2188 		if ( iError != KErrNone )
       
  2189 			{
       
  2190 			LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
       
  2191 			}
       
  2192 		}
       
  2193     sessionObject = NULL;
       
  2194     
       
  2195     return iError;
       
  2196     }
       
  2197 
       
  2198 // -----------------------------------------------------------------------------
       
  2199 // CATStorageServerSession::StopSubtestL()
       
  2200 // -----------------------------------------------------------------------------
       
  2201 //
       
  2202 TInt CATStorageServerSession::StopSubtestL( const RMessage2& aMessage )
       
  2203     {
       
  2204     LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtestL()" );
       
  2205     
       
  2206     iError = KErrNone;
       
  2207     
       
  2208     // Read the process ID at index 0
       
  2209     TUint processId = aMessage.Int0();
       
  2210     
       
  2211     // Read the sub test ID at index 1
       
  2212     TBuf8<KATMaxSubtestIdLength> subTestName;
       
  2213     iError = aMessage.Read( 1, subTestName );
       
  2214     
       
  2215     // Return if reading was not successful
       
  2216     if ( iError != KErrNone )
       
  2217         {
       
  2218         return iError;
       
  2219         }
       
  2220 
       
  2221     // Create another (non-8-bit) descriptor for logging to trace,
       
  2222     // and copy the contents
       
  2223     TBuf<KATMaxSubtestIdLength> subTestNameTrace;
       
  2224     subTestNameTrace.Copy( subTestName );
       
  2225 
       
  2226     // Read the handle count at index 2
       
  2227     TInt handleCount = aMessage.Int2();
       
  2228     
       
  2229     // FIND THE REQUESTED PROCESS
       
  2230     
       
  2231     // Get the dynamic process array
       
  2232     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2233                                              iStorageServer.DynProcessInfoArray();
       
  2234     
       
  2235     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2236     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2237     
       
  2238     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2239     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2240     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2241     delete dynProcessInfo;
       
  2242     dynProcessInfo = NULL;
       
  2243     
       
  2244     // Return, if a process with the requested process ID was not found
       
  2245     if ( index == KErrNotFound )
       
  2246         {
       
  2247         return index;
       
  2248         }
       
  2249     
       
  2250     // Get the wanted dynamic process info
       
  2251     dynProcessInfo = dynProcessArray[index];
       
  2252     
       
  2253     // Get the desired process's associated session object
       
  2254     const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2255   
       
  2256     // Make a buffer for logging thru trace
       
  2257     TBuf<KTestEndBufLength> loggingBuf;
       
  2258     
       
  2259     // Copy the line tag into the buffer  
       
  2260     loggingBuf.Copy( KSubtestEnd );
       
  2261     
       
  2262     // Get the current universal time
       
  2263     TInt64 timeFrom1970( GetTime() );
       
  2264     
       
  2265     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2266     // format
       
  2267     loggingBuf.AppendNum( timeFrom1970, EHex );
       
  2268     
       
  2269     // Append a space
       
  2270     loggingBuf.Append( KSpaceTrace );
       
  2271     
       
  2272     // Append the sub test ID
       
  2273     loggingBuf.Append( subTestNameTrace );
       
  2274 
       
  2275     // Append a space
       
  2276     loggingBuf.Append( KSpaceTrace );
       
  2277     
       
  2278     // Append current handle leak count
       
  2279     loggingBuf.AppendNum( handleCount );
       
  2280     
       
  2281     // Append a new line
       
  2282     loggingBuf.Append( KNewLineTrace );
       
  2283     
       
  2284     // Log the string through trace
       
  2285     iError = sessionObject->LogThroughTrace( loggingBuf );
       
  2286     
       
  2287     sessionObject = NULL;
       
  2288     
       
  2289     return iError;
       
  2290     }
       
  2291 
       
  2292 // -----------------------------------------------------------------------------
       
  2293 // CATStorageServerSession::StartSubtest2L()
       
  2294 // -----------------------------------------------------------------------------
       
  2295 //    
       
  2296 TInt CATStorageServerSession::StartSubtest2L( const RMessage2& aMessage )
       
  2297     {
       
  2298     LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtest2L()" );
       
  2299     
       
  2300     iError = KErrNone;
       
  2301     
       
  2302     // Read the sub test ID at index 0
       
  2303     TBuf8<KATMaxSubtestIdLength> subTestName;
       
  2304     iError = aMessage.Read( 0, subTestName );
       
  2305     
       
  2306     // Return if reading was not successful
       
  2307     if ( iError != KErrNone )
       
  2308         {
       
  2309         return iError;
       
  2310         }
       
  2311     
       
  2312     // Create another (non-8-bit) descriptor for logging to trace
       
  2313     // and copy the contents
       
  2314     TBuf<KATMaxSubtestIdLength> subTestNameTrace;
       
  2315     subTestNameTrace.Copy( subTestName );
       
  2316 
       
  2317     // Make a buffer for logging thru trace
       
  2318     TBuf<KTestStartBufLength> loggingBuf;
       
  2319     
       
  2320     // Copy the line tag into the buffer  
       
  2321     loggingBuf.Copy( KSubtestStart );
       
  2322     
       
  2323     // Get the current universal time
       
  2324     TInt64 timeFrom1970( GetTime() );
       
  2325     
       
  2326     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2327     // format
       
  2328     loggingBuf.AppendNum( timeFrom1970, EHex );
       
  2329     
       
  2330     // Append a space
       
  2331     loggingBuf.Append( KSpaceTrace );
       
  2332     
       
  2333     // Append the sub test ID
       
  2334     loggingBuf.Append( subTestNameTrace );
       
  2335     
       
  2336     // Append a new line
       
  2337     loggingBuf.Append( KNewLineTrace );
       
  2338     
       
  2339     // Log the string through trace
       
  2340     iError = LogThroughTrace( loggingBuf );
       
  2341     
       
  2342     // *******************
       
  2343 	// Send loaded DLL's
       
  2344 	// *******************
       
  2345 	
       
  2346     // Get the dynamic process array
       
  2347 	RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2348 		iStorageServer.DynProcessInfoArray();
       
  2349 	
       
  2350 	// Construct a CATDynProcessInfo object with the given process ID for searching
       
  2351 	CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( iProcessId );
       
  2352 	
       
  2353 	// Find the index of a CATDynProcessInfo object with the given process ID
       
  2354 	TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2355 	TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2356 	delete dynProcessInfo;
       
  2357 	dynProcessInfo = NULL;
       
  2358 	 
       
  2359 	// Return, if a process with the requested process ID was not found
       
  2360 	if ( index == KErrNotFound )
       
  2361 		{
       
  2362 		return index;
       
  2363 		}
       
  2364 	
       
  2365 	// Get the wanted dynamic process info
       
  2366 	dynProcessInfo = dynProcessArray[index];
       
  2367         
       
  2368 	// Fetch a reference to the desired DLL array
       
  2369 	RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
       
  2370 	
       
  2371 	// Take the count of dll info items
       
  2372 	TInt count( dllArray.Count() );
       
  2373 	LOGSTR2( "STSE > dllArray.Count( %i )", count );
       
  2374 	
       
  2375 	// Create buffers
       
  2376 	TBuf<KDllLoadBufLength> traceBuf;
       
  2377 	TBuf8<KDllLoadBufLength> dllBuf;
       
  2378 	
       
  2379 	for ( TInt x = 0; x < count; x++ )
       
  2380 		{
       
  2381 		dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
       
  2382 				dllArray[x].iStartAddress, dllArray[x].iEndAddress );
       
  2383 		traceBuf.Copy( dllBuf );
       
  2384 		
       
  2385 		// Log the string through trace
       
  2386 		iError = LogThroughTrace( traceBuf );
       
  2387 		if ( iError != KErrNone )
       
  2388 			{
       
  2389 			LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
       
  2390 			}
       
  2391 		}
       
  2392     	
       
  2393     return iError;
       
  2394     }
       
  2395     
       
  2396 // -----------------------------------------------------------------------------
       
  2397 // CATStorageServerSession::StopSubtest2()
       
  2398 // -----------------------------------------------------------------------------
       
  2399 //
       
  2400 TInt CATStorageServerSession::StopSubtest2( const RMessage2& aMessage )
       
  2401     {
       
  2402     LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtest2()" );
       
  2403     
       
  2404     iError = KErrNone;
       
  2405     
       
  2406     // Read the sub test ID at index 0
       
  2407     TBuf8<KATMaxSubtestIdLength> subTestName;
       
  2408     iError = aMessage.Read( 0, subTestName );
       
  2409     
       
  2410     // Return if reading was not successful
       
  2411     if ( iError != KErrNone )
       
  2412         {
       
  2413         return iError;
       
  2414         }
       
  2415 
       
  2416     // Create another (non-8-bit) descriptor for logging to trace,
       
  2417     // and copy the contents
       
  2418     TBuf<KATMaxSubtestIdLength> subTestNameTrace;
       
  2419     subTestNameTrace.Copy( subTestName );
       
  2420 
       
  2421     // Make a buffer for logging thru trace
       
  2422     TBuf<KTestEndBufLength> loggingBuf;
       
  2423     
       
  2424     // Copy the line tag into the buffer  
       
  2425     loggingBuf.Copy( KSubtestEnd );
       
  2426     
       
  2427     // Get the current universal time    
       
  2428     TInt64 timeFrom1970( GetTime() );
       
  2429     
       
  2430     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2431     // format
       
  2432     loggingBuf.AppendNum( timeFrom1970, EHex );
       
  2433     
       
  2434     // Append a space
       
  2435     loggingBuf.Append( KSpaceTrace );
       
  2436     
       
  2437     // Append the sub test ID
       
  2438     loggingBuf.Append( subTestNameTrace );
       
  2439     
       
  2440     // Append a new line
       
  2441     loggingBuf.Append( KNewLineTrace );
       
  2442     
       
  2443     // Log the string through trace
       
  2444     iError = LogThroughTrace( loggingBuf );
       
  2445     
       
  2446     return iError;
       
  2447     }
       
  2448 
       
  2449 // -----------------------------------------------------------------------------
       
  2450 // CATStorageServerSession::GetCurrentAllocsL()
       
  2451 // -----------------------------------------------------------------------------
       
  2452 //    
       
  2453 TInt CATStorageServerSession::GetCurrentAllocsL( const RMessage2& aMessage )
       
  2454     {
       
  2455     LOGSTR1( "STSE TInt CATStorageServerSession::GetCurrentAllocsL()" );
       
  2456     
       
  2457     iError = KErrNone;
       
  2458     
       
  2459     // Read the process ID at index 0
       
  2460     TUint processId = aMessage.Int0();
       
  2461     TUint32 allocNumber( 0 );
       
  2462     TUint32 allocSize( 0 );
       
  2463     
       
  2464     // Buffer position
       
  2465     TInt pos( 0 );
       
  2466     
       
  2467     // The length of the buffer to be constructed for allocation number and size
       
  2468     TInt bufferLength = KWordSize + KWordSize;
       
  2469     
       
  2470     // Get the dynamic process info array
       
  2471     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2472                                              iStorageServer.DynProcessInfoArray();
       
  2473     
       
  2474     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2475     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2476     
       
  2477     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2478     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2479     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2480     delete dynProcessInfo;
       
  2481     dynProcessInfo = NULL;
       
  2482     
       
  2483     // Return, if a process with the requested process ID was not found
       
  2484     if ( index == KErrNotFound )
       
  2485         {
       
  2486         return index;
       
  2487         }
       
  2488     
       
  2489     // Otherwise get the wanted dynamic process info
       
  2490     dynProcessInfo = dynProcessArray[index];
       
  2491 
       
  2492     // Get the desired process's associated session object
       
  2493     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2494     
       
  2495     // Get the alloc info array of that session object
       
  2496     RArray<TAllocInfo> allocInfo = sessionObject->AllocInfoArray();
       
  2497     
       
  2498     // Get the values for current allocations number and size
       
  2499     allocNumber = allocInfo.Count();
       
  2500     
       
  2501     // Calculate the total size of the current allocations
       
  2502     for ( TUint32 i = 0; i < allocNumber; i++ )
       
  2503         {
       
  2504         allocSize += allocInfo[i].iAllocSize;
       
  2505         }
       
  2506     
       
  2507     LOGSTR2( "STSE allocSize: %u", allocSize );
       
  2508     LOGSTR2( "STSE iCurAllocSize: %u", iCurAllocSize );
       
  2509     
       
  2510     CBufFlat* allocInfoBuf;
       
  2511     // Construct allocInfoBuf and expand it before the beginning (index 0)
       
  2512     allocInfoBuf = CBufFlat::NewL( bufferLength );
       
  2513     CleanupStack::PushL( allocInfoBuf );
       
  2514     allocInfoBuf->ExpandL( 0, bufferLength );
       
  2515     
       
  2516     // Write the current number of allocations of the requested process into the buffer.
       
  2517     allocInfoBuf->Write( pos, &allocNumber, KWordSize );
       
  2518     
       
  2519     // Move the position one word onwards
       
  2520     pos += KWordSize;
       
  2521     
       
  2522     // Write the current total size of the allocations of the requested process into the
       
  2523     // buffer.
       
  2524     allocInfoBuf->Write( pos, &allocSize, KWordSize );
       
  2525     
       
  2526     // Make a pointer descriptor that points to the data of allocInfoBuf
       
  2527     TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
       
  2528     
       
  2529     // Write the whole buffer into aMessage at index 1 for the client
       
  2530     aMessage.WriteL( 1, bufPtr );
       
  2531     
       
  2532     CleanupStack::PopAndDestroy( allocInfoBuf );
       
  2533                     
       
  2534     return iError;
       
  2535     }
       
  2536 
       
  2537 // -----------------------------------------------------------------------------
       
  2538 // CATStorageServerSession::GetMaxAllocsL()
       
  2539 // -----------------------------------------------------------------------------
       
  2540 //    
       
  2541 TInt CATStorageServerSession::GetMaxAllocsL( const RMessage2& aMessage )
       
  2542     {
       
  2543     LOGSTR1( "STSE TInt CATStorageServerSession::GetMaxAllocsL()" );
       
  2544     
       
  2545     iError = KErrNone;
       
  2546     
       
  2547     // Read the process ID at index 0
       
  2548     TUint processId = aMessage.Int0();
       
  2549     TUint32 allocNumber( 0 );
       
  2550     TUint32 allocSize( 0 );
       
  2551     
       
  2552     // Buffer position
       
  2553     TInt pos( 0 );
       
  2554     
       
  2555     // The length of the buffer to be constructed for allocation number and size
       
  2556     TInt bufferLength = KWordSize + KWordSize;
       
  2557     
       
  2558     // Get the dynamic process info array
       
  2559     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2560                                              iStorageServer.DynProcessInfoArray();
       
  2561     
       
  2562     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2563     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2564     
       
  2565     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2566     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2567     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2568     delete dynProcessInfo;
       
  2569     dynProcessInfo = NULL;
       
  2570     
       
  2571     // Return, if a process with the requested process ID was not found 
       
  2572     if ( index == KErrNotFound )
       
  2573         {
       
  2574         return index;
       
  2575         }
       
  2576     
       
  2577     // Otherwise get the wanted dynamic process info 
       
  2578     dynProcessInfo = dynProcessArray[index];
       
  2579 
       
  2580     // Get the desired process's associated session object
       
  2581     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2582     
       
  2583     // Get values for the maximum allocations number and size
       
  2584     allocNumber = sessionObject->iMaxAllocs;
       
  2585     allocSize = sessionObject->iMaxAllocSize;
       
  2586     
       
  2587     CBufFlat* allocInfoBuf;
       
  2588     // Construct allocInfoBuf and expand it before the beginning (index 0)
       
  2589     allocInfoBuf = CBufFlat::NewL( bufferLength );
       
  2590     CleanupStack::PushL( allocInfoBuf );
       
  2591     allocInfoBuf->ExpandL( 0, bufferLength );
       
  2592     
       
  2593     // Write the maximum number of allocations of the requested process into the buffer.
       
  2594     allocInfoBuf->Write( pos, &allocNumber, KWordSize );
       
  2595     
       
  2596     // Move the position one word onwards
       
  2597     pos += KWordSize;
       
  2598     
       
  2599     // Write the maximum total size of the allocations of the requested process into the
       
  2600     // buffer.
       
  2601     allocInfoBuf->Write( pos, &allocSize, KWordSize );
       
  2602     
       
  2603     // Make a pointer descriptor that points to the data of allocInfoBuf
       
  2604     TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
       
  2605     
       
  2606     // Write the whole buffer into aMessage at index 1 for the client
       
  2607     aMessage.WriteL( 1, bufPtr );
       
  2608     
       
  2609     CleanupStack::PopAndDestroy( allocInfoBuf );
       
  2610                     
       
  2611     return iError;
       
  2612     }
       
  2613   
       
  2614 // -----------------------------------------------------------------------------
       
  2615 // CATStorageServerSession::CancelLoggingL()
       
  2616 // -----------------------------------------------------------------------------
       
  2617 //    
       
  2618 TInt CATStorageServerSession::CancelLoggingL( const RMessage2& aMessage )
       
  2619     {
       
  2620     LOGSTR1( "STSE TInt CATStorageServerSession::CancelLoggingL()" );
       
  2621     
       
  2622     iError = KErrNone;
       
  2623     
       
  2624     // Read the process ID at index 0
       
  2625     TUint processId = aMessage.Int0();
       
  2626         
       
  2627     // FIND THE REQUESTED PROCESS
       
  2628     
       
  2629     // Get the dynamic process array
       
  2630     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  2631                                              iStorageServer.DynProcessInfoArray();
       
  2632     
       
  2633     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  2634     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  2635     
       
  2636     // Find the index of a CATDynProcessInfo object with the given process ID
       
  2637     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  2638     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  2639     delete dynProcessInfo;
       
  2640     dynProcessInfo = NULL;
       
  2641      
       
  2642     // Return, if a process with the requested process ID was not found
       
  2643     if ( index == KErrNotFound )
       
  2644         {
       
  2645         return index;
       
  2646         }
       
  2647     
       
  2648     // Otherwise get the wanted dynamic process info
       
  2649     dynProcessInfo = dynProcessArray[index];
       
  2650     
       
  2651     // Get the session object of the requested process
       
  2652     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  2653       
       
  2654     // Get the current universal time
       
  2655     TInt64 timeFrom1970( GetTime() );
       
  2656     
       
  2657     // Make a buffer for logging "logging cancelled"
       
  2658     TBuf8<KCancelBufLength> loggingBuf;
       
  2659     
       
  2660     // Copy the "logging cancelled" tag into the buffer with the current time 
       
  2661     loggingBuf.AppendFormat( KLoggingCancelled, timeFrom1970 );
       
  2662     
       
  2663     // Log the buffer eather to a file or to debug channel depending on the current
       
  2664     // logging mode
       
  2665     
       
  2666     if ( sessionObject->iLoggingOngoing && 
       
  2667          sessionObject->iLogOption == EATLogToFile )
       
  2668         {
       
  2669         // Write the buffer into the file  
       
  2670         sessionObject->iFile.Write( loggingBuf );
       
  2671         }
       
  2672     
       
  2673     else if ( sessionObject->iLoggingOngoing &&
       
  2674               sessionObject->iLogOption == EATLogToTrace )
       
  2675         {
       
  2676         // Make a buffer for logging to trace
       
  2677         TBuf<KCancelBufLength> traceBuf;
       
  2678         traceBuf.Copy( loggingBuf );
       
  2679         
       
  2680         // Write the buffer into the debug channel
       
  2681         RDebug::Print( KTraceMessage, processId ,&traceBuf );
       
  2682         }
       
  2683     
       
  2684     // Switch off logging of the requested process 
       
  2685     sessionObject->iLogOption = EATLoggingOff;
       
  2686     
       
  2687     return KErrNone;
       
  2688     }
       
  2689 
       
  2690 // -----------------------------------------------------------------------------
       
  2691 // CATStorageServerSession::HandleError
       
  2692 // Internally used for handling error situations.
       
  2693 // -----------------------------------------------------------------------------
       
  2694 // 
       
  2695 void CATStorageServerSession::HandleError( TInt aError )
       
  2696     {
       
  2697     LOGSTR1( "STSE void CATStorageServerSession::HandleError()" );
       
  2698       
       
  2699     // Get the current universal time
       
  2700     TInt64 timeFrom1970( GetTime() );
       
  2701         
       
  2702     // Make a buffer that will be logged into the opened logging file
       
  2703     TBufC8<KErrOccuredBufLength> loggingBuf;
       
  2704     
       
  2705     TPtr8 bufPtr( loggingBuf.Des() );
       
  2706      
       
  2707     // Write the error code to the buffer  
       
  2708     bufPtr.Format( KErrorOccured, aError );
       
  2709        
       
  2710     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2711     // format
       
  2712     bufPtr.AppendNum( timeFrom1970, EHex );
       
  2713     
       
  2714     // Append a new line
       
  2715     bufPtr.Append( KNewLine );
       
  2716             
       
  2717     // Write the buffer into a file (if possible in the current condition)
       
  2718     iFile.Write( loggingBuf );
       
  2719     }
       
  2720 
       
  2721 // -----------------------------------------------------------------------------
       
  2722 // CATStorageServerSession::HandleErrorTrace()
       
  2723 // Internally used for handling error situations.
       
  2724 // -----------------------------------------------------------------------------
       
  2725 //    
       
  2726 void CATStorageServerSession::HandleErrorTrace( TInt aError )
       
  2727     {
       
  2728     LOGSTR1( "STSE void CATStorageServerSession::HandleErrorTrace()" );
       
  2729     
       
  2730      // Get the current universal time
       
  2731     TInt64 timeFrom1970( GetTime() );
       
  2732         
       
  2733     // Make a buffer that will be logged
       
  2734     TBuf<KErrOccuredBufLength> traceBuf;
       
  2735      
       
  2736     // Write the error code to the buffer  
       
  2737     traceBuf.Format( KErrorOccuredTrace, aError );
       
  2738        
       
  2739     // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  2740     // format
       
  2741     traceBuf.AppendNum( timeFrom1970, EHex );
       
  2742     
       
  2743     // Append a new line
       
  2744     traceBuf.Append( KNewLineTrace );
       
  2745                  
       
  2746     RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
       
  2747     }
       
  2748 
       
  2749 // -----------------------------------------------------------------------------
       
  2750 // CATStorageServerSession::OpenFsAndFile
       
  2751 // Internally used for opening a handle to the file server and a file
       
  2752 // -----------------------------------------------------------------------------
       
  2753 // 
       
  2754 TInt CATStorageServerSession::OpenFsAndFile( const TDesC& aFileName, 
       
  2755     const TDesC8& aProcessName )
       
  2756     {
       
  2757     LOGSTR1( "STSE TInt CATStorageServerSession::OpenFsAndFile()" );
       
  2758     
       
  2759     // Connect file server, return if error occured
       
  2760     iError = iFileServer.Connect();
       
  2761     if ( iError )
       
  2762         {
       
  2763         iFileServer.Close();
       
  2764         return iError;
       
  2765         }
       
  2766 
       
  2767     // Open a file
       
  2768     TBuf<KMaxFileName> fileNameBuf;    
       
  2769     iError = TATDriveInfo::CreatePath( fileNameBuf, aFileName, iFileServer );
       
  2770                         
       
  2771     // Return, if an error occured, and it
       
  2772     // is not KErrAlreadyExists
       
  2773     if ( iError && iError != KErrAlreadyExists )
       
  2774         {
       
  2775         iFileServer.Close();
       
  2776         return iError;
       
  2777         }
       
  2778     
       
  2779     // Save the file name for this session
       
  2780     CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
       
  2781         
       
  2782     // Try to open file
       
  2783     CheckIfFileAlreadyExist( fileNameBuf );
       
  2784     
       
  2785     // If a data file with the requested name already existed, and was opened
       
  2786     // successfully, check the version of the file. If the line telling the version of
       
  2787     // the file is not the expected, replace the file
       
  2788     // If cannot open the file(error is KErrInUse), generate new filename and 
       
  2789     // then try to create new file.
       
  2790     if ( iError == KErrNone )
       
  2791         {
       
  2792         CheckFileVersion( fileNameBuf );
       
  2793         }    
       
  2794     else if ( iError == KErrInUse )
       
  2795         {
       
  2796         GenerateNewFileName( fileNameBuf, aProcessName );
       
  2797         
       
  2798         // Save the file name for this session
       
  2799         CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
       
  2800         }
       
  2801     LOGSTR2( "STSE > iError(%i)", iError );
       
  2802         
       
  2803     // If the file does not exist, create it. Write also the version number of
       
  2804     // the file at the beginning of the new file
       
  2805     if ( iError == KErrNotFound )
       
  2806         {
       
  2807         iError = iFile.Create( iFileServer, fileNameBuf, EFileWrite );
       
  2808         
       
  2809         if ( !iError )
       
  2810             {
       
  2811             iError = iFile.Write( KDataFileVersion );
       
  2812             }
       
  2813         }   
       
  2814        
       
  2815     if ( iError )
       
  2816         {
       
  2817         iFile.Close();
       
  2818         iFileServer.Close();
       
  2819         return iError;
       
  2820         }
       
  2821         
       
  2822     // Seek the end of the file and set the current file position there
       
  2823     TInt offset = 0;
       
  2824     iError = iFile.Seek( ESeekEnd, offset );
       
  2825     
       
  2826     return iError;
       
  2827     }
       
  2828 
       
  2829 // -----------------------------------------------------------------------------
       
  2830 // CATStorageServerSession::GenerateNewFileName
       
  2831 // Called internally when need generate new file name.
       
  2832 // -----------------------------------------------------------------------------
       
  2833 //                     
       
  2834 void CATStorageServerSession::GenerateNewFileName( TDes& aFileName,
       
  2835     const TDesC8& aProcessName )
       
  2836     {    
       
  2837     LOGSTR1( "STSE void CATStorageServerSession::GenerateNewFileName()" );
       
  2838         
       
  2839     // Extension
       
  2840     TBuf<KExtensionLength> extension;
       
  2841 
       
  2842     // Parse file extension
       
  2843     ParseExtension( aFileName, extension );
       
  2844 
       
  2845     // Try to find UID3 from current process name
       
  2846     TInt uidErr( KErrBadName );
       
  2847     TBuf<KMaxFileName> unicodeFile;
       
  2848 
       
  2849     // Converts text encoded using the Unicode transformation format UTF-8 
       
  2850     // into the Unicode UCS-2 character set. 
       
  2851     CnvUtfConverter::ConvertToUnicodeFromUtf8( unicodeFile, aProcessName );
       
  2852     LOGSTR2( "STSE > unicodeFile(%S)", &unicodeFile );
       
  2853 
       
  2854     // Find square brackets
       
  2855     TInt sPos( unicodeFile.Find( KOpenSquareBracket ) );
       
  2856     TInt ePos( unicodeFile.Find( KCloseSquareBracket ) );
       
  2857     LOGSTR3( "STSE > sPos(%i), ePos(%i)", sPos, ePos );
       
  2858             
       
  2859     if ( sPos != KErrNotFound && ePos != KErrNotFound )
       
  2860         {
       
  2861         TBuf<KProcessUidLength> processUid;
       
  2862         TInt pEnd( ePos - sPos - KOpenSquareBracket().Length() );
       
  2863         LOGSTR2( "STSE > pEnd(%i)", pEnd );
       
  2864         
       
  2865         // Copy UID value
       
  2866         if ( pEnd > 0 )
       
  2867             {
       
  2868             processUid.Copy( unicodeFile.Mid( 
       
  2869                     sPos + KOpenSquareBracket().Length(), pEnd ) );
       
  2870             LOGSTR2( "STSE > processUid(%S)", &processUid );
       
  2871             }
       
  2872         
       
  2873         if ( aFileName.Find( processUid ) == KErrNotFound )
       
  2874             {
       
  2875             // UID not exist, create new filename
       
  2876             // Append uid to filename (<file name>_<uid>.<extension>)
       
  2877             aFileName.Append( KUnderLine );
       
  2878             aFileName.Append( processUid );
       
  2879             aFileName.Append( extension );
       
  2880             // Try to open file
       
  2881             CheckIfFileAlreadyExist( aFileName );
       
  2882 
       
  2883             if ( iError == KErrNone )
       
  2884                 {
       
  2885                 uidErr = KErrNone;
       
  2886                 CheckFileVersion( aFileName );
       
  2887                 }
       
  2888             }
       
  2889         }
       
  2890 
       
  2891     if ( uidErr == KErrBadName && iError != KErrNotFound )
       
  2892         {
       
  2893         // Need re-create file name, add end off file _xx (xx=01, 02...)
       
  2894         LOGSTR2( "STSE > Re-create file name, aFileName(%S)", &aFileName );
       
  2895                 
       
  2896         // Parse file extension if exists.
       
  2897         ParseExtension( aFileName, extension );
       
  2898         
       
  2899         // Temp file name
       
  2900         TBuf<KMaxFileName> tempName;
       
  2901         
       
  2902         for ( TInt i = KNameIndexStart; i < KNameIndexEnd; i++ )
       
  2903             {
       
  2904             tempName.Delete( 0, tempName.MaxLength() );
       
  2905             tempName.Format( KFormat, &aFileName, &KUnderLine, i, &extension );
       
  2906             LOGSTR2( "STSE > tempName(%S)", &tempName );
       
  2907             // Try to open file
       
  2908             CheckIfFileAlreadyExist( tempName );
       
  2909             
       
  2910             if ( iError == KErrNone || iError == KErrNotFound )
       
  2911                 {
       
  2912                 aFileName.Copy( tempName );
       
  2913                 break;
       
  2914                 }
       
  2915             }
       
  2916         }
       
  2917     }
       
  2918 
       
  2919 // -----------------------------------------------------------------------------
       
  2920 // CATStorageServerSession::ParseExtension
       
  2921 // Method is used to parse file name extension.
       
  2922 // -----------------------------------------------------------------------------
       
  2923 //                     
       
  2924 void CATStorageServerSession::ParseExtension( 
       
  2925     TDes& aFileName, TDes& aExtension )
       
  2926     {    
       
  2927     LOGSTR2( "STSE void CATStorageServerSession::ParseExtension(%S)", 
       
  2928             &aFileName );
       
  2929 
       
  2930     // Parse current file name
       
  2931     TParse parse;
       
  2932     // Set up the TParse object 
       
  2933     parse.Set( aFileName, NULL, NULL );
       
  2934 
       
  2935     // Tests whether an extension is present.
       
  2936     if ( parse.ExtPresent() )
       
  2937         {
       
  2938         // Gets the extension
       
  2939         aExtension.Copy( parse.Ext() );
       
  2940         // Remove extension from file name
       
  2941         TInt pos( aFileName.Find( aExtension ) );
       
  2942         aFileName.Delete( pos, aFileName.Length() );
       
  2943         LOGSTR3( "STSE > aFileName(%S), aExtension(%S)", 
       
  2944                 &aFileName, &aExtension );
       
  2945         }
       
  2946     }
       
  2947 
       
  2948 // -----------------------------------------------------------------------------
       
  2949 // CATStorageServerSession::CheckIfFileAlreadyExist
       
  2950 // Method is used to check that file exists and is valid.
       
  2951 // -----------------------------------------------------------------------------
       
  2952 //                     
       
  2953 void CATStorageServerSession::CheckIfFileAlreadyExist( 
       
  2954     const TDes& aFileName )
       
  2955     {    
       
  2956     LOGSTR2( "STSE void CATStorageServerSession::CheckIfFileAlreadyExist(%S)", 
       
  2957             &aFileName );
       
  2958     
       
  2959     iError = iFile.Open( iFileServer, aFileName, EFileWrite );
       
  2960     LOGSTR2( "STSE > iError(%i)", iError );
       
  2961     }
       
  2962 
       
  2963 // -----------------------------------------------------------------------------
       
  2964 // CATStorageServerSession::CheckFileVersion
       
  2965 // Method is used to check file version.
       
  2966 // -----------------------------------------------------------------------------
       
  2967 //                     
       
  2968 void CATStorageServerSession::CheckFileVersion( 
       
  2969     const TDes& aFileName )
       
  2970     {    
       
  2971     LOGSTR2( "STSE void CATStorageServerSession::CheckFileVersion(%S)", 
       
  2972             &aFileName );
       
  2973 
       
  2974     TBuf8<KVersionStringLength> versionString;
       
  2975 
       
  2976     // Read version information from the beginning of the file (offset 0)
       
  2977     iFile.Read( 0, versionString, KVersionStringLength );
       
  2978 
       
  2979     // Delete the existing file, if the version string read from the file does not
       
  2980     // match with KDataFileVersion.
       
  2981     if ( versionString.Compare( KDataFileVersion ) != 0 )
       
  2982         {
       
  2983         // Close the existing, opened file, and delete it
       
  2984         iFile.Close();
       
  2985         iError = iFileServer.Delete( aFileName );
       
  2986         
       
  2987         // If the deletion was successful, set iError = KErrNotFound, so a new
       
  2988         // file will be created in the next few lines 
       
  2989         if ( iError == KErrNone )
       
  2990             {
       
  2991             iError = KErrNotFound;
       
  2992             }
       
  2993         }
       
  2994     }
       
  2995 
       
  2996 // -----------------------------------------------------------------------------
       
  2997 // CATStorageServerSession::CloseFsAndFile
       
  2998 // Internally used for closing a handle to the file server and a file
       
  2999 // -----------------------------------------------------------------------------
       
  3000 // 
       
  3001 void CATStorageServerSession::CloseFsAndFile()
       
  3002     {
       
  3003     LOGSTR1( "STSE void CATStorageServerSession::CloseFsAndFile()" );
       
  3004     
       
  3005     // Close the file    
       
  3006     iFile.Close();
       
  3007                  
       
  3008     // Close the server session and return the error code   
       
  3009     iFileServer.Close();
       
  3010     }
       
  3011 
       
  3012 // -----------------------------------------------------------------------------
       
  3013 // CATStorageServerSession::PrintLeaksL()
       
  3014 // Called internally when a process is closed. Prints possible memory leaks
       
  3015 // -----------------------------------------------------------------------------
       
  3016 //
       
  3017 TInt CATStorageServerSession::PrintLeaksL( const RMessage2& aMessage )
       
  3018     {
       
  3019     LOGSTR1( "STSE TInt CATStorageServerSession::PrintLeaksL()" );
       
  3020     
       
  3021     // Panic both the client and the server, if this method is called in a wrong
       
  3022     // state (logging should be ongoing, and the system should be logging into a file,
       
  3023     // not into debug channel)
       
  3024     if ( !iLoggingOngoing || iLogOption != EATLogToFile )
       
  3025         {
       
  3026         PanicClient( EAToolInternalError, aMessage );
       
  3027         StorageServerPanic( KCategoryServer, EAToolInternalError );
       
  3028         }
       
  3029    
       
  3030     LOGMEM;
       
  3031 
       
  3032     // A pointer to a buffer of call stack's memory addresses
       
  3033     CBufFlat* stackBuf = NULL;
       
  3034     
       
  3035     iError = KErrNone;
       
  3036     
       
  3037     TUint32 callStackAddr;
       
  3038     
       
  3039     // Number of leaks
       
  3040     TInt leakCount = iLeakArray.Count();
       
  3041     
       
  3042     // Variable for the number of memory addresses in the call stack
       
  3043     TInt addrCount( 0 );
       
  3044     
       
  3045     // Buffer position
       
  3046     TInt pos( 0 );
       
  3047                      
       
  3048     // Go through all the leaks 
       
  3049     for ( TInt i = 0; i < leakCount; i++ ) 
       
  3050         {   
       
  3051         pos = 0;
       
  3052         
       
  3053         // Get the call stack buffer of the the leak i.
       
  3054         stackBuf = const_cast<CBufFlat*>( iLeakArray[i]->iCallstackBuf );
       
  3055     
       
  3056         // Read the first word of the buffer. This includes the number of
       
  3057         // memory addresses stored in the current stackBuf
       
  3058         stackBuf->Read( pos, &addrCount, KWordSize );
       
  3059     
       
  3060         // Move the position one word onwards.
       
  3061         pos += KWordSize;
       
  3062          
       
  3063         // Construct a buffer for the string to be written into the logging file
       
  3064         // because of this memory leak. MEM_LEAK: <Memory address> <Time stamp>
       
  3065         // <Allocation size> <Call stack address> <Call stack address> ...
       
  3066         HBufC8* leakString = 
       
  3067             HBufC8::NewL( KMemleakLength +
       
  3068                           KHexa32Length +
       
  3069                           KSpaceLength + KHexa64Length +
       
  3070                           KSpaceLength + KHexa32Length +
       
  3071                           ( addrCount * (KSpaceLength + KHexa32Length) ) +
       
  3072                           KNewlineLength 
       
  3073                         );
       
  3074             
       
  3075         // Make a pointer descriptor that points to leakString
       
  3076         TPtr8 leakStringPtr( leakString->Des() );
       
  3077         
       
  3078         // Append the tag implying a memory leak line in the data file
       
  3079         leakStringPtr.Append( KMemoryLeak );
       
  3080         
       
  3081         // Append the address of the memory leak         
       
  3082         TUint32 memAddress = iLeakArray[i]->iMemAddress;
       
  3083         leakStringPtr.AppendNum( memAddress, EHex );
       
  3084         
       
  3085         // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  3086         // format
       
  3087         leakStringPtr.Append( KSpace );
       
  3088         TInt64 allocTime = iLeakArray[i]->iAllocTime;
       
  3089         leakStringPtr.AppendNum( allocTime, EHex );
       
  3090         
       
  3091         // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
       
  3092         // text format.
       
  3093         leakStringPtr.Append( KSpace );
       
  3094         TInt allocSize = iLeakArray[i]->iAllocSize;
       
  3095         leakStringPtr.AppendNum( allocSize, EHex );
       
  3096         
       
  3097         // Go through all call stack's memory addresses associated with
       
  3098         // the current memory leak 
       
  3099         for ( TInt j = 0; j < addrCount; j++ )
       
  3100             {
       
  3101             // Read the next call stack's memory address stored in the buffer.
       
  3102             stackBuf->Read( pos, &callStackAddr, KWordSize );
       
  3103             
       
  3104             // Append the read memory address as a hexadecimal number
       
  3105             leakStringPtr.AppendFormat( KHexaNumber,  callStackAddr );
       
  3106     
       
  3107             // Move the pos variable one word onwards.
       
  3108             pos += KWordSize;
       
  3109             }
       
  3110         
       
  3111         leakStringPtr.Append( KNewLine );
       
  3112         
       
  3113         // Set stackBuf to NULL, because it is not used anymore.
       
  3114         stackBuf = NULL;
       
  3115         
       
  3116         // Write the constructed string into the data file and return if error
       
  3117         iError = iFile.Write( *leakString );
       
  3118         
       
  3119         delete leakString;
       
  3120           
       
  3121         if ( iError != KErrNone )
       
  3122             {
       
  3123             return iError;
       
  3124             }
       
  3125               
       
  3126         } // The outer for
       
  3127    
       
  3128     LOGSTR1( "STSE End of CATStorageServerSession::PrintLeaks()" );
       
  3129     LOGMEM;
       
  3130    
       
  3131     // Empty the leak array and delete the referenced objects
       
  3132     iLeakArray.ResetAndDestroy();
       
  3133    
       
  3134     return KErrNone;
       
  3135     }
       
  3136 
       
  3137 // -----------------------------------------------------------------------------
       
  3138 // CATStorageServerSession::SetLogOption()
       
  3139 // For setting the logging mode.
       
  3140 // -----------------------------------------------------------------------------
       
  3141 //
       
  3142 void CATStorageServerSession::SetLogOption( const RMessage2& aMessage )
       
  3143     {
       
  3144     LOGSTR1( "STSE void CATStorageServerSession::SetLogOption()" );
       
  3145         
       
  3146     // Panic both the client and the server, if this method is called in a wrong
       
  3147     // state (logging must not be ongoing when changing the mode of operation).
       
  3148     // So, the mode cannot be changed "on the fly".
       
  3149     if ( iLoggingOngoing )
       
  3150         {
       
  3151         PanicClient( EAToolInternalError, aMessage );
       
  3152         StorageServerPanic( KCategoryServer, EAToolInternalError );
       
  3153         }    
       
  3154 
       
  3155     iLogOption = static_cast<TATLogOption>( aMessage.Int3() );
       
  3156     
       
  3157     // The default is EATLogToFile
       
  3158     if ( iLogOption == EATUseDefault )
       
  3159         {
       
  3160         iLogOption = KDefaultLoggingMode;
       
  3161         } 
       
  3162     }
       
  3163     
       
  3164 // -----------------------------------------------------------------------------
       
  3165 // CATStorageServerSession::LogThroughTrace()
       
  3166 // -----------------------------------------------------------------------------
       
  3167 //
       
  3168 TInt CATStorageServerSession::LogThroughTrace( const TDesC& aLogString ) const
       
  3169     {
       
  3170     LOGSTR1( "STSE TInt CATStorageServerSession::LogThroughTrace()" );
       
  3171 
       
  3172     // Return KErrNotSupported, if a logging session is not currently ongoing, or
       
  3173     // the logging mode is not EATLogToTrace
       
  3174     if ( !iLoggingOngoing || iLogOption != EATLogToTrace)
       
  3175         {
       
  3176         return KErrNotSupported;
       
  3177         }
       
  3178         
       
  3179     RDebug::Print( KTraceMessage, iProcessId, &aLogString );
       
  3180     
       
  3181     return KErrNone;
       
  3182     }
       
  3183 
       
  3184 // -----------------------------------------------------------------------------
       
  3185 // CATStorageServerSession::AllocInfoArray
       
  3186 // -----------------------------------------------------------------------------
       
  3187 // 
       
  3188 RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()
       
  3189     {
       
  3190     LOGSTR1( "STSE RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()" );
       
  3191      
       
  3192     return iAllocInfoArray;
       
  3193     }    
       
  3194 
       
  3195 // -----------------------------------------------------------------------------
       
  3196 // CATStorageServerSession::PanicClient
       
  3197 // Creates a panic in the associated client's code.
       
  3198 // -----------------------------------------------------------------------------
       
  3199 //
       
  3200 void CATStorageServerSession::PanicClient( TInt aPanic, const RMessage2& aMessage )
       
  3201     {
       
  3202     LOGSTR1( "STSE void CATStorageServerSession::PanicClient()" );
       
  3203     
       
  3204     aMessage.Panic( KCategoryClient, aPanic );
       
  3205     }
       
  3206 
       
  3207 // -----------------------------------------------------------------------------
       
  3208 // CATStorageServerSession::GetLoggingFileL()
       
  3209 // -----------------------------------------------------------------------------
       
  3210 //    
       
  3211 TInt CATStorageServerSession::GetLoggingFileL( const RMessage2& aMessage )
       
  3212     {
       
  3213     LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingFileL()" );
       
  3214     
       
  3215     iError = KErrNone;
       
  3216     
       
  3217     // Read the process ID at index 0
       
  3218     TUint processId = aMessage.Int0();
       
  3219     
       
  3220     // Get the dynamic process info array
       
  3221     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  3222                                              iStorageServer.DynProcessInfoArray();
       
  3223     
       
  3224     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  3225     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  3226     
       
  3227     // Find the index of a CATDynProcessInfo object with the given process ID
       
  3228     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  3229     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  3230     delete dynProcessInfo;
       
  3231     dynProcessInfo = NULL;
       
  3232     
       
  3233     // Return, if a process with the requested process ID was not found 
       
  3234     if ( index == KErrNotFound )
       
  3235         {
       
  3236         return index;
       
  3237         }
       
  3238     
       
  3239     // Otherwise get the wanted dynamic process info
       
  3240     dynProcessInfo = dynProcessArray[index];
       
  3241 
       
  3242     // Get the desired process's associated session object
       
  3243     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  3244             
       
  3245     // Write the whole buffer into aMessage at index 1 for the client
       
  3246     aMessage.WriteL( 1, sessionObject->iLogFile );
       
  3247                     
       
  3248     return iError;
       
  3249     }
       
  3250 
       
  3251 // -----------------------------------------------------------------------------
       
  3252 // CATStorageServerSession::GetUdebL()
       
  3253 // -----------------------------------------------------------------------------
       
  3254 //    
       
  3255 TInt CATStorageServerSession::GetUdebL( const RMessage2& aMessage )
       
  3256     {
       
  3257     LOGSTR1( "STSE TInt CATStorageServerSession::GetUdebL()" );
       
  3258     
       
  3259     iError = KErrNone;
       
  3260     
       
  3261     // Read the process ID at index 0
       
  3262     TUint processId = aMessage.Int0();
       
  3263     
       
  3264     // Get the dynamic process info array
       
  3265     RPointerArray<CATDynProcessInfo> dynProcessArray =
       
  3266                                              iStorageServer.DynProcessInfoArray();
       
  3267     
       
  3268     // Construct a CATDynProcessInfo object with the given process ID for searching
       
  3269     CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
       
  3270     
       
  3271     // Find the index of a CATDynProcessInfo object with the given process ID
       
  3272     TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
       
  3273     TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
       
  3274     delete dynProcessInfo;
       
  3275     dynProcessInfo = NULL;
       
  3276     
       
  3277     // Return, if a process with the requested process ID was not found 
       
  3278     if ( index == KErrNotFound )
       
  3279         {
       
  3280         return index;
       
  3281         }
       
  3282     
       
  3283     // Otherwise get the wanted dynamic process info
       
  3284     dynProcessInfo = dynProcessArray[index];
       
  3285 
       
  3286     // Get the desired process's associated session object
       
  3287     CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
       
  3288     
       
  3289     TBuf8<KMaxVersionName> isUdeb;
       
  3290     if ( sessionObject->iIsUdeb == 1 )
       
  3291         {
       
  3292         isUdeb.Copy( KUdeb() );
       
  3293         }
       
  3294     else if ( sessionObject->iIsUdeb == 0 )
       
  3295         {
       
  3296         isUdeb.Copy( KUrel() );
       
  3297         }
       
  3298     else
       
  3299         {
       
  3300         return KErrNotFound;
       
  3301         }
       
  3302     // Write the whole buffer into aMessage at index 1 for the client
       
  3303     aMessage.WriteL( 1, isUdeb );
       
  3304     
       
  3305     return iError;
       
  3306     }
       
  3307 
       
  3308 // -----------------------------------------------------------------------------
       
  3309 // CATStorageServerSession::SetUdeb()
       
  3310 // -----------------------------------------------------------------------------
       
  3311 //    
       
  3312 void CATStorageServerSession::SetUdeb( const RMessage2& aMessage )
       
  3313     {
       
  3314     LOGSTR1( "STSE void CATStorageServerSession::SetUdeb()" );
       
  3315  
       
  3316     iIsUdeb = aMessage.Int0();
       
  3317     }
       
  3318 
       
  3319 // -----------------------------------------------------------------------------
       
  3320 // CATStorageServerSession::LogAbnormalEnd()
       
  3321 // -----------------------------------------------------------------------------
       
  3322 //    
       
  3323 void CATStorageServerSession::LogAbnormalEnd()
       
  3324     {
       
  3325     LOGSTR1( "STSE void CATStorageServerSession::LogAbnormalEnd()" );
       
  3326     
       
  3327     // Get the current universal time     
       
  3328     TInt64 timeFrom1970( GetTime() );
       
  3329         
       
  3330     switch ( iLogOption )
       
  3331         {
       
  3332         case EATLogToTrace:
       
  3333             {            
       
  3334             // Make a buffer that will be logged
       
  3335             TBuf<KEndAbnormalBufLength> traceBuf;
       
  3336             
       
  3337             // Write the process id to the buffer  
       
  3338             traceBuf.Format( KProcessEndAbnormalTrace, iProcessId );
       
  3339             
       
  3340             // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  3341             // format         
       
  3342             traceBuf.AppendNum( timeFrom1970, EHex );
       
  3343                 
       
  3344             // Append a new line
       
  3345             traceBuf.Append( KNewLineTrace );
       
  3346             
       
  3347             // Write the buffer into the debug channel
       
  3348             RDebug::Print( KTraceMessage, iProcessId, &traceBuf );
       
  3349             }
       
  3350         break;
       
  3351         
       
  3352         case EATLogToFile:
       
  3353             {            
       
  3354             // Make a buffer that will be logged
       
  3355             TBuf8<KEndAbnormalBufLength> loggingBuf;
       
  3356             
       
  3357             // Write the process id to the buffer  
       
  3358             loggingBuf.Format( KProcessEndAbnormal, iProcessId );
       
  3359             
       
  3360             // Append the current time in the 64-bit (max 16 characters) hexadecimal text
       
  3361             // format         
       
  3362             loggingBuf.AppendNum( timeFrom1970, EHex );
       
  3363                 
       
  3364             // Append a new line
       
  3365             loggingBuf.Append( KNewLine );
       
  3366             
       
  3367             // Write the buffer into a file (if possible in the current condition)
       
  3368             iFile.Write( loggingBuf );
       
  3369             }
       
  3370         break;
       
  3371               
       
  3372         default:
       
  3373             break;
       
  3374         }    
       
  3375     }
       
  3376 
       
  3377 // -----------------------------------------------------------------------------
       
  3378 // CATStorageServerSession::GetTime()
       
  3379 // Get the current universal time
       
  3380 // -----------------------------------------------------------------------------
       
  3381 //    
       
  3382 TInt64 CATStorageServerSession::GetTime()
       
  3383     {
       
  3384     LOGSTR1( "STSE void CATStorageServerSession::GetTime()" );
       
  3385     
       
  3386     // Get the current universal time
       
  3387     iTime.UniversalTime();
       
  3388         
       
  3389     // Change the time format that tells the number of microseconds from January First,
       
  3390     // 0 AD nominal Gregorian, into a format that tells the number of microseconds from
       
  3391     // January First, 1970 AD nominal Gregorian. This is a more generic format and
       
  3392     // can be directly exploited by the PC code parsing the data file that this
       
  3393     // server generates.        
       
  3394     return ( iTime.Int64() - iMicroSecondsAt1970 );        
       
  3395     }
       
  3396 
       
  3397 //  End of File