os/kernelhwsrv/kerneltest/f32test/fileutils/src/f32_test_utils.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // @file
    15 // various FAT utilities 
    16 // 
    17 //
    18 
    19 #include "f32_test_utils.h"
    20 using namespace F32_Test_Utils;
    21 
    22 #include "filesystem_fat.h"
    23 
    24 //-------------------------------------------------------------------------------------------------------------------
    25 
    26 //-- define this macro if it is necessarily to exclude all stuff that uses RFs, consoles etc.
    27 //-- may be useful if this code is used for file server extensions. mmp file is a good place to define this macro.
    28 #ifndef FAT_UTILS_LEAN_AND_MEAN
    29 
    30 #include <e32cons.h>
    31 #include <e32math.h>
    32 
    33 //-- Note that the writable static data are not allowed in DLLs i.e. plugins or somethig else.
    34 //-- Thus it needs to be thrown away by preprocessing in such a case.
    35 
    36 static CConsoleBase* pConsole = NULL;   //-- pointer to the text console for printing out data
    37 static TBool  bPrintOutEnabled = ETrue; //-- global flag, if EFalse, all printing out is disabled
    38 
    39 /**
    40     Set the console where the ouput will go.
    41     @param  apConsole pointer to the console. if NULL, the print out will be debug port only.
    42 */
    43 void F32_Test_Utils::SetConsole(CConsoleBase* apConsole)
    44 {
    45     pConsole = apConsole;
    46 }
    47 
    48 /** 
    49     Enable or disable printing out. See DoPrintf()
    50     @param  bEnable If ETrue, print out is enabled
    51     @return previous value of the global bPrintOutEnabled flag
    52 */
    53 TBool F32_Test_Utils::EnablePrintOutput(TBool bEnable)
    54 {
    55     TBool bPrevVal = bPrintOutEnabled;
    56     bPrintOutEnabled = bEnable;
    57 
    58     return bPrevVal;
    59 }
    60 
    61 /**
    62     Print out the drive information.
    63 
    64     @param  aFs             reference to the FS session
    65     @param  aDrive          drive number
    66     @return system-wide error codes.
    67 */
    68 TInt F32_Test_Utils::PrintDrvInfo(RFs &aFs, TInt aDrive)
    69 {
    70     TInt        nRes;
    71     TDriveInfo  driveInfo;
    72     TVolumeInfo volInfo;
    73     TBuf<256>   Buf;
    74 
    75     //-- get drive info
    76     nRes = aFs.Drive(driveInfo, aDrive);
    77     if(nRes != KErrNone)
    78         return nRes;
    79 
    80     nRes = aFs.Volume(volInfo, aDrive);
    81     if(nRes != KErrNone)
    82         return nRes;
    83 
    84     DoPrintf(_L("Drive %c: #%d\n"), 'A'+aDrive, aDrive);
    85 
    86     //-- print the FS name
    87     nRes = aFs.FileSystemName(Buf, aDrive);
    88     if(nRes != KErrNone)
    89         return nRes;
    90     
    91     //-- to find out FS sub type
    92     TFSName fsName;
    93     nRes = aFs.FileSystemSubType(aDrive, fsName); 
    94     if(nRes == KErrNone && Buf.CompareF(fsName) !=KErrNone)
    95     {
    96         Buf.AppendFormat(_L(" (%S)"), &fsName);
    97     }
    98     
    99         
   100    DoPrintf(_L("FS name: %S\n"), &Buf);
   101    
   102    //-- print drive and media attributes
   103    DoPrintf(_L("MediaType: 0x%x\n"), driveInfo.iType);
   104    DoPrintf(_L("DriveAtt:0x%x\n"),driveInfo.iDriveAtt);
   105    DoPrintf(_L("MediaAtt:0x%x\n"),driveInfo.iMediaAtt);
   106 
   107    //-- volume information
   108    DoPrintf(_L("VolId:0x%x\n"),volInfo.iUniqueID);
   109    DoPrintf(_L("VolSz:%ld (%ldK)\n"),volInfo.iSize, volInfo.iSize/1024);
   110    DoPrintf(_L("Free:%ld (%ldK)\n"),volInfo.iFree, volInfo.iFree/1024);
   111 
   112    return KErrNone;
   113 }
   114 
   115 //-------------------------------------------------------------------------------------------------------------------
   116 
   117 
   118 /**
   119     Fill a media region with a given byte pattern
   120     
   121     @param  aFs             reference to the FS session
   122     @param  aDrive          drive number
   123     @param  aMediaStartPos  media region start position  
   124     @param  aMediaEndPos    media region end position
   125     @param  aBytePattern    byte to fill the media region with
   126     
   127     @return system-wide error codes.
   128 */
   129 TInt F32_Test_Utils::FillMedia(RFs &aFs, TInt aDrive, TInt64 aMediaStartPos, TInt64 aMediaEndPos, TUint8 aBytePattern/*=0*/)
   130 {
   131     DoPrintf(_L("~ F32_Test_Utils::FillMedia() drv:%d, from:%u to:%u\n"),aDrive, (TUint32)aMediaStartPos, (TUint32)aMediaEndPos);
   132    
   133     ASSERT(aMediaStartPos<=aMediaEndPos && aMediaStartPos >=0  && aMediaEndPos >=0);
   134 
   135     TInt  nRes = KErrNone;
   136     RBuf8 buf;
   137     const TUint32 KBufSz=65536; //-- zero-buffer size, bytes
   138     
   139     //-- create a buffer, filled with given pattern
   140     nRes = buf.CreateMax(KBufSz);
   141     ASSERT(nRes == KErrNone);
   142     buf.Fill(aBytePattern);
   143 
   144     TUint32 rem = (TUint32)(aMediaEndPos - aMediaStartPos);
   145     while(rem)
   146     {
   147         const TUint32 bytesToWrite=Min(rem, KBufSz);
   148         TPtrC8 ptrData(buf.Ptr(), bytesToWrite);
   149 
   150         nRes = MediaRawWrite(aFs, aDrive, aMediaStartPos, ptrData); 
   151         if(nRes != KErrNone && nRes != KErrDiskFull)
   152             break;
   153 
   154         aMediaStartPos+=bytesToWrite;
   155         rem-=bytesToWrite;
   156     }
   157 
   158     buf.Close();
   159 
   160     return nRes;    
   161 }
   162 
   163 
   164 //-------------------------------------------------------------------------------------------------------------------
   165 
   166 /**
   167     Raw read from the media.
   168 
   169     @param  aFs         reference to the FS session
   170     @param  aDrive      drive number
   171     @param  aMediaPos   media position 
   172     @param  aLen        how many bytes to read
   173     @param  aData       descriptor for the data
   174 
   175     @return system-wide error code.
   176 */
   177 TInt F32_Test_Utils::MediaRawRead(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TUint32 aLen, TDes8& aData)
   178 {
   179     TInt nRes=KErrNone;
   180     TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, aLen, aData));
   181     return nRes;
   182 }
   183 
   184 //-------------------------------------------------------------------------------------------------------------------
   185 
   186 /**
   187     Raw write to the media.
   188 
   189     @param  aFs         reference to the FS session
   190     @param  aDrive      drive number
   191     @param  aMediaPos   media position 
   192     @param  aData       descriptor with the data to write
   193 
   194     @return system-wide error code.
   195 */
   196 TInt F32_Test_Utils::MediaRawWrite(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TDesC8& aData)
   197 {
   198     TInt nRes=KErrNone;
   199     TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, aData));
   200     return nRes;
   201 }
   202 
   203 
   204 //-------------------------------------------------------------------------------------------------------------------
   205 void F32_Test_Utils::DoMediaRawReadL(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TUint32 aLen, TDes8& aData)
   206 {
   207     ASSERT(aMediaPos>=0);
   208     ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   209 
   210     if((TUint32)aData.MaxSize() < aLen)
   211         User::Leave(KErrArgument);
   212 
   213     if(aLen == 0)
   214         return;
   215 
   216     aData.SetLength(aLen);
   217 
   218     RRawDisk  rawDisk;
   219     CleanupClosePushL(rawDisk);
   220     
   221     User::LeaveIfError(rawDisk.Open(aFs, aDrive));
   222     User::LeaveIfError(rawDisk.Read(aMediaPos, aData));
   223 
   224     CleanupStack::PopAndDestroy(&rawDisk);
   225 }
   226 
   227 //-------------------------------------------------------------------------------------------------------------------
   228 void F32_Test_Utils::DoMediaRawWriteL(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TDesC8& aData)
   229 {
   230     ASSERT(aMediaPos>=0);
   231     ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   232   
   233     if(aData.Size() == 0)
   234         return;
   235 
   236     RRawDisk  rawDisk;
   237     CleanupClosePushL(rawDisk);
   238     
   239     User::LeaveIfError(rawDisk.Open(aFs, aDrive));
   240     User::LeaveIfError(rawDisk.Write(aMediaPos, (TDesC8&)aData));
   241 
   242     CleanupStack::PopAndDestroy(&rawDisk);
   243 }
   244 
   245 //-------------------------------------------------------------------------------------------------------------------
   246 
   247 _LIT(KFsName_LFFS,  "lffs");
   248 _LIT(KFsName_Win32, "Win32");
   249 _LIT(KFsName_ExFAT, "ExFat");
   250 _LIT(KFsName_AutoMonuter, "automounter");
   251 
   252 /**  @return ETrue if "Automounter" FS is mounted on this drive */
   253 TBool F32_Test_Utils::Is_Automounter(RFs &aFs, TInt aDrive)
   254 {
   255 	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   256     TFSName f;
   257 	TInt r = aFs.FileSystemName(f, aDrive);
   258     __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   259 
   260     return (f.CompareF(KFsName_AutoMonuter) == 0 );
   261 
   262 }
   263 
   264 /** @return ETrue if "lffs" FS is mounted on this drive */
   265 TBool F32_Test_Utils::Is_Lffs(RFs &aFs, TInt aDrive)
   266 {
   267 	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   268     TFSName f;
   269 	TInt r = aFs.FileSystemName(f, aDrive);
   270     __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   271 
   272     return (f.CompareF(KFsName_LFFS) == 0 );
   273 
   274 }
   275    
   276 /** @return ETrue if "Win32" FS is mounted on this drive (i.e this is emulator's drive c:) */
   277 TBool F32_Test_Utils::Is_Win32(RFs &aFs, TInt aDrive)   
   278 {
   279 	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   280     TFSName f;
   281 	TInt r = aFs.FileSystemName(f, aDrive);
   282     __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   283 
   284     return (f.CompareF(KFsName_Win32) == 0 );
   285 }
   286 
   287 /** @return ETrue if the filesystem if FAT (fat12/16/32) */
   288 TBool F32_Test_Utils::Is_Fat(RFs &aFs, TInt aDrive)
   289 {
   290 	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   291     TFSName fsName;
   292 	TInt nRes = aFs.FileSystemName(fsName, aDrive);
   293     __ASSERT_ALWAYS((nRes==KErrNone) && (fsName.Length()>0), User::Invariant());
   294 
   295     if(fsName.CompareF(KFileSystemName_FAT) == 0)
   296         return ETrue; //-- "FAT" FS is explicitly mounted on this drive
   297 
   298     //-- try analyse file system subtype for the case of automounter FS
   299     nRes = aFs.FileSystemSubType(aDrive,fsName); 
   300     if(nRes !=KErrNone)
   301         return EFalse;
   302 
   303     return (fsName.CompareF(KFSSubType_FAT16) == 0 || fsName.CompareF(KFSSubType_FAT32) == 0 || fsName.CompareF(KFSSubType_FAT12) == 0);
   304 }
   305 
   306 /** returns ETrue if "exFAT" FS is mounted on this drive */
   307 TBool F32_Test_Utils::Is_ExFat(RFs &aFs, TInt aDrive)
   308 {
   309 	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   310     TFSName fsName;
   311 	TInt nRes = aFs.FileSystemName(fsName, aDrive);
   312     __ASSERT_ALWAYS((nRes==KErrNone) && (fsName.Length()>0), User::Invariant());
   313 
   314     if(fsName.CompareF(KFsName_ExFAT) == 0 )
   315         return ETrue; //-- "exFAT" FS is explicitly mounted on this drive
   316 
   317     //-- try analyse file system subtype for the case of automounter FS
   318     nRes = aFs.FileSystemSubType(aDrive,fsName); 
   319     if(nRes !=KErrNone)
   320         return EFalse;
   321 
   322     return (fsName.CompareF(KFsName_ExFAT) == 0);
   323 }
   324 
   325 /** @return ETrue if the filesystem if FAT32 */
   326 TBool F32_Test_Utils::Is_Fat32(RFs &aFs, TInt aDrive)
   327 {
   328     if(!Is_Fat(aFs, aDrive))
   329         return EFalse;
   330 
   331     TFSName fsName;
   332     TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   333     
   334     if(nRes !=KErrNone)
   335         return EFalse;
   336 
   337     return (fsName.CompareF(KFSSubType_FAT32) == 0);
   338 
   339 }
   340 
   341 /** @return ETrue if the filesystem if FAT16 */
   342 TBool F32_Test_Utils::Is_Fat16(RFs &aFs, TInt aDrive)
   343 {
   344     if(!Is_Fat(aFs, aDrive))
   345         return EFalse;
   346 
   347     TFSName fsName;
   348     TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   349     
   350     if(nRes !=KErrNone)
   351         return EFalse;
   352 
   353     return (fsName.CompareF(KFSSubType_FAT16) == 0);
   354 
   355 }
   356 
   357 /** @return ETrue if the filesystem if FAT12 */
   358 TBool F32_Test_Utils::Is_Fat12(RFs &aFs, TInt aDrive)
   359 {
   360     if(!Is_Fat(aFs, aDrive))
   361         return EFalse;
   362 
   363     TFSName fsName;
   364     TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   365     
   366     if(nRes !=KErrNone)
   367         return EFalse;
   368 
   369     return (fsName.CompareF(KFSSubType_FAT12) == 0);
   370 
   371 }
   372 
   373 
   374 static void DoCreateCheckableFileL(RFile64& aFile, TUint64 aSize)
   375 {
   376     
   377     ASSERT(aSize >= TMD5::HashSize);
   378 
   379     //-- 1. set file size
   380     User::LeaveIfError(aFile.SetSize((TInt)aSize));
   381 
   382     //-- 2. leave place for the 16-bytes MD5 hash in the file beginning
   383     TInt64 filePos = TMD5::HashSize;
   384     User::LeaveIfError(aFile.Seek(ESeekStart,filePos));
   385     aSize-=TMD5::HashSize;
   386     
   387     TMD5 md5Hash;
   388     
   389     //-- 3. fill the file with random bytes
   390     const TInt KBufSize=65536; //-- buffer size for writing data
   391     TInt64 rndSeed = aSize % 43283;
   392     if(!rndSeed)
   393         rndSeed = 33521; 
   394 
   395     RBuf8 buf;
   396     buf.CreateMaxL(KBufSize);
   397     
   398     TUint64 prevSz = aSize;
   399     while(aSize)
   400     {
   401         //-- initialize buffer with random rubbish
   402         for(TInt i=0; i<KBufSize; ++i)
   403         {
   404             buf[i] = (TUint8)Math::Rand(rndSeed);
   405         }
   406 
   407         const TUint32 nBytes = (TUint32)Min((TUint64)KBufSize, aSize);
   408         TPtrC8 ptrData(buf.Ptr(), nBytes);
   409         User::LeaveIfError(aFile.Write(ptrData)); //-- write data to the file
   410         md5Hash.Update(ptrData); //-- update MD5 hash        
   411        
   412         aSize-=nBytes;
   413         
   414         if((prevSz - aSize) >= K1MegaByte)
   415         {
   416             prevSz = aSize;
   417             DoPrintf(_L("."));
   418         }
   419     }
   420 
   421 
   422     buf.Close();
   423     DoPrintf(_L("\n"));
   424 
   425     //-- 4. write MD5 hash to the beginning of the file
   426     filePos = 0;
   427     User::LeaveIfError(aFile.Seek(ESeekStart,filePos));
   428     User::LeaveIfError(aFile.Write(md5Hash.Final()));
   429 
   430 }
   431 
   432 
   433 static void DoVerifyCheckableFileL(RFile64& aFile)
   434 {
   435     TInt64 fileSize;
   436     User::LeaveIfError(aFile.Size(fileSize));
   437 
   438     if(fileSize < TMD5::HashSize)
   439        User::Leave(KErrCorrupt); //-- MD5 hash is 16 bytes, it's the minimal file size
   440 
   441     //-- 1. read MD5 header from the file
   442     TBuf8<TMD5::HashSize> md5Header(TMD5::HashSize);
   443     User::LeaveIfError(aFile.Read(md5Header));
   444     fileSize -= TMD5::HashSize;
   445 
   446     //-- 2. read the rest of the data and calculate the checksum
   447     TMD5 md5Hash;
   448     RBuf8 buf;
   449     
   450     const TInt KBufSize=65536; //-- buffer size for writing data
   451     buf.CreateMaxL(KBufSize);
   452     
   453     TUint64 prevSz = fileSize;
   454     while(fileSize)
   455     {
   456         User::LeaveIfError(aFile.Read(buf)); //-- read data from the file
   457 		if (buf.Length() == 0)
   458 			User::Leave(KErrEof);
   459         md5Hash.Update(buf); //-- update MD5 hash        
   460         
   461         fileSize-=buf.Length();
   462 
   463         if((prevSz - fileSize) >= K1MegaByte)
   464         {
   465             prevSz = fileSize;
   466             DoPrintf(_L("."));
   467         }
   468     }
   469 
   470     buf.Close();
   471     DoPrintf(_L("\n"));
   472 
   473     if(md5Hash.Final() != md5Header)
   474         User::Leave(KErrCorrupt); //-- the file is corrupt
   475 }
   476 
   477 //-------------------------------------------------------------------------------------------------------------------
   478 
   479 /**
   480     Creates a file filled with random data. The file has a 16-byte MD5 header at the start, so it is possible to
   481     verify the data validity later. Thus the minimal file size is 16 bytes. The file with the iven name may already
   482     exist; in this case it will be replaced.
   483 
   484     @param  aFs         reference to the FS session
   485     @param  aFileName   name of the file to be created / replaced
   486     @param  aSize       size of the file; 16 bytes min.
   487 
   488     @return Standard error code
   489 */
   490 TInt  F32_Test_Utils::CreateCheckableStuffedFile(RFs& aFs, const TDesC& aFileName, TUint64 aSize)
   491 {
   492 
   493     DoPrintf(_L("~ F32_Test_Utils::CreateCheckableStuffedFile() file:%S, Size:%LU\n"), &aFileName, aSize);
   494 
   495     if(aSize < TMD5::HashSize)
   496         return KErrArgument; //-- MD5 hash is 16 bytes, it's the minimal file size
   497 
   498     RFile64 file;
   499 
   500     //-- 1. create a file
   501     TInt nRes = file.Replace(aFs, aFileName, EFileWrite);
   502     if(nRes != KErrNone)
   503         return nRes;
   504 
   505     TRAP(nRes, DoCreateCheckableFileL(file, aSize));
   506 
   507     file.Close();
   508     return nRes;
   509 }
   510 
   511 
   512 /**
   513     Verify previously created file that has MD5 header at the beginning. See  CreateCheckableStuffedFile(...)
   514 
   515     @param  aFs         reference to the FS session
   516     @param  aFileName   name of the file to be verified
   517 
   518     @return Standard error code. KErrNone if the file contents matches the MD5 header.
   519 */
   520 TInt  F32_Test_Utils::VerifyCheckableFile(RFs& aFs, const TDesC& aFileName)
   521 {
   522     DoPrintf(_L("~ F32_Test_Utils::VerifyCheckableFile() file:%S\n"), &aFileName);
   523 
   524     RFile64 file;
   525 
   526     //-- 1. create a file
   527     TInt nRes = file.Open(aFs, aFileName, EFileRead);
   528     if(nRes != KErrNone)
   529         return nRes;
   530 
   531     TRAP(nRes, DoVerifyCheckableFileL(file));
   532 
   533     file.Close();
   534     return nRes;
   535 
   536 }
   537 
   538 
   539 /**
   540     Create an empty file (not filled with anything). The size of the file is set by using RFile::SetSize().
   541     For FAT this will result in allocating a cluster chain in FAT fable, for the file systems that support sparse files (like LFFS)
   542     this might not work as expected.
   543 
   544     @param  aFs         reference to the FS session
   545     @param  aFileName   name of the file to be created / replaced
   546     @param  aSize       size of the file
   547 
   548     @return Standard error code
   549 */
   550 TInt  F32_Test_Utils::CreateEmptyFile(RFs& aFs, const TDesC& aFileName, TUint64 aSize)
   551 {
   552     DoPrintf(_L("~ F32_Test_Utils::CreateEmptyFile() file:%S, sz:%LU\n"), &aFileName, aSize);
   553 
   554     RFile64 file;
   555 
   556     //-- 1. create a file
   557     TInt nRes = file.Replace(aFs, aFileName, EFileWrite);
   558     if(nRes != KErrNone)
   559         return nRes;
   560 
   561     //-- 2. set file size
   562     nRes = file.SetSize(aSize);
   563 
   564     file.Close();
   565 
   566     return nRes;
   567 }
   568 
   569 //-------------------------------------------------------------------------------------------------------------------
   570 
   571 /**
   572     Dismount and mount the filesystem again, optionally taking time when the mount starts.
   573     The FS can have extensions added into it; this function will handle only the primary extension (if it is present) and
   574     will mont the FS with it. Non-primary extensions are not supported yet.
   575 
   576 
   577     @param  aFs         reference to the FS session
   578     @param  aDrive      drive number
   579     @param  apTimeMountStart pointer to the TTime object, that can be called TTime::UniversalTime() on mount start (this can be
   580                              used for measuring time taken to mount the FS).
   581                              if NULL, no action will be taken.
   582 
   583     @return error code from the RFs::MountFileSystem()
   584 
   585 */
   586 TInt  F32_Test_Utils::RemountFS(RFs& aFs, TInt aDrive, TTime* apTimeMountStart/*=NULL*/)
   587 {
   588     TInt nRes;
   589     DoPrintf(_L("~ F32_Test_Utils::RemountingFS at drive:%d\n"), aDrive);    
   590 
   591     TFSDescriptor fsDescriptor;
   592 
   593     //-- 1. get current FS information 
   594     nRes = GetFileSystemDescriptor(aFs, aDrive, fsDescriptor);
   595     if(nRes != KErrNone)
   596         return nRes;
   597 
   598     //-- 2. dismount the file system
   599     if(fsDescriptor.iPExtName.Length() > 0)
   600     {
   601         DoPrintf(_L("~ Dismounting FS:%S with ext:%S\n"), &fsDescriptor.iFsName, &fsDescriptor.iPExtName);
   602     }
   603     else
   604     {
   605         DoPrintf(_L("~ Dismounting FS:%S\n"), &fsDescriptor.iFsName);    
   606     }
   607 
   608     nRes = aFs.DismountFileSystem(fsDescriptor.iFsName, aDrive);
   609     if(nRes != KErrNone)
   610     {
   611         ASSERT(0);
   612         return nRes;
   613     }
   614 
   615     //-- 3. mount it again
   616     if(apTimeMountStart)
   617         apTimeMountStart->UniversalTime(); //-- take Mount start time
   618 
   619     
   620     nRes = MountFileSystem(aFs, aDrive, fsDescriptor);
   621     return nRes;
   622 }
   623 
   624 //-------------------------------------------------------------------------------------------------------------------
   625 
   626 TFSDescriptor::TFSDescriptor()
   627 {
   628     Init();
   629 }
   630 
   631 void TFSDescriptor::Init()
   632 {
   633     iFsName.SetLength(0);
   634     iPExtName.SetLength(0);
   635     iDriveSynch = EFalse;
   636 }
   637 
   638 TBool TFSDescriptor::operator==(const TFSDescriptor& aRhs) const
   639 {
   640     ASSERT(this != &aRhs);
   641     return (iFsName.CompareF(aRhs.iFsName) == 0 && iPExtName.CompareF(aRhs.iPExtName) == 0 && iDriveSynch == aRhs.iDriveSynch);
   642 }
   643 
   644 
   645 //-------------------------------------------------------------------------------------------------------------------
   646 /**
   647     Gets the information about file system mounted on a drive. This information can be later used for mounting this FS back if it is going to be dismounted
   648 
   649     @param  aFs         reference to the FS session
   650     @param  aDrive      drive number
   651     @param  aFsDesc     file system descriptor
   652     
   653     @return standard error code
   654 */
   655 TInt F32_Test_Utils::GetFileSystemDescriptor(RFs &aFs, TInt aDrive, TFSDescriptor& aFsDesc)
   656 {
   657     TInt nRes;
   658 
   659     //-- 1. get file system name
   660     nRes = aFs.FileSystemName(aFsDesc.iFsName, aDrive);
   661     if(nRes != KErrNone)
   662     {
   663         ASSERT(0);
   664         return nRes;
   665     }
   666     
   667     //-- 2. find out if the drive sync/async
   668     TPckgBuf<TBool> drvSyncBuf;
   669     nRes = aFs.QueryVolumeInfoExt(aDrive, EIsDriveSync, drvSyncBuf);
   670     if(nRes != KErrNone)
   671     {//-- pretend that the drive is asynch. in the case of file system being corrupted. this is 99.9% true
   672        aFsDesc.iDriveSynch = EFalse;
   673     }
   674     else
   675     {
   676         aFsDesc.iDriveSynch = drvSyncBuf();
   677     }
   678 
   679     //-- 3. find out primary extension name if it is present; we will need to add it again when mounting the FS
   680     //-- other extensions (non-primary) are not supported yet
   681     nRes = aFs.ExtensionName(aFsDesc.iPExtName, aDrive, 0);
   682     if(nRes != KErrNone)
   683     {
   684         aFsDesc.iPExtName.SetLength(0);
   685     }
   686 
   687     //-- 3.1 check if the drive has non-primary extensions, fail in this case
   688     TBuf<40> extName;
   689     nRes = aFs.ExtensionName(extName, aDrive, 1);
   690     if(nRes == KErrNone)
   691     {   
   692         DoPrintf(_L("~ F32_Test_Utils::GetFileSystemDescriptor: Non-primary extensions are not supported!\n"));
   693         return KErrNotSupported;
   694     }
   695 
   696 
   697     return KErrNone;
   698 }
   699 
   700 //-------------------------------------------------------------------------------------------------------------------
   701 /**
   702     Mount the file system by the information provided in the FS descriptor
   703 
   704     @param  aFs         reference to the FS session
   705     @param  aDrive      drive number
   706     @param  aFsDesc     file system descriptor containing all necessary information to mount the FS.
   707     
   708     @return standard error code
   709 */
   710 TInt F32_Test_Utils::MountFileSystem(RFs &aFs, TInt aDrive, const TFSDescriptor& aFsDesc)
   711 {
   712     DoPrintf(_L("~ F32_Test_Utils::MountFileSystem() drive:%d Name:%S\n"), aDrive, &aFsDesc.iFsName);  
   713     
   714     TInt nRes;
   715     if(aFsDesc.iFsName.Length() <=0 )
   716     {
   717         ASSERT(0);
   718         return KErrArgument;
   719     }  
   720 
   721 
   722     //-- mount File system 
   723     const TBool bPrimaryExt = (aFsDesc.iPExtName.Length() > 0);
   724 
   725     if(bPrimaryExt)
   726     {//-- we need to mount FS with the primary extension
   727         nRes = aFs.AddExtension(aFsDesc.iPExtName);
   728         if(nRes != KErrNone && nRes != KErrAlreadyExists)
   729         {
   730             ASSERT(0);
   731             return nRes;
   732         }
   733         
   734         nRes = aFs.MountFileSystem(aFsDesc.iFsName, aFsDesc.iPExtName, aDrive, aFsDesc.iDriveSynch);
   735     }
   736     else
   737     {//-- the FS did not have primary extension
   738         nRes = aFs.MountFileSystem(aFsDesc.iFsName, aDrive, aFsDesc.iDriveSynch);
   739     }
   740 
   741 
   742     return nRes;
   743 }
   744 
   745 //-------------------------------------------------------------------------------------------------------------------
   746 /**
   747     Format volume, regardless the file system installed.
   748     
   749     @param  aFs             reference to the FS session
   750     @param  aDrive          drive number
   751     @param  aQuickFormat    if True, a quick format will be performed. otherwise - full
   752     @return system-wide error codes.
   753 */
   754 TInt F32_Test_Utils::FormatDrive(RFs &aFs, TInt aDrive, TBool aQuickFormat)
   755 {
   756     TPtrC fmtTypeName = (aQuickFormat ? _L("Quick") : _L("Full"));
   757     DoPrintf(_L("~ F32_Test_Utils::FormatDrive() drv:%d, type:%S\n"),aDrive, &fmtTypeName);
   758    
   759     ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   760     
   761     RFormat format;
   762     TUint   fmtMode=0;
   763     TInt    fmtCnt=0;
   764     TInt    prevCnt;
   765     TInt    nRes;
   766 
   767     if(aQuickFormat) 
   768         fmtMode |= EQuickFormat;
   769 
   770     //if(aForceErase)
   771     //    fmtMode |= EForceErase;
   772 
   773     TBuf<10> drvName;
   774     drvName.Format(_L("%C:"),'A'+aDrive);
   775     
   776     nRes = format.Open(aFs, drvName, fmtMode, fmtCnt);
   777     if(nRes!=KErrNone)
   778         goto Fail;
   779 
   780     //-- do format steps
   781     prevCnt=fmtCnt;
   782     while(fmtCnt)
   783     {
   784         nRes = format.Next(fmtCnt);
   785         if(nRes!=KErrNone)
   786             goto Fail;
   787 
   788         if(fmtCnt != prevCnt)
   789         {
   790             DoPrintf(_L("."));
   791             prevCnt = fmtCnt;
   792         }
   793     }
   794 
   795     //-- formatting has finished
   796     DoPrintf(_L("\n"));
   797     format.Close();
   798     return KErrNone;
   799 
   800    Fail:
   801     format.Close();
   802     DoPrintf(_L("~ F32_Test_Utils::FormatFatDrive() failed! code:%d\n"), nRes);
   803 
   804     return nRes;
   805 }
   806 
   807 
   808 #endif //FAT_UTILS_LEAN_AND_MEAN
   809 
   810 
   811 //-------------------------------------------------------------------------------------------------------------------
   812 /**
   813     printing interface. Prints out to the console (if is set) and to the debug interface
   814     if pConsole is NULL will print to the debug port only.
   815 */ 
   816 void F32_Test_Utils::DoPrintf(TRefByValue<const TDesC> aFmt,...)
   817 {
   818 #ifndef FAT_UTILS_LEAN_AND_MEAN
   819     if(!bPrintOutEnabled) 
   820         return; //-- disabled by global flag
   821 #endif //FAT_UTILS_LEAN_AND_MEAN
   822 
   823     VA_LIST list;
   824     VA_START(list, aFmt);
   825     
   826     TBuf<0x100> buf;
   827     buf.FormatList(aFmt, list); //-- ignore overflows
   828 
   829 #ifndef FAT_UTILS_LEAN_AND_MEAN
   830     if(pConsole)
   831     {
   832         pConsole->Write(buf);
   833     }
   834 #endif //FAT_UTILS_LEAN_AND_MEAN
   835     
   836     const TInt bufLen = buf.Length();
   837     if(bufLen >0 && buf[bufLen-1] == '\n')
   838     {
   839         buf.Insert(bufLen-1, _L("\r"));
   840     }
   841 
   842     RDebug::RawPrint(buf);
   843 }
   844 
   845 //-------------------------------------------------------------------------------------------------------------------
   846 
   847 TBool F32_Test_Utils::IsPowerOf2(TUint32 aVal)
   848     {
   849     if (aVal==0)
   850         return EFalse;
   851 
   852     return !(aVal & (aVal-1));
   853     }
   854 
   855 
   856 //-------------------------------------------------------------------------------------------------------------------
   857 TUint32 F32_Test_Utils::Log2(TUint32 aVal)
   858 {
   859     __ASSERT_COMPILE(sizeof(TUint32) == 4);
   860     ASSERT(aVal);
   861 
   862     TUint32 bitPos=31;
   863 
   864     if(!(aVal >> 16)) {bitPos-=16; aVal<<=16;}
   865     if(!(aVal >> 24)) {bitPos-=8;  aVal<<=8 ;}
   866     if(!(aVal >> 28)) {bitPos-=4;  aVal<<=4 ;}
   867     if(!(aVal >> 30)) {bitPos-=2;  aVal<<=2 ;}
   868     if(!(aVal >> 31)) {bitPos-=1;}
   869     
   870     return bitPos;
   871 }
   872 
   873 
   874 //-------------------------------------------------------------------------------------------------------------------
   875 
   876 //###################################################################################################################
   877 //#     TMD5 class implementation 
   878 //###################################################################################################################
   879 
   880 
   881 #define T_MASK ((TUint32)~0)
   882 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
   883 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
   884 #define T3    0x242070db
   885 #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
   886 #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
   887 #define T6    0x4787c62a
   888 #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
   889 #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
   890 #define T9    0x698098d8
   891 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
   892 #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
   893 #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
   894 #define T13    0x6b901122
   895 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
   896 #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
   897 #define T16    0x49b40821
   898 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
   899 #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
   900 #define T19    0x265e5a51
   901 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
   902 #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
   903 #define T22    0x02441453
   904 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
   905 #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
   906 #define T25    0x21e1cde6
   907 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
   908 #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
   909 #define T28    0x455a14ed
   910 #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
   911 #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
   912 #define T31    0x676f02d9
   913 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
   914 #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
   915 #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
   916 #define T35    0x6d9d6122
   917 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
   918 #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
   919 #define T38    0x4bdecfa9
   920 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
   921 #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
   922 #define T41    0x289b7ec6
   923 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
   924 #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
   925 #define T44    0x04881d05
   926 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
   927 #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
   928 #define T47    0x1fa27cf8
   929 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
   930 #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
   931 #define T50    0x432aff97
   932 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
   933 #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
   934 #define T53    0x655b59c3
   935 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
   936 #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
   937 #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
   938 #define T57    0x6fa87e4f
   939 #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
   940 #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
   941 #define T60    0x4e0811a1
   942 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
   943 #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
   944 #define T63    0x2ad7d2bb
   945 #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
   946 
   947 
   948 TMD5::TMD5()
   949 {
   950     Reset();
   951 }
   952 
   953 //-------------------------------------------------------------------------------------------------------------------
   954 
   955 void TMD5::Md5_process(const TUint8 *data /*[64]*/)
   956 {
   957     TUint32
   958     a = iState.abcd[0], b = iState.abcd[1],
   959     c = iState.abcd[2], d = iState.abcd[3];
   960     TUint32 t;
   961     TUint32 xbuf[16];
   962     const TUint32 *X;
   963 
   964     {
   965         static const TInt w = 1;
   966         if (*((const TUint8 *)&w)) 
   967         {
   968             if (!((data - (const TUint8 *)0) & 3)) {
   969             X = (const TUint32 *)data;
   970             } else {
   971             memcpy(xbuf, data, 64);
   972             X = xbuf;
   973             }
   974         }
   975         else
   976         {
   977             const TUint8 *xp = data;
   978             TInt i;
   979 
   980             X = xbuf;       /* (dynamic only) */
   981             for (i = 0; i < 16; ++i, xp += 4)
   982             xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
   983         }
   984     }
   985 
   986 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
   987 
   988 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
   989 #define SET(a, b, c, d, k, s, Ti)\
   990   t = a + F(b,c,d) + X[k] + Ti;\
   991   a = ROTATE_LEFT(t, s) + b
   992     SET(a, b, c, d,  0,  7,  T1);
   993     SET(d, a, b, c,  1, 12,  T2);
   994     SET(c, d, a, b,  2, 17,  T3);
   995     SET(b, c, d, a,  3, 22,  T4);
   996     SET(a, b, c, d,  4,  7,  T5);
   997     SET(d, a, b, c,  5, 12,  T6);
   998     SET(c, d, a, b,  6, 17,  T7);
   999     SET(b, c, d, a,  7, 22,  T8);
  1000     SET(a, b, c, d,  8,  7,  T9);
  1001     SET(d, a, b, c,  9, 12, T10);
  1002     SET(c, d, a, b, 10, 17, T11);
  1003     SET(b, c, d, a, 11, 22, T12);
  1004     SET(a, b, c, d, 12,  7, T13);
  1005     SET(d, a, b, c, 13, 12, T14);
  1006     SET(c, d, a, b, 14, 17, T15);
  1007     SET(b, c, d, a, 15, 22, T16);
  1008 #undef SET
  1009 
  1010 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
  1011 #define SET(a, b, c, d, k, s, Ti)\
  1012     t = a + G(b,c,d) + X[k] + Ti;\
  1013     a = ROTATE_LEFT(t, s) + b
  1014     SET(a, b, c, d,  1,  5, T17);
  1015     SET(d, a, b, c,  6,  9, T18);
  1016     SET(c, d, a, b, 11, 14, T19);
  1017     SET(b, c, d, a,  0, 20, T20);
  1018     SET(a, b, c, d,  5,  5, T21);
  1019     SET(d, a, b, c, 10,  9, T22);
  1020     SET(c, d, a, b, 15, 14, T23);
  1021     SET(b, c, d, a,  4, 20, T24);
  1022     SET(a, b, c, d,  9,  5, T25);
  1023     SET(d, a, b, c, 14,  9, T26);
  1024     SET(c, d, a, b,  3, 14, T27);
  1025     SET(b, c, d, a,  8, 20, T28);
  1026     SET(a, b, c, d, 13,  5, T29);
  1027     SET(d, a, b, c,  2,  9, T30);
  1028     SET(c, d, a, b,  7, 14, T31);
  1029     SET(b, c, d, a, 12, 20, T32);
  1030 #undef SET
  1031 
  1032 #define H(x, y, z) ((x) ^ (y) ^ (z))
  1033 #define SET(a, b, c, d, k, s, Ti)\
  1034     t = a + H(b,c,d) + X[k] + Ti;\
  1035     a = ROTATE_LEFT(t, s) + b
  1036     SET(a, b, c, d,  5,  4, T33);
  1037     SET(d, a, b, c,  8, 11, T34);
  1038     SET(c, d, a, b, 11, 16, T35);
  1039     SET(b, c, d, a, 14, 23, T36);
  1040     SET(a, b, c, d,  1,  4, T37);
  1041     SET(d, a, b, c,  4, 11, T38);
  1042     SET(c, d, a, b,  7, 16, T39);
  1043     SET(b, c, d, a, 10, 23, T40);
  1044     SET(a, b, c, d, 13,  4, T41);
  1045     SET(d, a, b, c,  0, 11, T42);
  1046     SET(c, d, a, b,  3, 16, T43);
  1047     SET(b, c, d, a,  6, 23, T44);
  1048     SET(a, b, c, d,  9,  4, T45);
  1049     SET(d, a, b, c, 12, 11, T46);
  1050     SET(c, d, a, b, 15, 16, T47);
  1051     SET(b, c, d, a,  2, 23, T48);
  1052 #undef SET
  1053 
  1054 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
  1055 #define SET(a, b, c, d, k, s, Ti)\
  1056     t = a + I(b,c,d) + X[k] + Ti;\
  1057     a = ROTATE_LEFT(t, s) + b
  1058     SET(a, b, c, d,  0,  6, T49);
  1059     SET(d, a, b, c,  7, 10, T50);
  1060     SET(c, d, a, b, 14, 15, T51);
  1061     SET(b, c, d, a,  5, 21, T52);
  1062     SET(a, b, c, d, 12,  6, T53);
  1063     SET(d, a, b, c,  3, 10, T54);
  1064     SET(c, d, a, b, 10, 15, T55);
  1065     SET(b, c, d, a,  1, 21, T56);
  1066     SET(a, b, c, d,  8,  6, T57);
  1067     SET(d, a, b, c, 15, 10, T58);
  1068     SET(c, d, a, b,  6, 15, T59);
  1069     SET(b, c, d, a, 13, 21, T60);
  1070     SET(a, b, c, d,  4,  6, T61);
  1071     SET(d, a, b, c, 11, 10, T62);
  1072     SET(c, d, a, b,  2, 15, T63);
  1073     SET(b, c, d, a,  9, 21, T64);
  1074 #undef SET
  1075 
  1076     iState.abcd[0] += a;
  1077     iState.abcd[1] += b;
  1078     iState.abcd[2] += c;
  1079     iState.abcd[3] += d;
  1080 
  1081 }
  1082 
  1083 //-------------------------------------------------------------------------------------------------------------------
  1084 void TMD5::Md5_append(const TUint8 *data, TInt nbytes)
  1085 {
  1086     const TUint8 *p = data;
  1087     
  1088     TInt left = nbytes;
  1089 
  1090     TInt offset = (iState.count[0] >> 3) & 63;
  1091     TUint32 nbits = (TUint32)(nbytes << 3);
  1092 
  1093     if (nbytes <= 0)
  1094     return;
  1095 
  1096     iState.count[1] += nbytes >> 29;
  1097     iState.count[0] += nbits;
  1098     if (iState.count[0] < nbits)
  1099     iState.count[1]++;
  1100 
  1101     if (offset) 
  1102     {
  1103     TInt copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
  1104 
  1105     memcpy(iState.buf + offset, p, copy);
  1106     if (offset + copy < 64)
  1107         return;
  1108     p += copy;
  1109     left -= copy;
  1110     Md5_process(iState.buf);
  1111     }
  1112 
  1113     for (; left >= 64; p += 64, left -= 64)
  1114         Md5_process(p);
  1115 
  1116     if (left)
  1117         memcpy(iState.buf, p, left);
  1118 
  1119 }
  1120 
  1121 
  1122 void TMD5::Md5_finish()
  1123 {
  1124     static const TUint8 pad[64] = {
  1125     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1126     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1127     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1128     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  1129     };
  1130     TUint8 data[8];
  1131     TInt i;
  1132 
  1133     for (i = 0; i < 8; ++i)
  1134     data[i] = (TUint8)(iState.count[i >> 2] >> ((i & 3) << 3));
  1135     Md5_append(pad, ((55 - (iState.count[0] >> 3)) & 63) + 1);
  1136     Md5_append(data, 8);
  1137     for (i = 0; i < 16; ++i)
  1138         iDigest[i] = (TUint8)(iState.abcd[i >> 2] >> ((i & 3) << 3));
  1139 
  1140 }
  1141 
  1142 //-------------------------------------------------------------------------------------------------------------------
  1143 
  1144 /** reset MD5 to initial state */
  1145 void TMD5::Reset()
  1146 {
  1147     iState.count[0] = iState.count[1] = 0;
  1148     iState.abcd[0] = 0x67452301;
  1149     iState.abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
  1150     iState.abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
  1151     iState.abcd[3] = 0x10325476;
  1152 }
  1153 
  1154 
  1155 /**
  1156     Update MD5 with some data
  1157     @param aMessage descriptor with data
  1158 */
  1159 void TMD5::Update(const TDesC8& aMessage)
  1160 {
  1161     Md5_append((const TUint8*)aMessage.Ptr(), aMessage.Length());
  1162 }
  1163 
  1164 /**
  1165     Finalise MD5 calculation
  1166     @param  aMessage descriptor with data
  1167     @return pointer to 16-byte array with MD5 hash
  1168 */
  1169 TPtrC8 TMD5::Final(const TDesC8& aMessage)
  1170 {
  1171     Update(aMessage);
  1172     Md5_finish();
  1173     return TPtrC8(iDigest, HashSize);
  1174 }
  1175 
  1176 
  1177 /**
  1178     Finalise MD5 calculation
  1179     @return pointer to 16-byte array with MD5 hash
  1180 */
  1181 TPtrC8 TMD5::Final()
  1182 {
  1183     Md5_finish();
  1184     return TPtrC8(iDigest, HashSize);
  1185 }
  1186 
  1187 
  1188 
  1189 
  1190 
  1191 
  1192 
  1193 
  1194 
  1195 
  1196 
  1197 
  1198 
  1199 
  1200 
  1201 
  1202 
  1203 
  1204 
  1205 
  1206 
  1207