perfsrv/memspy/Engine/Source/MemSpyEngineUtils.cpp
changeset 48 516af714ebb4
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
       
     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:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <memspy/engine/memspyengineutils.h>
       
    19 
       
    20 // System includes
       
    21 #include <e32svr.h>
       
    22 #include <e32capability.h>
       
    23 #ifdef __EPOC32__
       
    24 #include <e32rom.h>
       
    25 #endif
       
    26 
       
    27 // User includes
       
    28 #include <memspy/engine/memspyengineoutputsink.h>
       
    29 
       
    30 // Typedefs
       
    31 typedef TInt(*TSysUtilGetSWVersionFunction)(TDes&);
       
    32 
       
    33 // Literal constants
       
    34 _LIT( KMemSpyEngineDoubleColon, "::" );
       
    35 _LIT( KMemSpyKernelProcessName, "ekern" );
       
    36 _LIT( KMemSpyKernelProcessFullName, "ekern.exe[100041af]0001" );
       
    37 _LIT( KMemSpyKernelThreadName, "Supervisor" );
       
    38 _LIT( KMemSpyLogRootPath, "\\MemSpy\\" );
       
    39 _LIT( KMemSpyLogDefaultName, "Log" );
       
    40 _LIT( KMemSpyLogFileNameWithTimeStamp, "MemSpy - %4d%02d%02d - %02d.%02d.%02d.%06d - " );
       
    41 
       
    42 
       
    43 EXPORT_C void MemSpyEngineUtils::FormatTimeL( TDes& aBuf, const TInt64& aTimeVal, TBool aLocalTime )
       
    44     {
       
    45     const TTime time( aTimeVal );
       
    46     FormatTimeL( aBuf, time, aLocalTime );
       
    47     }
       
    48 
       
    49 
       
    50 EXPORT_C void MemSpyEngineUtils::FormatTimeL( TDes& aBuf, const TTime& aTime, TBool aLocalTime )
       
    51     {
       
    52     if  ( aLocalTime )
       
    53         {
       
    54         _LIT( KFormatSpecLocal, "%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%:3%+B" );
       
    55         // 
       
    56         TTime time( aTime );
       
    57         time += User::UTCOffset();
       
    58         time.FormatL( aBuf, KFormatSpecLocal );
       
    59         }
       
    60     else
       
    61         {
       
    62         _LIT( KFormatSpecUTC, "%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%:3%+B UTC" );
       
    63         aTime.FormatL( aBuf, KFormatSpecUTC );
       
    64         }
       
    65     }
       
    66 
       
    67 
       
    68 void MemSpyEngineUtils::FormatTimeSimple( TDes& aBuf, const TTime& aTime )
       
    69     {
       
    70     const TDateTime dt = aTime.DateTime();
       
    71     //
       
    72     _LIT( KTimeFormatSpec, "%04d%02d%02d %02d:%02d:%02d" );
       
    73     aBuf.Format( KTimeFormatSpec, dt.Year(), dt.Month()+1, dt.Day()+1, dt.Hour(), dt.Minute(), dt.Second() );
       
    74     }
       
    75 
       
    76 
       
    77 EXPORT_C void MemSpyEngineUtils::FormatHex( TDes& aBuf, TInt aValue )
       
    78     {
       
    79     _LIT(KMemSpyNumericHexFormat, "0x%08x");
       
    80     aBuf.Format( KMemSpyNumericHexFormat, aValue );
       
    81     }
       
    82 
       
    83 
       
    84 EXPORT_C TMemSpySizeText MemSpyEngineUtils::FormatSizeText( const TInt64& aValue, TInt aDecimalPlaces, TBool aExtraRounding )
       
    85     {
       
    86     _LIT(KFormatKilo, "%dK");
       
    87     _LIT(KFormatMega, "%SM");
       
    88     _LIT(KFormatGiga, "%SG");
       
    89 
       
    90 	TMemSpySizeText buf;
       
    91 	if  ( aValue < 1024000 )					// If < 1000K
       
    92 		{
       
    93 		TInt sizeInK = 0;
       
    94 
       
    95         if  ( aValue != 0 )
       
    96 			{
       
    97 			sizeInK = I64INT( (aValue + 512) >> 10 );
       
    98 			if  (sizeInK < 1)
       
    99                 {
       
   100 				sizeInK = 1;
       
   101                 }
       
   102 			if  (sizeInK > 999)
       
   103                 {
       
   104 				sizeInK = 999;
       
   105                 }
       
   106 			}
       
   107 
       
   108         buf.Format( KFormatKilo, sizeInK );
       
   109 		}
       
   110 	else
       
   111 		{
       
   112 		TReal sizeInM = I64INT( aValue );
       
   113 		sizeInM /= 1048576;
       
   114 		if  ( sizeInM < 1 )
       
   115             {
       
   116 			sizeInM = 1;
       
   117             }
       
   118 
       
   119         TPtrC pFormat( KFormatMega );
       
   120 		if  ( sizeInM >= 1000 )
       
   121 			{
       
   122 			sizeInM /= 1024;				// Size in G
       
   123 			if  (sizeInM < 1)
       
   124                 {
       
   125 				sizeInM = 1;
       
   126                 }
       
   127 			
       
   128             pFormat.Set( KFormatGiga );
       
   129 			}
       
   130 
       
   131         if  ( sizeInM > 999.9)
       
   132             {
       
   133             sizeInM = 999.9;
       
   134             }
       
   135 
       
   136         if  ( aExtraRounding )
       
   137             {
       
   138 			sizeInM += 0.499999;
       
   139             }
       
   140 
       
   141 		TBuf<16> size;
       
   142 		size.Num( sizeInM, TRealFormat( 14, aDecimalPlaces ) );	// Allow for "17179869184.0"G which is 2^64
       
   143         buf.Format( pFormat, &size );
       
   144 		}
       
   145 
       
   146     return buf;
       
   147     }
       
   148 
       
   149 
       
   150 EXPORT_C TMemSpySizeText MemSpyEngineUtils::FormatSizeText( TInt aValue )
       
   151     {
       
   152     const TInt64 value( aValue );
       
   153 	return FormatSizeText( value );
       
   154     }
       
   155 
       
   156 
       
   157 EXPORT_C TMemSpySizeText MemSpyEngineUtils::FormatSizeTextPrecise( TInt aValue )
       
   158     {
       
   159     /*
       
   160     0123456789
       
   161     ==========
       
   162     1234567890
       
   163 
       
   164     1,234,567,890
       
   165 
       
   166     len = 10;
       
   167     */
       
   168 
       
   169 	TMemSpySizeText buf;
       
   170     buf.Num( aValue );
       
   171     TInt index = buf.Length() - 3;
       
   172     while( index > 0 )
       
   173         {
       
   174         buf.Insert( index, _L(",") );
       
   175         index -= 3;
       
   176         }
       
   177 
       
   178     return buf;
       
   179     }
       
   180 
       
   181 
       
   182 EXPORT_C TBool MemSpyEngineUtils::IsRomAddress( TAny* aAddress )
       
   183     {
       
   184     TBool inRom = EFalse;
       
   185     //
       
   186 #ifdef __EPOC32__
       
   187     const TInt err = User::IsRomAddress( inRom, aAddress );
       
   188     if  ( err != KErrNone )
       
   189         {
       
   190         inRom = EFalse;
       
   191         }
       
   192 #else
       
   193     (void) aAddress;
       
   194     inRom = ETrue;
       
   195 #endif
       
   196     //
       
   197     return inRom;
       
   198     }
       
   199 
       
   200 
       
   201 EXPORT_C void MemSpyEngineUtils::GetCapabilityName( TDes& aBuf, TCapability aCapability )
       
   202     {
       
   203     const TPtrC8 pName( (const TUint8*) CapabilityNames[ aCapability ] );
       
   204     aBuf.Copy( pName );
       
   205     }
       
   206 
       
   207 
       
   208 EXPORT_C TBool MemSpyEngineUtils::StripText( TDes& aText, const TDesC& aStrip )
       
   209     {
       
   210     TBool stripped = EFalse;
       
   211     const TInt stripTextLength = aStrip.Length();
       
   212     //
       
   213     if  ( aText.Length() > stripTextLength )
       
   214         {
       
   215         const TPtrC leftText( aText.Left( stripTextLength ) );
       
   216         if  ( leftText.CompareF( aStrip ) == 0)
       
   217             {
       
   218             // Try to find the first double colon
       
   219             const TInt doubleColonPos = aText.Find( KMemSpyEngineDoubleColon );
       
   220             if  ( doubleColonPos >= stripTextLength )
       
   221                 {
       
   222                 aText.Delete( 0, doubleColonPos + 2 );
       
   223                 }
       
   224             else
       
   225                 {
       
   226                 aText.Delete( 0, stripTextLength );
       
   227                 }
       
   228 
       
   229             stripped = ETrue;
       
   230             }
       
   231         }
       
   232     //
       
   233     return stripped;
       
   234     }
       
   235 
       
   236 
       
   237 EXPORT_C void MemSpyEngineUtils::TextBeforeDoubleColon( TDes& aText )
       
   238     {
       
   239     const TInt doubleColonPos = aText.Find( KMemSpyEngineDoubleColon );
       
   240     if  ( doubleColonPos >= 0 )
       
   241         {
       
   242         aText.SetLength( doubleColonPos );
       
   243         }
       
   244     }
       
   245 
       
   246 
       
   247 EXPORT_C void MemSpyEngineUtils::TextAfterDoubleColon( TDes& aText )
       
   248     {
       
   249     const TInt doubleColonPos = aText.Find( KMemSpyEngineDoubleColon );
       
   250     if  ( doubleColonPos >= 0 )
       
   251         {
       
   252         aText.Delete( 0, doubleColonPos + 2 );
       
   253         }
       
   254     }
       
   255 
       
   256 
       
   257 TPtrC MemSpyEngineUtils::TextAfterLastDoubleColon( const TDesC& aText )
       
   258     {
       
   259     TPtrC ret( aText );
       
   260 
       
   261     // ABCD::123
       
   262     const TInt doubleColonPos = aText.LocateReverseF( ':' );
       
   263     if  ( doubleColonPos > 0 )
       
   264         {
       
   265         if ( aText[ doubleColonPos ] == ':' )
       
   266             {
       
   267             ret.Set( aText.Mid( doubleColonPos + 1 ) );
       
   268             }
       
   269         }
       
   270 
       
   271     return ret;
       
   272     }
       
   273 
       
   274 
       
   275 EXPORT_C TMemSpyPercentText MemSpyEngineUtils::FormatPercentage( TReal aOneHundredPercentValue, TReal aValue )
       
   276     {
       
   277     const TReal value = (( aValue / aOneHundredPercentValue) * 100.0);
       
   278     
       
   279     _LIT(KPercentFormat, "%3.2f %%");
       
   280 
       
   281     TMemSpyPercentText val;
       
   282     val.Format( KPercentFormat, value );
       
   283     
       
   284     return val;
       
   285     }
       
   286 
       
   287 
       
   288 EXPORT_C HBufC* MemSpyEngineUtils::CleanupTextLC( const TDesC& aText )
       
   289     {
       
   290     _LIT( KMemSpyTabChar, "\t" );
       
   291     _LIT( KMemSpyTabReplacementChar, " " );
       
   292     _LIT( KMemSpyNewLineChar, "\n" );
       
   293     _LIT( KMemSpyNewLineReplacementChar, " " );
       
   294 
       
   295     TInt pos = KErrNotFound;
       
   296 
       
   297     // Create replacement
       
   298     const TInt originalLength = aText.Length();
       
   299     HBufC* text = HBufC::NewLC( originalLength );
       
   300     TPtr pText( text->Des() );
       
   301     pText.Copy( aText );
       
   302 
       
   303     // Replace tabs
       
   304     pos = pText.Find( KMemSpyTabChar );
       
   305     while( pos >= 0 )
       
   306         {
       
   307         pText.Replace( pos, KMemSpyTabChar().Length(), KMemSpyTabReplacementChar );
       
   308         pos = pText.Find( KMemSpyTabChar );
       
   309         }
       
   310 
       
   311     // Replace tabs
       
   312     pos = pText.Find( KMemSpyNewLineChar );
       
   313     while( pos >= 0 )
       
   314         {
       
   315         pText.Replace( pos, KMemSpyNewLineChar().Length(), KMemSpyNewLineReplacementChar );
       
   316         pos = pText.Find( KMemSpyNewLineChar );
       
   317         }
       
   318 
       
   319     __ASSERT_ALWAYS( pText.Length() == aText.Length(), User::Invariant() );
       
   320     return text;
       
   321     }
       
   322 
       
   323 
       
   324 EXPORT_C void MemSpyEngineUtils::GetRomInfoL( TDes& aPlatform, TDes& aChecksum )
       
   325     {
       
   326     aPlatform.Zero();
       
   327     aChecksum.Zero();
       
   328 
       
   329 #ifdef __EPOC32__
       
   330     // Get checksum 
       
   331     TRomHeader* romHeader = (TRomHeader*) UserSvr::RomHeaderAddress();
       
   332     if  ( romHeader )
       
   333         {
       
   334         aChecksum.Format( _L("0x%08x"), romHeader->iCheckSum );
       
   335         }
       
   336 #endif
       
   337 
       
   338     // Platform version
       
   339     _LIT( KS60VersionDllName, "SysUtil.dll" );
       
   340     RLibrary lib;
       
   341     if  ( lib.Load( KS60VersionDllName ) == KErrNone )
       
   342         {
       
   343         // Get exported version function
       
   344 #ifdef __EPOC32__
       
   345         const TInt KSysUtilOrdinal = 9;
       
   346 #else
       
   347         const TInt KSysUtilOrdinal = 6;
       
   348 #endif
       
   349         TLibraryFunction fn = lib.Lookup( KSysUtilOrdinal );
       
   350         if ( fn != NULL )
       
   351             {
       
   352             TSysUtilGetSWVersionFunction sysUtilGetSWVersion = (TSysUtilGetSWVersionFunction) fn;
       
   353             TInt err = (*sysUtilGetSWVersion)( aPlatform );
       
   354             err = err;
       
   355 #ifdef _DEBUG
       
   356             RDebug::Printf( "MemSpyEngineUtils::GetRomInfoL() - SysUtil::GetSWVersion() returned: %d", err );
       
   357 #endif
       
   358             }
       
   359 
       
   360         lib.Close();
       
   361         }
       
   362     }
       
   363 
       
   364 
       
   365 EXPORT_C void MemSpyEngineUtils::GetFolderL( RFs& aFsSession, TDes& aFolder, const CMemSpyEngineSinkMetaData& aMetaData, const TDriveNumber* aForceDrive )
       
   366     {
       
   367     const TChar KMemSpyDirectorySeparator = '\\';
       
   368     const TChar KMemSpyDriveSeparator = ':';
       
   369 
       
   370     TDriveList drives;
       
   371     User::LeaveIfError( aFsSession.DriveList( drives ) );
       
   372     
       
   373     // We prefer to log to MMC if its available. If not, we'll log to C: instead. On
       
   374     // WINS we prefer to log to C: because its easier to find via Windows Explorer.
       
   375     TDriveNumber logDrive = EDriveC;
       
   376     if  ( aForceDrive )
       
   377         {
       
   378         logDrive = *aForceDrive;
       
   379         TRACE( RDebug::Printf( "MemSpyEngineUtils::GetFolderL() - FORCED TO DRIVE: %c:\\", *aForceDrive + 'A' ) );
       
   380         }
       
   381     else
       
   382         {
       
   383 		// check if drive is specified in root path
       
   384 		if ( aMetaData.Root().Length() > 2 && aMetaData.Root()[1] == KMemSpyDriveSeparator )
       
   385 			{
       
   386 			TChar drive = aMetaData.Root()[0];
       
   387 			
       
   388 			// check if drive is valid
       
   389 			if (drives.Locate(drive) != KErrNone)
       
   390 				{
       
   391 				TDriveUnit driveUnit( aMetaData.Root().Left(1) );
       
   392 				logDrive = static_cast<TDriveNumber>(static_cast<TInt>(driveUnit));
       
   393 				}
       
   394 			else
       
   395 				{
       
   396 				logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession );
       
   397 				}
       
   398 			}
       
   399 		else
       
   400 			{
       
   401 			logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession );
       
   402 			}
       
   403         }
       
   404 
       
   405     // Prepare the drive buffer
       
   406     HBufC* fileName = HBufC::NewLC( KMaxFileName * 2 );
       
   407     TPtr pFileName( fileName->Des() );
       
   408 
       
   409     // Prepare the drive name
       
   410     TDriveUnit driveUnit( logDrive );
       
   411     pFileName.Append( driveUnit.Name() );
       
   412     
       
   413     if ( aMetaData.Root().Length() == 0 )
       
   414     	{
       
   415 		pFileName.Append( KMemSpyLogRootPath );
       
   416     	}
       
   417     else
       
   418     	{
       
   419 		TPtrC root( aMetaData.Root() );
       
   420 		// check if root path contains drive (e.g. c:) and remove it
       
   421 		if ( root.Length() > 2 && root[1] == KMemSpyDriveSeparator )
       
   422 			{
       
   423 			root.Set( root.Mid( 2 ) );
       
   424 			}
       
   425 		// check if root starts with \ and remove it
       
   426 		if ( root.Length() > 1 && root[0] == KMemSpyDirectorySeparator )
       
   427 			{
       
   428 			root.Set( root.Mid( 1 ) );
       
   429 			}
       
   430 		
       
   431 		// append root path
       
   432 		pFileName.Append( KMemSpyDirectorySeparator );
       
   433 		pFileName.Append( root );
       
   434 		
       
   435 		// add trailing slash if necessary
       
   436 		if ( root[root.Length() - 1] != KMemSpyDirectorySeparator )
       
   437 			{
       
   438 			pFileName.Append( KMemSpyDirectorySeparator );
       
   439 			}
       
   440     	}
       
   441 
       
   442     // Add any custom folder information
       
   443     if  ( aMetaData.Folder().Length() > 0 )
       
   444         {
       
   445         pFileName.Append( aMetaData.Folder() );
       
   446         TRACE( RDebug::Print( _L("MemSpyEngineUtils::GetFolderL() - client folder: %S" ), &pFileName ) );
       
   447 
       
   448         TChar lastChar = pFileName[ pFileName.Length() - 1 ];
       
   449 
       
   450         // Take into account any "group" timestamp appendix
       
   451         if  ( aMetaData.FolderTimeStamp().Length() )
       
   452             {
       
   453             if  ( lastChar != KMemSpyDirectorySeparator )
       
   454                 {
       
   455                 // Doesn't end with a backslash, so we must
       
   456                 // add separator info before the timestamp
       
   457                 pFileName.Append( ' ' );
       
   458                 pFileName.Append( '-' );
       
   459                 pFileName.Append( ' ' );
       
   460                 }
       
   461 
       
   462             pFileName.Append( aMetaData.FolderTimeStamp() );
       
   463             TRACE( RDebug::Print( _L("MemSpyEngineUtils::GetFolderL() - timestamp folder: %S" ), &pFileName ) );
       
   464             }
       
   465 
       
   466         // Ensure post-fixed by '\\' character
       
   467         lastChar = ( pFileName[ pFileName.Length() - 1 ] );
       
   468         if  ( lastChar != KMemSpyDirectorySeparator )
       
   469             {
       
   470             pFileName.Append( KMemSpyDirectorySeparator );
       
   471             }
       
   472         }
       
   473 
       
   474     // Generate the timestamp file name
       
   475     if  ( aMetaData.UseFileTimeStamp() )
       
   476         {
       
   477         TTime now;
       
   478         now.HomeTime();
       
   479         const TDateTime dateTime( now.DateTime() );
       
   480         pFileName.AppendFormat( KMemSpyLogFileNameWithTimeStamp, dateTime.Year(), dateTime.Month() + 1, dateTime.Day() + 1,
       
   481                                                                  dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond() );
       
   482         TRACE( RDebug::Print( _L("MemSpyEngineUtils::GetFolderL() - timestamp file: %S" ), &pFileName ) );
       
   483         }
       
   484         
       
   485     // Do we have some context information? If so, make sure its printable
       
   486     HBufC* cleanedContext = NULL;
       
   487     if  ( aMetaData.Context().Length() )
       
   488         {
       
   489         cleanedContext = CleanContextInfoLC( aMetaData.Context() );
       
   490         }
       
   491     else
       
   492         {
       
   493         // This must be the standard log then...
       
   494         cleanedContext = KMemSpyLogDefaultName().AllocLC();
       
   495         }
       
   496 
       
   497     TRACE( RDebug::Print( _L("MemSpyEngineUtils::GetFolderL() - cleaned context: %S" ), cleanedContext ) );
       
   498 
       
   499     // Build final part of file name
       
   500     pFileName.Append( *cleanedContext );
       
   501     CleanupStack::PopAndDestroy( cleanedContext );
       
   502 
       
   503     // and finally, add the extension
       
   504     if  ( aMetaData.Extension().Length() )
       
   505         {
       
   506         pFileName.Append( aMetaData.Extension() );
       
   507         }
       
   508     else
       
   509         {
       
   510         pFileName.Append( KMemSpyLogDefaultExtension );
       
   511         }
       
   512 
       
   513     TRACE( RDebug::Print( _L("MemSpyEngineUtils::GetFolderL() - END - fileName: %S"), fileName ) );
       
   514     if  ( pFileName.Length() > aFolder.MaxLength() )
       
   515         {
       
   516         User::Leave( KErrOverflow );
       
   517         }
       
   518 
       
   519     aFolder.Copy( pFileName );
       
   520     CleanupStack::PopAndDestroy( fileName );
       
   521     }
       
   522 
       
   523 
       
   524 TDriveNumber MemSpyEngineUtils::LocateSuitableDrive( RFs& aFsSession )
       
   525     {
       
   526 #ifndef __WINS__
       
   527     TDriveInfo driveInfo;
       
   528     TDriveList drives;
       
   529     if  ( aFsSession.DriveList( drives ) == KErrNone )
       
   530         {
       
   531         for( TInt i=EDriveY; i>=EDriveD; i-- )
       
   532             {
       
   533             const TDriveNumber drive = static_cast< TDriveNumber >( i );
       
   534             TRACE( RDebug::Print( _L("MemSpyEngineUtils::LocateSuitableDrive() - drive: %c:\\, available: %d"), drive + 'A', drives[ drive ] ) );
       
   535 
       
   536             // Is drive available from an OS perspective?
       
   537             if  ( drives[ drive ] != 0 )
       
   538                 {
       
   539                 // Check whether there is a disk present or not.
       
   540                 const TInt driveInfoErr = aFsSession.Drive( driveInfo, drive );
       
   541                 TRACE( RDebug::Print( _L("MemSpyEngineUtils::LocateSuitableDrive() - drive: %c:\\, driveInfoErr: %d"), drive + 'A', driveInfoErr ) );
       
   542                 if  ( driveInfoErr == KErrNone )
       
   543                     {
       
   544                     // Check if the drive is removable. We'll try to 
       
   545                     // save data here in preference to the system drive if at all
       
   546                     // possible...
       
   547                     const TBool removable = ( driveInfo.iDriveAtt & KDriveAttRemovable );
       
   548                     const TBool ram = ( driveInfo.iType == EMediaRam );
       
   549                     const TBool rom = ( driveInfo.iType == EMediaRom );
       
   550                     TRACE( RDebug::Printf( "MemSpyEngineUtils::LocateSuitableDrive() - drive: %c:\\, removable: %d, ram: %d, rom: %d", drive + 'A', removable, ram, rom ) );
       
   551                     //
       
   552                     if  ( removable && !( ram || rom ) )
       
   553                         {
       
   554                         // Check free space etc
       
   555                         TVolumeInfo volInfo;
       
   556                         const TInt volInfoErr = aFsSession.Volume( volInfo, drive );
       
   557                         TRACE( RDebug::Printf( "MemSpyEngineUtils::LocateSuitableDrive() - drive: %c:\\, volInfoErr: %d", drive + 'A', volInfoErr ) );
       
   558                         if  ( volInfoErr == KErrNone )
       
   559                             {
       
   560                             TRACE( RDebug::Printf( "MemSpyEngineUtils::LocateSuitableDrive() - END - using drive: %c:\\", drive + 'A', removable ) );
       
   561                             return drive;
       
   562                             }
       
   563                         }
       
   564                     }
       
   565                 }
       
   566             }
       
   567 
       
   568         }
       
   569 #else
       
   570 	(void) aFsSession;
       
   571 #endif
       
   572 
       
   573     // Don't use RFs::GetSystemDrive() as it isn't available on v9.1
       
   574     TRACE( RDebug::Printf( "MemSpyEngineUtils::LocateSuitableDrive() - END - fallback to EDriveC" ) );
       
   575     return EDriveC;
       
   576     }
       
   577 
       
   578 
       
   579 void MemSpyEngineUtils::FormatTimeNowL( TDes& aBuf, TBool aLocalTime )
       
   580     {
       
   581     TTime time;
       
   582     if  ( aLocalTime )
       
   583         {
       
   584         time.HomeTime();
       
   585         }
       
   586     else
       
   587         {
       
   588         time.UniversalTime();
       
   589         }
       
   590 
       
   591     FormatTimeL( aBuf, time, aLocalTime );
       
   592     }
       
   593 
       
   594 
       
   595 HBufC* MemSpyEngineUtils::DataStreamFolderNameWithTimeStampLC( const TDesC& aFolderName )
       
   596     {
       
   597     TMemSpyTimeText time;
       
   598     FormatTimeNowL( time, ETrue );
       
   599     //
       
   600     HBufC* folder = HBufC::NewLC( aFolderName.Length() + time.Length() + 10 );
       
   601     TPtr pFolder( folder->Des() );
       
   602     //
       
   603     pFolder.Append( aFolderName );
       
   604     pFolder.Append( time );
       
   605     //
       
   606     return folder;
       
   607     }
       
   608 
       
   609 
       
   610 void MemSpyEngineUtils::GetKernelHeapThreadName( TDes& aBuf, TBool aFullName )
       
   611     {
       
   612     if  ( !aFullName )
       
   613         {
       
   614         aBuf.Copy( KMemSpyKernelProcessName );
       
   615         }
       
   616     else
       
   617         {
       
   618         aBuf.Copy( KMemSpyKernelProcessFullName );
       
   619         }
       
   620 
       
   621     aBuf.Append( KMemSpyEngineDoubleColon );
       
   622     aBuf.Append( KMemSpyKernelThreadName );
       
   623     }
       
   624 
       
   625 
       
   626 void MemSpyEngineUtils::GetKernelHeapThreadAndProcessNames( TDes& aThreadName, TDes& aProcessName )
       
   627     {
       
   628     aThreadName.Copy( KMemSpyKernelThreadName );
       
   629     aProcessName.Copy( KMemSpyKernelProcessName );
       
   630     }
       
   631 
       
   632 
       
   633 TUint32 MemSpyEngineUtils::Hash( const TDesC& aText )
       
   634     {
       
   635     // DJB Hash Function
       
   636     TUint32 hash = 5381;
       
   637     //
       
   638     const TInt length = aText.Length();
       
   639     for( TInt i = 0; i < length; i++)
       
   640         {
       
   641         hash = ((hash << 5) + hash) + aText[ i ];
       
   642         }
       
   643     //
       
   644     return hash;
       
   645     }
       
   646 
       
   647 
       
   648 void MemSpyEngineUtils::Panic( TMemSpyEnginePanic aPanic )
       
   649     {
       
   650     _LIT( KMemSpyEnginePanicCategory, "MemSpyEngine" );
       
   651     User::Panic( KMemSpyEnginePanicCategory, aPanic );
       
   652     }
       
   653 
       
   654 
       
   655 TProcessId MemSpyEngineUtils::IdentifyFileServerProcessIdL()
       
   656     {
       
   657     TRACE( RDebug::Printf( "MemSpyEngineUtils::IdentifyFileServerProcessIdL() - START" ) );
       
   658 
       
   659     TProcessId ret = KNullProcessId;
       
   660 
       
   661     _LIT(KFindMask, "efile*");
       
   662     TFullName name( KFindMask );
       
   663     TFindProcess finder( name );
       
   664 
       
   665     if  ( finder.Next( name ) == KErrNone )
       
   666         {
       
   667         RProcess process;
       
   668         const TInt error = process.Open( name );
       
   669         TRACE( RDebug::Print( _L("MemSpyEngineUtils::IdentifyFileServerProcessIdL() - process open err: %d, name: %S"), error, &name ) );
       
   670         if  ( error == KErrNone )
       
   671             {
       
   672             ret = process.Id();
       
   673             }
       
   674 
       
   675         process.Close();
       
   676         }
       
   677 
       
   678     TRACE( RDebug::Printf( "MemSpyEngineUtils::IdentifyFileServerProcessIdL() - almost done - ret: %d", (TUint) ret ) );
       
   679 
       
   680     if  ( static_cast< TUint >( ret ) == KNullProcessId )
       
   681         {
       
   682         User::Leave( KErrNotFound );
       
   683         }
       
   684 
       
   685     TRACE( RDebug::Printf( "MemSpyEngineUtils::IdentifyFileServerProcessIdL() - END - ret: %d", (TUint) ret ) );
       
   686     return ret;
       
   687     }
       
   688 
       
   689 
       
   690 HBufC* MemSpyEngineUtils::CleanContextInfoLC( const TDesC& aContext )
       
   691     {
       
   692     TRACE( RDebug::Print( _L("MemSpyEngineUtils::CleanContextInfoLC() - START - %S"), &aContext ) );
       
   693     TFileName fileName;
       
   694 
       
   695     TBool seenDoubleColon = EFalse;
       
   696     const TInt length = aContext.Length();
       
   697     for( TInt i=0; i<length; i++ )
       
   698         {
       
   699         const TChar c( aContext[ i ] );
       
   700         const TBool haveNextChar = ( i+1 < length );
       
   701         //
       
   702         //TRACE( RDebug::Print( _L("MemSpyEngineUtils::CleanContextInfoLC() - c[%03d]: \'%c\', haveNextChar: %d, seenDoubleColon: %d"), i, (TUint32) c, haveNextChar, seenDoubleColon ) );
       
   703         //
       
   704         if  ( c == ':' && haveNextChar && aContext[ i + 1 ] == ':' )
       
   705             {
       
   706             // Skip double colon
       
   707             i++;
       
   708             fileName.Append( '-' );
       
   709             seenDoubleColon = ETrue;
       
   710             }
       
   711         else if ( c == '.' )
       
   712             {
       
   713             if  ( seenDoubleColon )
       
   714                 {
       
   715                 break;
       
   716                 }
       
   717             else
       
   718                 {
       
   719                 fileName.Append( '-' );
       
   720                 }
       
   721             }
       
   722         else
       
   723             {
       
   724             fileName.Append( c );
       
   725             }
       
   726         }
       
   727 
       
   728     TRACE( RDebug::Print( _L("MemSpyEngineUtils::CleanContextInfoLC() - END - %S"), &fileName ) );
       
   729     return fileName.AllocLC();
       
   730     }
       
   731 
       
   732