kerneltest/f32test/fileutils/src/f32_test_utils.cpp
changeset 0 a41df078684a
child 175 5af6c74cd793
child 256 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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