os/kernelhwsrv/kerneltest/f32test/fileutils/src/f32_test_utils.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/fileutils/src/f32_test_utils.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1207 @@
     1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// @file
    1.18 +// various FAT utilities 
    1.19 +// 
    1.20 +//
    1.21 +
    1.22 +#include "f32_test_utils.h"
    1.23 +using namespace F32_Test_Utils;
    1.24 +
    1.25 +#include "filesystem_fat.h"
    1.26 +
    1.27 +//-------------------------------------------------------------------------------------------------------------------
    1.28 +
    1.29 +//-- define this macro if it is necessarily to exclude all stuff that uses RFs, consoles etc.
    1.30 +//-- may be useful if this code is used for file server extensions. mmp file is a good place to define this macro.
    1.31 +#ifndef FAT_UTILS_LEAN_AND_MEAN
    1.32 +
    1.33 +#include <e32cons.h>
    1.34 +#include <e32math.h>
    1.35 +
    1.36 +//-- Note that the writable static data are not allowed in DLLs i.e. plugins or somethig else.
    1.37 +//-- Thus it needs to be thrown away by preprocessing in such a case.
    1.38 +
    1.39 +static CConsoleBase* pConsole = NULL;   //-- pointer to the text console for printing out data
    1.40 +static TBool  bPrintOutEnabled = ETrue; //-- global flag, if EFalse, all printing out is disabled
    1.41 +
    1.42 +/**
    1.43 +    Set the console where the ouput will go.
    1.44 +    @param  apConsole pointer to the console. if NULL, the print out will be debug port only.
    1.45 +*/
    1.46 +void F32_Test_Utils::SetConsole(CConsoleBase* apConsole)
    1.47 +{
    1.48 +    pConsole = apConsole;
    1.49 +}
    1.50 +
    1.51 +/** 
    1.52 +    Enable or disable printing out. See DoPrintf()
    1.53 +    @param  bEnable If ETrue, print out is enabled
    1.54 +    @return previous value of the global bPrintOutEnabled flag
    1.55 +*/
    1.56 +TBool F32_Test_Utils::EnablePrintOutput(TBool bEnable)
    1.57 +{
    1.58 +    TBool bPrevVal = bPrintOutEnabled;
    1.59 +    bPrintOutEnabled = bEnable;
    1.60 +
    1.61 +    return bPrevVal;
    1.62 +}
    1.63 +
    1.64 +/**
    1.65 +    Print out the drive information.
    1.66 +
    1.67 +    @param  aFs             reference to the FS session
    1.68 +    @param  aDrive          drive number
    1.69 +    @return system-wide error codes.
    1.70 +*/
    1.71 +TInt F32_Test_Utils::PrintDrvInfo(RFs &aFs, TInt aDrive)
    1.72 +{
    1.73 +    TInt        nRes;
    1.74 +    TDriveInfo  driveInfo;
    1.75 +    TVolumeInfo volInfo;
    1.76 +    TBuf<256>   Buf;
    1.77 +
    1.78 +    //-- get drive info
    1.79 +    nRes = aFs.Drive(driveInfo, aDrive);
    1.80 +    if(nRes != KErrNone)
    1.81 +        return nRes;
    1.82 +
    1.83 +    nRes = aFs.Volume(volInfo, aDrive);
    1.84 +    if(nRes != KErrNone)
    1.85 +        return nRes;
    1.86 +
    1.87 +    DoPrintf(_L("Drive %c: #%d\n"), 'A'+aDrive, aDrive);
    1.88 +
    1.89 +    //-- print the FS name
    1.90 +    nRes = aFs.FileSystemName(Buf, aDrive);
    1.91 +    if(nRes != KErrNone)
    1.92 +        return nRes;
    1.93 +    
    1.94 +    //-- to find out FS sub type
    1.95 +    TFSName fsName;
    1.96 +    nRes = aFs.FileSystemSubType(aDrive, fsName); 
    1.97 +    if(nRes == KErrNone && Buf.CompareF(fsName) !=KErrNone)
    1.98 +    {
    1.99 +        Buf.AppendFormat(_L(" (%S)"), &fsName);
   1.100 +    }
   1.101 +    
   1.102 +        
   1.103 +   DoPrintf(_L("FS name: %S\n"), &Buf);
   1.104 +   
   1.105 +   //-- print drive and media attributes
   1.106 +   DoPrintf(_L("MediaType: 0x%x\n"), driveInfo.iType);
   1.107 +   DoPrintf(_L("DriveAtt:0x%x\n"),driveInfo.iDriveAtt);
   1.108 +   DoPrintf(_L("MediaAtt:0x%x\n"),driveInfo.iMediaAtt);
   1.109 +
   1.110 +   //-- volume information
   1.111 +   DoPrintf(_L("VolId:0x%x\n"),volInfo.iUniqueID);
   1.112 +   DoPrintf(_L("VolSz:%ld (%ldK)\n"),volInfo.iSize, volInfo.iSize/1024);
   1.113 +   DoPrintf(_L("Free:%ld (%ldK)\n"),volInfo.iFree, volInfo.iFree/1024);
   1.114 +
   1.115 +   return KErrNone;
   1.116 +}
   1.117 +
   1.118 +//-------------------------------------------------------------------------------------------------------------------
   1.119 +
   1.120 +
   1.121 +/**
   1.122 +    Fill a media region with a given byte pattern
   1.123 +    
   1.124 +    @param  aFs             reference to the FS session
   1.125 +    @param  aDrive          drive number
   1.126 +    @param  aMediaStartPos  media region start position  
   1.127 +    @param  aMediaEndPos    media region end position
   1.128 +    @param  aBytePattern    byte to fill the media region with
   1.129 +    
   1.130 +    @return system-wide error codes.
   1.131 +*/
   1.132 +TInt F32_Test_Utils::FillMedia(RFs &aFs, TInt aDrive, TInt64 aMediaStartPos, TInt64 aMediaEndPos, TUint8 aBytePattern/*=0*/)
   1.133 +{
   1.134 +    DoPrintf(_L("~ F32_Test_Utils::FillMedia() drv:%d, from:%u to:%u\n"),aDrive, (TUint32)aMediaStartPos, (TUint32)aMediaEndPos);
   1.135 +   
   1.136 +    ASSERT(aMediaStartPos<=aMediaEndPos && aMediaStartPos >=0  && aMediaEndPos >=0);
   1.137 +
   1.138 +    TInt  nRes = KErrNone;
   1.139 +    RBuf8 buf;
   1.140 +    const TUint32 KBufSz=65536; //-- zero-buffer size, bytes
   1.141 +    
   1.142 +    //-- create a buffer, filled with given pattern
   1.143 +    nRes = buf.CreateMax(KBufSz);
   1.144 +    ASSERT(nRes == KErrNone);
   1.145 +    buf.Fill(aBytePattern);
   1.146 +
   1.147 +    TUint32 rem = (TUint32)(aMediaEndPos - aMediaStartPos);
   1.148 +    while(rem)
   1.149 +    {
   1.150 +        const TUint32 bytesToWrite=Min(rem, KBufSz);
   1.151 +        TPtrC8 ptrData(buf.Ptr(), bytesToWrite);
   1.152 +
   1.153 +        nRes = MediaRawWrite(aFs, aDrive, aMediaStartPos, ptrData); 
   1.154 +        if(nRes != KErrNone && nRes != KErrDiskFull)
   1.155 +            break;
   1.156 +
   1.157 +        aMediaStartPos+=bytesToWrite;
   1.158 +        rem-=bytesToWrite;
   1.159 +    }
   1.160 +
   1.161 +    buf.Close();
   1.162 +
   1.163 +    return nRes;    
   1.164 +}
   1.165 +
   1.166 +
   1.167 +//-------------------------------------------------------------------------------------------------------------------
   1.168 +
   1.169 +/**
   1.170 +    Raw read from the media.
   1.171 +
   1.172 +    @param  aFs         reference to the FS session
   1.173 +    @param  aDrive      drive number
   1.174 +    @param  aMediaPos   media position 
   1.175 +    @param  aLen        how many bytes to read
   1.176 +    @param  aData       descriptor for the data
   1.177 +
   1.178 +    @return system-wide error code.
   1.179 +*/
   1.180 +TInt F32_Test_Utils::MediaRawRead(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TUint32 aLen, TDes8& aData)
   1.181 +{
   1.182 +    TInt nRes=KErrNone;
   1.183 +    TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, aLen, aData));
   1.184 +    return nRes;
   1.185 +}
   1.186 +
   1.187 +//-------------------------------------------------------------------------------------------------------------------
   1.188 +
   1.189 +/**
   1.190 +    Raw write to the media.
   1.191 +
   1.192 +    @param  aFs         reference to the FS session
   1.193 +    @param  aDrive      drive number
   1.194 +    @param  aMediaPos   media position 
   1.195 +    @param  aData       descriptor with the data to write
   1.196 +
   1.197 +    @return system-wide error code.
   1.198 +*/
   1.199 +TInt F32_Test_Utils::MediaRawWrite(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TDesC8& aData)
   1.200 +{
   1.201 +    TInt nRes=KErrNone;
   1.202 +    TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, aData));
   1.203 +    return nRes;
   1.204 +}
   1.205 +
   1.206 +
   1.207 +//-------------------------------------------------------------------------------------------------------------------
   1.208 +void F32_Test_Utils::DoMediaRawReadL(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TUint32 aLen, TDes8& aData)
   1.209 +{
   1.210 +    ASSERT(aMediaPos>=0);
   1.211 +    ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.212 +
   1.213 +    if((TUint32)aData.MaxSize() < aLen)
   1.214 +        User::Leave(KErrArgument);
   1.215 +
   1.216 +    if(aLen == 0)
   1.217 +        return;
   1.218 +
   1.219 +    aData.SetLength(aLen);
   1.220 +
   1.221 +    RRawDisk  rawDisk;
   1.222 +    CleanupClosePushL(rawDisk);
   1.223 +    
   1.224 +    User::LeaveIfError(rawDisk.Open(aFs, aDrive));
   1.225 +    User::LeaveIfError(rawDisk.Read(aMediaPos, aData));
   1.226 +
   1.227 +    CleanupStack::PopAndDestroy(&rawDisk);
   1.228 +}
   1.229 +
   1.230 +//-------------------------------------------------------------------------------------------------------------------
   1.231 +void F32_Test_Utils::DoMediaRawWriteL(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TDesC8& aData)
   1.232 +{
   1.233 +    ASSERT(aMediaPos>=0);
   1.234 +    ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.235 +  
   1.236 +    if(aData.Size() == 0)
   1.237 +        return;
   1.238 +
   1.239 +    RRawDisk  rawDisk;
   1.240 +    CleanupClosePushL(rawDisk);
   1.241 +    
   1.242 +    User::LeaveIfError(rawDisk.Open(aFs, aDrive));
   1.243 +    User::LeaveIfError(rawDisk.Write(aMediaPos, (TDesC8&)aData));
   1.244 +
   1.245 +    CleanupStack::PopAndDestroy(&rawDisk);
   1.246 +}
   1.247 +
   1.248 +//-------------------------------------------------------------------------------------------------------------------
   1.249 +
   1.250 +_LIT(KFsName_LFFS,  "lffs");
   1.251 +_LIT(KFsName_Win32, "Win32");
   1.252 +_LIT(KFsName_ExFAT, "ExFat");
   1.253 +_LIT(KFsName_AutoMonuter, "automounter");
   1.254 +
   1.255 +/**  @return ETrue if "Automounter" FS is mounted on this drive */
   1.256 +TBool F32_Test_Utils::Is_Automounter(RFs &aFs, TInt aDrive)
   1.257 +{
   1.258 +	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.259 +    TFSName f;
   1.260 +	TInt r = aFs.FileSystemName(f, aDrive);
   1.261 +    __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   1.262 +
   1.263 +    return (f.CompareF(KFsName_AutoMonuter) == 0 );
   1.264 +
   1.265 +}
   1.266 +
   1.267 +/** @return ETrue if "lffs" FS is mounted on this drive */
   1.268 +TBool F32_Test_Utils::Is_Lffs(RFs &aFs, TInt aDrive)
   1.269 +{
   1.270 +	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.271 +    TFSName f;
   1.272 +	TInt r = aFs.FileSystemName(f, aDrive);
   1.273 +    __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   1.274 +
   1.275 +    return (f.CompareF(KFsName_LFFS) == 0 );
   1.276 +
   1.277 +}
   1.278 +   
   1.279 +/** @return ETrue if "Win32" FS is mounted on this drive (i.e this is emulator's drive c:) */
   1.280 +TBool F32_Test_Utils::Is_Win32(RFs &aFs, TInt aDrive)   
   1.281 +{
   1.282 +	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.283 +    TFSName f;
   1.284 +	TInt r = aFs.FileSystemName(f, aDrive);
   1.285 +    __ASSERT_ALWAYS((r==KErrNone) && (f.Length()>0), User::Invariant());
   1.286 +
   1.287 +    return (f.CompareF(KFsName_Win32) == 0 );
   1.288 +}
   1.289 +
   1.290 +/** @return ETrue if the filesystem if FAT (fat12/16/32) */
   1.291 +TBool F32_Test_Utils::Is_Fat(RFs &aFs, TInt aDrive)
   1.292 +{
   1.293 +	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.294 +    TFSName fsName;
   1.295 +	TInt nRes = aFs.FileSystemName(fsName, aDrive);
   1.296 +    __ASSERT_ALWAYS((nRes==KErrNone) && (fsName.Length()>0), User::Invariant());
   1.297 +
   1.298 +    if(fsName.CompareF(KFileSystemName_FAT) == 0)
   1.299 +        return ETrue; //-- "FAT" FS is explicitly mounted on this drive
   1.300 +
   1.301 +    //-- try analyse file system subtype for the case of automounter FS
   1.302 +    nRes = aFs.FileSystemSubType(aDrive,fsName); 
   1.303 +    if(nRes !=KErrNone)
   1.304 +        return EFalse;
   1.305 +
   1.306 +    return (fsName.CompareF(KFSSubType_FAT16) == 0 || fsName.CompareF(KFSSubType_FAT32) == 0 || fsName.CompareF(KFSSubType_FAT12) == 0);
   1.307 +}
   1.308 +
   1.309 +/** returns ETrue if "exFAT" FS is mounted on this drive */
   1.310 +TBool F32_Test_Utils::Is_ExFat(RFs &aFs, TInt aDrive)
   1.311 +{
   1.312 +	ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.313 +    TFSName fsName;
   1.314 +	TInt nRes = aFs.FileSystemName(fsName, aDrive);
   1.315 +    __ASSERT_ALWAYS((nRes==KErrNone) && (fsName.Length()>0), User::Invariant());
   1.316 +
   1.317 +    if(fsName.CompareF(KFsName_ExFAT) == 0 )
   1.318 +        return ETrue; //-- "exFAT" FS is explicitly mounted on this drive
   1.319 +
   1.320 +    //-- try analyse file system subtype for the case of automounter FS
   1.321 +    nRes = aFs.FileSystemSubType(aDrive,fsName); 
   1.322 +    if(nRes !=KErrNone)
   1.323 +        return EFalse;
   1.324 +
   1.325 +    return (fsName.CompareF(KFsName_ExFAT) == 0);
   1.326 +}
   1.327 +
   1.328 +/** @return ETrue if the filesystem if FAT32 */
   1.329 +TBool F32_Test_Utils::Is_Fat32(RFs &aFs, TInt aDrive)
   1.330 +{
   1.331 +    if(!Is_Fat(aFs, aDrive))
   1.332 +        return EFalse;
   1.333 +
   1.334 +    TFSName fsName;
   1.335 +    TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   1.336 +    
   1.337 +    if(nRes !=KErrNone)
   1.338 +        return EFalse;
   1.339 +
   1.340 +    return (fsName.CompareF(KFSSubType_FAT32) == 0);
   1.341 +
   1.342 +}
   1.343 +
   1.344 +/** @return ETrue if the filesystem if FAT16 */
   1.345 +TBool F32_Test_Utils::Is_Fat16(RFs &aFs, TInt aDrive)
   1.346 +{
   1.347 +    if(!Is_Fat(aFs, aDrive))
   1.348 +        return EFalse;
   1.349 +
   1.350 +    TFSName fsName;
   1.351 +    TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   1.352 +    
   1.353 +    if(nRes !=KErrNone)
   1.354 +        return EFalse;
   1.355 +
   1.356 +    return (fsName.CompareF(KFSSubType_FAT16) == 0);
   1.357 +
   1.358 +}
   1.359 +
   1.360 +/** @return ETrue if the filesystem if FAT12 */
   1.361 +TBool F32_Test_Utils::Is_Fat12(RFs &aFs, TInt aDrive)
   1.362 +{
   1.363 +    if(!Is_Fat(aFs, aDrive))
   1.364 +        return EFalse;
   1.365 +
   1.366 +    TFSName fsName;
   1.367 +    TInt nRes = aFs.FileSystemSubType(aDrive,fsName); 
   1.368 +    
   1.369 +    if(nRes !=KErrNone)
   1.370 +        return EFalse;
   1.371 +
   1.372 +    return (fsName.CompareF(KFSSubType_FAT12) == 0);
   1.373 +
   1.374 +}
   1.375 +
   1.376 +
   1.377 +static void DoCreateCheckableFileL(RFile64& aFile, TUint64 aSize)
   1.378 +{
   1.379 +    
   1.380 +    ASSERT(aSize >= TMD5::HashSize);
   1.381 +
   1.382 +    //-- 1. set file size
   1.383 +    User::LeaveIfError(aFile.SetSize((TInt)aSize));
   1.384 +
   1.385 +    //-- 2. leave place for the 16-bytes MD5 hash in the file beginning
   1.386 +    TInt64 filePos = TMD5::HashSize;
   1.387 +    User::LeaveIfError(aFile.Seek(ESeekStart,filePos));
   1.388 +    aSize-=TMD5::HashSize;
   1.389 +    
   1.390 +    TMD5 md5Hash;
   1.391 +    
   1.392 +    //-- 3. fill the file with random bytes
   1.393 +    const TInt KBufSize=65536; //-- buffer size for writing data
   1.394 +    TInt64 rndSeed = aSize % 43283;
   1.395 +    if(!rndSeed)
   1.396 +        rndSeed = 33521; 
   1.397 +
   1.398 +    RBuf8 buf;
   1.399 +    buf.CreateMaxL(KBufSize);
   1.400 +    
   1.401 +    TUint64 prevSz = aSize;
   1.402 +    while(aSize)
   1.403 +    {
   1.404 +        //-- initialize buffer with random rubbish
   1.405 +        for(TInt i=0; i<KBufSize; ++i)
   1.406 +        {
   1.407 +            buf[i] = (TUint8)Math::Rand(rndSeed);
   1.408 +        }
   1.409 +
   1.410 +        const TUint32 nBytes = (TUint32)Min((TUint64)KBufSize, aSize);
   1.411 +        TPtrC8 ptrData(buf.Ptr(), nBytes);
   1.412 +        User::LeaveIfError(aFile.Write(ptrData)); //-- write data to the file
   1.413 +        md5Hash.Update(ptrData); //-- update MD5 hash        
   1.414 +       
   1.415 +        aSize-=nBytes;
   1.416 +        
   1.417 +        if((prevSz - aSize) >= K1MegaByte)
   1.418 +        {
   1.419 +            prevSz = aSize;
   1.420 +            DoPrintf(_L("."));
   1.421 +        }
   1.422 +    }
   1.423 +
   1.424 +
   1.425 +    buf.Close();
   1.426 +    DoPrintf(_L("\n"));
   1.427 +
   1.428 +    //-- 4. write MD5 hash to the beginning of the file
   1.429 +    filePos = 0;
   1.430 +    User::LeaveIfError(aFile.Seek(ESeekStart,filePos));
   1.431 +    User::LeaveIfError(aFile.Write(md5Hash.Final()));
   1.432 +
   1.433 +}
   1.434 +
   1.435 +
   1.436 +static void DoVerifyCheckableFileL(RFile64& aFile)
   1.437 +{
   1.438 +    TInt64 fileSize;
   1.439 +    User::LeaveIfError(aFile.Size(fileSize));
   1.440 +
   1.441 +    if(fileSize < TMD5::HashSize)
   1.442 +       User::Leave(KErrCorrupt); //-- MD5 hash is 16 bytes, it's the minimal file size
   1.443 +
   1.444 +    //-- 1. read MD5 header from the file
   1.445 +    TBuf8<TMD5::HashSize> md5Header(TMD5::HashSize);
   1.446 +    User::LeaveIfError(aFile.Read(md5Header));
   1.447 +    fileSize -= TMD5::HashSize;
   1.448 +
   1.449 +    //-- 2. read the rest of the data and calculate the checksum
   1.450 +    TMD5 md5Hash;
   1.451 +    RBuf8 buf;
   1.452 +    
   1.453 +    const TInt KBufSize=65536; //-- buffer size for writing data
   1.454 +    buf.CreateMaxL(KBufSize);
   1.455 +    
   1.456 +    TUint64 prevSz = fileSize;
   1.457 +    while(fileSize)
   1.458 +    {
   1.459 +        User::LeaveIfError(aFile.Read(buf)); //-- read data from the file
   1.460 +		if (buf.Length() == 0)
   1.461 +			User::Leave(KErrEof);
   1.462 +        md5Hash.Update(buf); //-- update MD5 hash        
   1.463 +        
   1.464 +        fileSize-=buf.Length();
   1.465 +
   1.466 +        if((prevSz - fileSize) >= K1MegaByte)
   1.467 +        {
   1.468 +            prevSz = fileSize;
   1.469 +            DoPrintf(_L("."));
   1.470 +        }
   1.471 +    }
   1.472 +
   1.473 +    buf.Close();
   1.474 +    DoPrintf(_L("\n"));
   1.475 +
   1.476 +    if(md5Hash.Final() != md5Header)
   1.477 +        User::Leave(KErrCorrupt); //-- the file is corrupt
   1.478 +}
   1.479 +
   1.480 +//-------------------------------------------------------------------------------------------------------------------
   1.481 +
   1.482 +/**
   1.483 +    Creates a file filled with random data. The file has a 16-byte MD5 header at the start, so it is possible to
   1.484 +    verify the data validity later. Thus the minimal file size is 16 bytes. The file with the iven name may already
   1.485 +    exist; in this case it will be replaced.
   1.486 +
   1.487 +    @param  aFs         reference to the FS session
   1.488 +    @param  aFileName   name of the file to be created / replaced
   1.489 +    @param  aSize       size of the file; 16 bytes min.
   1.490 +
   1.491 +    @return Standard error code
   1.492 +*/
   1.493 +TInt  F32_Test_Utils::CreateCheckableStuffedFile(RFs& aFs, const TDesC& aFileName, TUint64 aSize)
   1.494 +{
   1.495 +
   1.496 +    DoPrintf(_L("~ F32_Test_Utils::CreateCheckableStuffedFile() file:%S, Size:%LU\n"), &aFileName, aSize);
   1.497 +
   1.498 +    if(aSize < TMD5::HashSize)
   1.499 +        return KErrArgument; //-- MD5 hash is 16 bytes, it's the minimal file size
   1.500 +
   1.501 +    RFile64 file;
   1.502 +
   1.503 +    //-- 1. create a file
   1.504 +    TInt nRes = file.Replace(aFs, aFileName, EFileWrite);
   1.505 +    if(nRes != KErrNone)
   1.506 +        return nRes;
   1.507 +
   1.508 +    TRAP(nRes, DoCreateCheckableFileL(file, aSize));
   1.509 +
   1.510 +    file.Close();
   1.511 +    return nRes;
   1.512 +}
   1.513 +
   1.514 +
   1.515 +/**
   1.516 +    Verify previously created file that has MD5 header at the beginning. See  CreateCheckableStuffedFile(...)
   1.517 +
   1.518 +    @param  aFs         reference to the FS session
   1.519 +    @param  aFileName   name of the file to be verified
   1.520 +
   1.521 +    @return Standard error code. KErrNone if the file contents matches the MD5 header.
   1.522 +*/
   1.523 +TInt  F32_Test_Utils::VerifyCheckableFile(RFs& aFs, const TDesC& aFileName)
   1.524 +{
   1.525 +    DoPrintf(_L("~ F32_Test_Utils::VerifyCheckableFile() file:%S\n"), &aFileName);
   1.526 +
   1.527 +    RFile64 file;
   1.528 +
   1.529 +    //-- 1. create a file
   1.530 +    TInt nRes = file.Open(aFs, aFileName, EFileRead);
   1.531 +    if(nRes != KErrNone)
   1.532 +        return nRes;
   1.533 +
   1.534 +    TRAP(nRes, DoVerifyCheckableFileL(file));
   1.535 +
   1.536 +    file.Close();
   1.537 +    return nRes;
   1.538 +
   1.539 +}
   1.540 +
   1.541 +
   1.542 +/**
   1.543 +    Create an empty file (not filled with anything). The size of the file is set by using RFile::SetSize().
   1.544 +    For FAT this will result in allocating a cluster chain in FAT fable, for the file systems that support sparse files (like LFFS)
   1.545 +    this might not work as expected.
   1.546 +
   1.547 +    @param  aFs         reference to the FS session
   1.548 +    @param  aFileName   name of the file to be created / replaced
   1.549 +    @param  aSize       size of the file
   1.550 +
   1.551 +    @return Standard error code
   1.552 +*/
   1.553 +TInt  F32_Test_Utils::CreateEmptyFile(RFs& aFs, const TDesC& aFileName, TUint64 aSize)
   1.554 +{
   1.555 +    DoPrintf(_L("~ F32_Test_Utils::CreateEmptyFile() file:%S, sz:%LU\n"), &aFileName, aSize);
   1.556 +
   1.557 +    RFile64 file;
   1.558 +
   1.559 +    //-- 1. create a file
   1.560 +    TInt nRes = file.Replace(aFs, aFileName, EFileWrite);
   1.561 +    if(nRes != KErrNone)
   1.562 +        return nRes;
   1.563 +
   1.564 +    //-- 2. set file size
   1.565 +    nRes = file.SetSize(aSize);
   1.566 +
   1.567 +    file.Close();
   1.568 +
   1.569 +    return nRes;
   1.570 +}
   1.571 +
   1.572 +//-------------------------------------------------------------------------------------------------------------------
   1.573 +
   1.574 +/**
   1.575 +    Dismount and mount the filesystem again, optionally taking time when the mount starts.
   1.576 +    The FS can have extensions added into it; this function will handle only the primary extension (if it is present) and
   1.577 +    will mont the FS with it. Non-primary extensions are not supported yet.
   1.578 +
   1.579 +
   1.580 +    @param  aFs         reference to the FS session
   1.581 +    @param  aDrive      drive number
   1.582 +    @param  apTimeMountStart pointer to the TTime object, that can be called TTime::UniversalTime() on mount start (this can be
   1.583 +                             used for measuring time taken to mount the FS).
   1.584 +                             if NULL, no action will be taken.
   1.585 +
   1.586 +    @return error code from the RFs::MountFileSystem()
   1.587 +
   1.588 +*/
   1.589 +TInt  F32_Test_Utils::RemountFS(RFs& aFs, TInt aDrive, TTime* apTimeMountStart/*=NULL*/)
   1.590 +{
   1.591 +    TInt nRes;
   1.592 +    DoPrintf(_L("~ F32_Test_Utils::RemountingFS at drive:%d\n"), aDrive);    
   1.593 +
   1.594 +    TFSDescriptor fsDescriptor;
   1.595 +
   1.596 +    //-- 1. get current FS information 
   1.597 +    nRes = GetFileSystemDescriptor(aFs, aDrive, fsDescriptor);
   1.598 +    if(nRes != KErrNone)
   1.599 +        return nRes;
   1.600 +
   1.601 +    //-- 2. dismount the file system
   1.602 +    if(fsDescriptor.iPExtName.Length() > 0)
   1.603 +    {
   1.604 +        DoPrintf(_L("~ Dismounting FS:%S with ext:%S\n"), &fsDescriptor.iFsName, &fsDescriptor.iPExtName);
   1.605 +    }
   1.606 +    else
   1.607 +    {
   1.608 +        DoPrintf(_L("~ Dismounting FS:%S\n"), &fsDescriptor.iFsName);    
   1.609 +    }
   1.610 +
   1.611 +    nRes = aFs.DismountFileSystem(fsDescriptor.iFsName, aDrive);
   1.612 +    if(nRes != KErrNone)
   1.613 +    {
   1.614 +        ASSERT(0);
   1.615 +        return nRes;
   1.616 +    }
   1.617 +
   1.618 +    //-- 3. mount it again
   1.619 +    if(apTimeMountStart)
   1.620 +        apTimeMountStart->UniversalTime(); //-- take Mount start time
   1.621 +
   1.622 +    
   1.623 +    nRes = MountFileSystem(aFs, aDrive, fsDescriptor);
   1.624 +    return nRes;
   1.625 +}
   1.626 +
   1.627 +//-------------------------------------------------------------------------------------------------------------------
   1.628 +
   1.629 +TFSDescriptor::TFSDescriptor()
   1.630 +{
   1.631 +    Init();
   1.632 +}
   1.633 +
   1.634 +void TFSDescriptor::Init()
   1.635 +{
   1.636 +    iFsName.SetLength(0);
   1.637 +    iPExtName.SetLength(0);
   1.638 +    iDriveSynch = EFalse;
   1.639 +}
   1.640 +
   1.641 +TBool TFSDescriptor::operator==(const TFSDescriptor& aRhs) const
   1.642 +{
   1.643 +    ASSERT(this != &aRhs);
   1.644 +    return (iFsName.CompareF(aRhs.iFsName) == 0 && iPExtName.CompareF(aRhs.iPExtName) == 0 && iDriveSynch == aRhs.iDriveSynch);
   1.645 +}
   1.646 +
   1.647 +
   1.648 +//-------------------------------------------------------------------------------------------------------------------
   1.649 +/**
   1.650 +    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
   1.651 +
   1.652 +    @param  aFs         reference to the FS session
   1.653 +    @param  aDrive      drive number
   1.654 +    @param  aFsDesc     file system descriptor
   1.655 +    
   1.656 +    @return standard error code
   1.657 +*/
   1.658 +TInt F32_Test_Utils::GetFileSystemDescriptor(RFs &aFs, TInt aDrive, TFSDescriptor& aFsDesc)
   1.659 +{
   1.660 +    TInt nRes;
   1.661 +
   1.662 +    //-- 1. get file system name
   1.663 +    nRes = aFs.FileSystemName(aFsDesc.iFsName, aDrive);
   1.664 +    if(nRes != KErrNone)
   1.665 +    {
   1.666 +        ASSERT(0);
   1.667 +        return nRes;
   1.668 +    }
   1.669 +    
   1.670 +    //-- 2. find out if the drive sync/async
   1.671 +    TPckgBuf<TBool> drvSyncBuf;
   1.672 +    nRes = aFs.QueryVolumeInfoExt(aDrive, EIsDriveSync, drvSyncBuf);
   1.673 +    if(nRes != KErrNone)
   1.674 +    {//-- pretend that the drive is asynch. in the case of file system being corrupted. this is 99.9% true
   1.675 +       aFsDesc.iDriveSynch = EFalse;
   1.676 +    }
   1.677 +    else
   1.678 +    {
   1.679 +        aFsDesc.iDriveSynch = drvSyncBuf();
   1.680 +    }
   1.681 +
   1.682 +    //-- 3. find out primary extension name if it is present; we will need to add it again when mounting the FS
   1.683 +    //-- other extensions (non-primary) are not supported yet
   1.684 +    nRes = aFs.ExtensionName(aFsDesc.iPExtName, aDrive, 0);
   1.685 +    if(nRes != KErrNone)
   1.686 +    {
   1.687 +        aFsDesc.iPExtName.SetLength(0);
   1.688 +    }
   1.689 +
   1.690 +    //-- 3.1 check if the drive has non-primary extensions, fail in this case
   1.691 +    TBuf<40> extName;
   1.692 +    nRes = aFs.ExtensionName(extName, aDrive, 1);
   1.693 +    if(nRes == KErrNone)
   1.694 +    {   
   1.695 +        DoPrintf(_L("~ F32_Test_Utils::GetFileSystemDescriptor: Non-primary extensions are not supported!\n"));
   1.696 +        return KErrNotSupported;
   1.697 +    }
   1.698 +
   1.699 +
   1.700 +    return KErrNone;
   1.701 +}
   1.702 +
   1.703 +//-------------------------------------------------------------------------------------------------------------------
   1.704 +/**
   1.705 +    Mount the file system by the information provided in the FS descriptor
   1.706 +
   1.707 +    @param  aFs         reference to the FS session
   1.708 +    @param  aDrive      drive number
   1.709 +    @param  aFsDesc     file system descriptor containing all necessary information to mount the FS.
   1.710 +    
   1.711 +    @return standard error code
   1.712 +*/
   1.713 +TInt F32_Test_Utils::MountFileSystem(RFs &aFs, TInt aDrive, const TFSDescriptor& aFsDesc)
   1.714 +{
   1.715 +    DoPrintf(_L("~ F32_Test_Utils::MountFileSystem() drive:%d Name:%S\n"), aDrive, &aFsDesc.iFsName);  
   1.716 +    
   1.717 +    TInt nRes;
   1.718 +    if(aFsDesc.iFsName.Length() <=0 )
   1.719 +    {
   1.720 +        ASSERT(0);
   1.721 +        return KErrArgument;
   1.722 +    }  
   1.723 +
   1.724 +
   1.725 +    //-- mount File system 
   1.726 +    const TBool bPrimaryExt = (aFsDesc.iPExtName.Length() > 0);
   1.727 +
   1.728 +    if(bPrimaryExt)
   1.729 +    {//-- we need to mount FS with the primary extension
   1.730 +        nRes = aFs.AddExtension(aFsDesc.iPExtName);
   1.731 +        if(nRes != KErrNone && nRes != KErrAlreadyExists)
   1.732 +        {
   1.733 +            ASSERT(0);
   1.734 +            return nRes;
   1.735 +        }
   1.736 +        
   1.737 +        nRes = aFs.MountFileSystem(aFsDesc.iFsName, aFsDesc.iPExtName, aDrive, aFsDesc.iDriveSynch);
   1.738 +    }
   1.739 +    else
   1.740 +    {//-- the FS did not have primary extension
   1.741 +        nRes = aFs.MountFileSystem(aFsDesc.iFsName, aDrive, aFsDesc.iDriveSynch);
   1.742 +    }
   1.743 +
   1.744 +
   1.745 +    return nRes;
   1.746 +}
   1.747 +
   1.748 +//-------------------------------------------------------------------------------------------------------------------
   1.749 +/**
   1.750 +    Format volume, regardless the file system installed.
   1.751 +    
   1.752 +    @param  aFs             reference to the FS session
   1.753 +    @param  aDrive          drive number
   1.754 +    @param  aQuickFormat    if True, a quick format will be performed. otherwise - full
   1.755 +    @return system-wide error codes.
   1.756 +*/
   1.757 +TInt F32_Test_Utils::FormatDrive(RFs &aFs, TInt aDrive, TBool aQuickFormat)
   1.758 +{
   1.759 +    TPtrC fmtTypeName = (aQuickFormat ? _L("Quick") : _L("Full"));
   1.760 +    DoPrintf(_L("~ F32_Test_Utils::FormatDrive() drv:%d, type:%S\n"),aDrive, &fmtTypeName);
   1.761 +   
   1.762 +    ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
   1.763 +    
   1.764 +    RFormat format;
   1.765 +    TUint   fmtMode=0;
   1.766 +    TInt    fmtCnt=0;
   1.767 +    TInt    prevCnt;
   1.768 +    TInt    nRes;
   1.769 +
   1.770 +    if(aQuickFormat) 
   1.771 +        fmtMode |= EQuickFormat;
   1.772 +
   1.773 +    //if(aForceErase)
   1.774 +    //    fmtMode |= EForceErase;
   1.775 +
   1.776 +    TBuf<10> drvName;
   1.777 +    drvName.Format(_L("%C:"),'A'+aDrive);
   1.778 +    
   1.779 +    nRes = format.Open(aFs, drvName, fmtMode, fmtCnt);
   1.780 +    if(nRes!=KErrNone)
   1.781 +        goto Fail;
   1.782 +
   1.783 +    //-- do format steps
   1.784 +    prevCnt=fmtCnt;
   1.785 +    while(fmtCnt)
   1.786 +    {
   1.787 +        nRes = format.Next(fmtCnt);
   1.788 +        if(nRes!=KErrNone)
   1.789 +            goto Fail;
   1.790 +
   1.791 +        if(fmtCnt != prevCnt)
   1.792 +        {
   1.793 +            DoPrintf(_L("."));
   1.794 +            prevCnt = fmtCnt;
   1.795 +        }
   1.796 +    }
   1.797 +
   1.798 +    //-- formatting has finished
   1.799 +    DoPrintf(_L("\n"));
   1.800 +    format.Close();
   1.801 +    return KErrNone;
   1.802 +
   1.803 +   Fail:
   1.804 +    format.Close();
   1.805 +    DoPrintf(_L("~ F32_Test_Utils::FormatFatDrive() failed! code:%d\n"), nRes);
   1.806 +
   1.807 +    return nRes;
   1.808 +}
   1.809 +
   1.810 +
   1.811 +#endif //FAT_UTILS_LEAN_AND_MEAN
   1.812 +
   1.813 +
   1.814 +//-------------------------------------------------------------------------------------------------------------------
   1.815 +/**
   1.816 +    printing interface. Prints out to the console (if is set) and to the debug interface
   1.817 +    if pConsole is NULL will print to the debug port only.
   1.818 +*/ 
   1.819 +void F32_Test_Utils::DoPrintf(TRefByValue<const TDesC> aFmt,...)
   1.820 +{
   1.821 +#ifndef FAT_UTILS_LEAN_AND_MEAN
   1.822 +    if(!bPrintOutEnabled) 
   1.823 +        return; //-- disabled by global flag
   1.824 +#endif //FAT_UTILS_LEAN_AND_MEAN
   1.825 +
   1.826 +    VA_LIST list;
   1.827 +    VA_START(list, aFmt);
   1.828 +    
   1.829 +    TBuf<0x100> buf;
   1.830 +    buf.FormatList(aFmt, list); //-- ignore overflows
   1.831 +
   1.832 +#ifndef FAT_UTILS_LEAN_AND_MEAN
   1.833 +    if(pConsole)
   1.834 +    {
   1.835 +        pConsole->Write(buf);
   1.836 +    }
   1.837 +#endif //FAT_UTILS_LEAN_AND_MEAN
   1.838 +    
   1.839 +    const TInt bufLen = buf.Length();
   1.840 +    if(bufLen >0 && buf[bufLen-1] == '\n')
   1.841 +    {
   1.842 +        buf.Insert(bufLen-1, _L("\r"));
   1.843 +    }
   1.844 +
   1.845 +    RDebug::RawPrint(buf);
   1.846 +}
   1.847 +
   1.848 +//-------------------------------------------------------------------------------------------------------------------
   1.849 +
   1.850 +TBool F32_Test_Utils::IsPowerOf2(TUint32 aVal)
   1.851 +    {
   1.852 +    if (aVal==0)
   1.853 +        return EFalse;
   1.854 +
   1.855 +    return !(aVal & (aVal-1));
   1.856 +    }
   1.857 +
   1.858 +
   1.859 +//-------------------------------------------------------------------------------------------------------------------
   1.860 +TUint32 F32_Test_Utils::Log2(TUint32 aVal)
   1.861 +{
   1.862 +    __ASSERT_COMPILE(sizeof(TUint32) == 4);
   1.863 +    ASSERT(aVal);
   1.864 +
   1.865 +    TUint32 bitPos=31;
   1.866 +
   1.867 +    if(!(aVal >> 16)) {bitPos-=16; aVal<<=16;}
   1.868 +    if(!(aVal >> 24)) {bitPos-=8;  aVal<<=8 ;}
   1.869 +    if(!(aVal >> 28)) {bitPos-=4;  aVal<<=4 ;}
   1.870 +    if(!(aVal >> 30)) {bitPos-=2;  aVal<<=2 ;}
   1.871 +    if(!(aVal >> 31)) {bitPos-=1;}
   1.872 +    
   1.873 +    return bitPos;
   1.874 +}
   1.875 +
   1.876 +
   1.877 +//-------------------------------------------------------------------------------------------------------------------
   1.878 +
   1.879 +//###################################################################################################################
   1.880 +//#     TMD5 class implementation 
   1.881 +//###################################################################################################################
   1.882 +
   1.883 +
   1.884 +#define T_MASK ((TUint32)~0)
   1.885 +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
   1.886 +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
   1.887 +#define T3    0x242070db
   1.888 +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
   1.889 +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
   1.890 +#define T6    0x4787c62a
   1.891 +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
   1.892 +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
   1.893 +#define T9    0x698098d8
   1.894 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
   1.895 +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
   1.896 +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
   1.897 +#define T13    0x6b901122
   1.898 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
   1.899 +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
   1.900 +#define T16    0x49b40821
   1.901 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
   1.902 +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
   1.903 +#define T19    0x265e5a51
   1.904 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
   1.905 +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
   1.906 +#define T22    0x02441453
   1.907 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
   1.908 +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
   1.909 +#define T25    0x21e1cde6
   1.910 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
   1.911 +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
   1.912 +#define T28    0x455a14ed
   1.913 +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
   1.914 +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
   1.915 +#define T31    0x676f02d9
   1.916 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
   1.917 +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
   1.918 +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
   1.919 +#define T35    0x6d9d6122
   1.920 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
   1.921 +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
   1.922 +#define T38    0x4bdecfa9
   1.923 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
   1.924 +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
   1.925 +#define T41    0x289b7ec6
   1.926 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
   1.927 +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
   1.928 +#define T44    0x04881d05
   1.929 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
   1.930 +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
   1.931 +#define T47    0x1fa27cf8
   1.932 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
   1.933 +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
   1.934 +#define T50    0x432aff97
   1.935 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
   1.936 +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
   1.937 +#define T53    0x655b59c3
   1.938 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
   1.939 +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
   1.940 +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
   1.941 +#define T57    0x6fa87e4f
   1.942 +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
   1.943 +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
   1.944 +#define T60    0x4e0811a1
   1.945 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
   1.946 +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
   1.947 +#define T63    0x2ad7d2bb
   1.948 +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
   1.949 +
   1.950 +
   1.951 +TMD5::TMD5()
   1.952 +{
   1.953 +    Reset();
   1.954 +}
   1.955 +
   1.956 +//-------------------------------------------------------------------------------------------------------------------
   1.957 +
   1.958 +void TMD5::Md5_process(const TUint8 *data /*[64]*/)
   1.959 +{
   1.960 +    TUint32
   1.961 +    a = iState.abcd[0], b = iState.abcd[1],
   1.962 +    c = iState.abcd[2], d = iState.abcd[3];
   1.963 +    TUint32 t;
   1.964 +    TUint32 xbuf[16];
   1.965 +    const TUint32 *X;
   1.966 +
   1.967 +    {
   1.968 +        static const TInt w = 1;
   1.969 +        if (*((const TUint8 *)&w)) 
   1.970 +        {
   1.971 +            if (!((data - (const TUint8 *)0) & 3)) {
   1.972 +            X = (const TUint32 *)data;
   1.973 +            } else {
   1.974 +            memcpy(xbuf, data, 64);
   1.975 +            X = xbuf;
   1.976 +            }
   1.977 +        }
   1.978 +        else
   1.979 +        {
   1.980 +            const TUint8 *xp = data;
   1.981 +            TInt i;
   1.982 +
   1.983 +            X = xbuf;       /* (dynamic only) */
   1.984 +            for (i = 0; i < 16; ++i, xp += 4)
   1.985 +            xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
   1.986 +        }
   1.987 +    }
   1.988 +
   1.989 +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
   1.990 +
   1.991 +#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
   1.992 +#define SET(a, b, c, d, k, s, Ti)\
   1.993 +  t = a + F(b,c,d) + X[k] + Ti;\
   1.994 +  a = ROTATE_LEFT(t, s) + b
   1.995 +    SET(a, b, c, d,  0,  7,  T1);
   1.996 +    SET(d, a, b, c,  1, 12,  T2);
   1.997 +    SET(c, d, a, b,  2, 17,  T3);
   1.998 +    SET(b, c, d, a,  3, 22,  T4);
   1.999 +    SET(a, b, c, d,  4,  7,  T5);
  1.1000 +    SET(d, a, b, c,  5, 12,  T6);
  1.1001 +    SET(c, d, a, b,  6, 17,  T7);
  1.1002 +    SET(b, c, d, a,  7, 22,  T8);
  1.1003 +    SET(a, b, c, d,  8,  7,  T9);
  1.1004 +    SET(d, a, b, c,  9, 12, T10);
  1.1005 +    SET(c, d, a, b, 10, 17, T11);
  1.1006 +    SET(b, c, d, a, 11, 22, T12);
  1.1007 +    SET(a, b, c, d, 12,  7, T13);
  1.1008 +    SET(d, a, b, c, 13, 12, T14);
  1.1009 +    SET(c, d, a, b, 14, 17, T15);
  1.1010 +    SET(b, c, d, a, 15, 22, T16);
  1.1011 +#undef SET
  1.1012 +
  1.1013 +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
  1.1014 +#define SET(a, b, c, d, k, s, Ti)\
  1.1015 +    t = a + G(b,c,d) + X[k] + Ti;\
  1.1016 +    a = ROTATE_LEFT(t, s) + b
  1.1017 +    SET(a, b, c, d,  1,  5, T17);
  1.1018 +    SET(d, a, b, c,  6,  9, T18);
  1.1019 +    SET(c, d, a, b, 11, 14, T19);
  1.1020 +    SET(b, c, d, a,  0, 20, T20);
  1.1021 +    SET(a, b, c, d,  5,  5, T21);
  1.1022 +    SET(d, a, b, c, 10,  9, T22);
  1.1023 +    SET(c, d, a, b, 15, 14, T23);
  1.1024 +    SET(b, c, d, a,  4, 20, T24);
  1.1025 +    SET(a, b, c, d,  9,  5, T25);
  1.1026 +    SET(d, a, b, c, 14,  9, T26);
  1.1027 +    SET(c, d, a, b,  3, 14, T27);
  1.1028 +    SET(b, c, d, a,  8, 20, T28);
  1.1029 +    SET(a, b, c, d, 13,  5, T29);
  1.1030 +    SET(d, a, b, c,  2,  9, T30);
  1.1031 +    SET(c, d, a, b,  7, 14, T31);
  1.1032 +    SET(b, c, d, a, 12, 20, T32);
  1.1033 +#undef SET
  1.1034 +
  1.1035 +#define H(x, y, z) ((x) ^ (y) ^ (z))
  1.1036 +#define SET(a, b, c, d, k, s, Ti)\
  1.1037 +    t = a + H(b,c,d) + X[k] + Ti;\
  1.1038 +    a = ROTATE_LEFT(t, s) + b
  1.1039 +    SET(a, b, c, d,  5,  4, T33);
  1.1040 +    SET(d, a, b, c,  8, 11, T34);
  1.1041 +    SET(c, d, a, b, 11, 16, T35);
  1.1042 +    SET(b, c, d, a, 14, 23, T36);
  1.1043 +    SET(a, b, c, d,  1,  4, T37);
  1.1044 +    SET(d, a, b, c,  4, 11, T38);
  1.1045 +    SET(c, d, a, b,  7, 16, T39);
  1.1046 +    SET(b, c, d, a, 10, 23, T40);
  1.1047 +    SET(a, b, c, d, 13,  4, T41);
  1.1048 +    SET(d, a, b, c,  0, 11, T42);
  1.1049 +    SET(c, d, a, b,  3, 16, T43);
  1.1050 +    SET(b, c, d, a,  6, 23, T44);
  1.1051 +    SET(a, b, c, d,  9,  4, T45);
  1.1052 +    SET(d, a, b, c, 12, 11, T46);
  1.1053 +    SET(c, d, a, b, 15, 16, T47);
  1.1054 +    SET(b, c, d, a,  2, 23, T48);
  1.1055 +#undef SET
  1.1056 +
  1.1057 +#define I(x, y, z) ((y) ^ ((x) | ~(z)))
  1.1058 +#define SET(a, b, c, d, k, s, Ti)\
  1.1059 +    t = a + I(b,c,d) + X[k] + Ti;\
  1.1060 +    a = ROTATE_LEFT(t, s) + b
  1.1061 +    SET(a, b, c, d,  0,  6, T49);
  1.1062 +    SET(d, a, b, c,  7, 10, T50);
  1.1063 +    SET(c, d, a, b, 14, 15, T51);
  1.1064 +    SET(b, c, d, a,  5, 21, T52);
  1.1065 +    SET(a, b, c, d, 12,  6, T53);
  1.1066 +    SET(d, a, b, c,  3, 10, T54);
  1.1067 +    SET(c, d, a, b, 10, 15, T55);
  1.1068 +    SET(b, c, d, a,  1, 21, T56);
  1.1069 +    SET(a, b, c, d,  8,  6, T57);
  1.1070 +    SET(d, a, b, c, 15, 10, T58);
  1.1071 +    SET(c, d, a, b,  6, 15, T59);
  1.1072 +    SET(b, c, d, a, 13, 21, T60);
  1.1073 +    SET(a, b, c, d,  4,  6, T61);
  1.1074 +    SET(d, a, b, c, 11, 10, T62);
  1.1075 +    SET(c, d, a, b,  2, 15, T63);
  1.1076 +    SET(b, c, d, a,  9, 21, T64);
  1.1077 +#undef SET
  1.1078 +
  1.1079 +    iState.abcd[0] += a;
  1.1080 +    iState.abcd[1] += b;
  1.1081 +    iState.abcd[2] += c;
  1.1082 +    iState.abcd[3] += d;
  1.1083 +
  1.1084 +}
  1.1085 +
  1.1086 +//-------------------------------------------------------------------------------------------------------------------
  1.1087 +void TMD5::Md5_append(const TUint8 *data, TInt nbytes)
  1.1088 +{
  1.1089 +    const TUint8 *p = data;
  1.1090 +    
  1.1091 +    TInt left = nbytes;
  1.1092 +
  1.1093 +    TInt offset = (iState.count[0] >> 3) & 63;
  1.1094 +    TUint32 nbits = (TUint32)(nbytes << 3);
  1.1095 +
  1.1096 +    if (nbytes <= 0)
  1.1097 +    return;
  1.1098 +
  1.1099 +    iState.count[1] += nbytes >> 29;
  1.1100 +    iState.count[0] += nbits;
  1.1101 +    if (iState.count[0] < nbits)
  1.1102 +    iState.count[1]++;
  1.1103 +
  1.1104 +    if (offset) 
  1.1105 +    {
  1.1106 +    TInt copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
  1.1107 +
  1.1108 +    memcpy(iState.buf + offset, p, copy);
  1.1109 +    if (offset + copy < 64)
  1.1110 +        return;
  1.1111 +    p += copy;
  1.1112 +    left -= copy;
  1.1113 +    Md5_process(iState.buf);
  1.1114 +    }
  1.1115 +
  1.1116 +    for (; left >= 64; p += 64, left -= 64)
  1.1117 +        Md5_process(p);
  1.1118 +
  1.1119 +    if (left)
  1.1120 +        memcpy(iState.buf, p, left);
  1.1121 +
  1.1122 +}
  1.1123 +
  1.1124 +
  1.1125 +void TMD5::Md5_finish()
  1.1126 +{
  1.1127 +    static const TUint8 pad[64] = {
  1.1128 +    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1.1129 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1.1130 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1.1131 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  1.1132 +    };
  1.1133 +    TUint8 data[8];
  1.1134 +    TInt i;
  1.1135 +
  1.1136 +    for (i = 0; i < 8; ++i)
  1.1137 +    data[i] = (TUint8)(iState.count[i >> 2] >> ((i & 3) << 3));
  1.1138 +    Md5_append(pad, ((55 - (iState.count[0] >> 3)) & 63) + 1);
  1.1139 +    Md5_append(data, 8);
  1.1140 +    for (i = 0; i < 16; ++i)
  1.1141 +        iDigest[i] = (TUint8)(iState.abcd[i >> 2] >> ((i & 3) << 3));
  1.1142 +
  1.1143 +}
  1.1144 +
  1.1145 +//-------------------------------------------------------------------------------------------------------------------
  1.1146 +
  1.1147 +/** reset MD5 to initial state */
  1.1148 +void TMD5::Reset()
  1.1149 +{
  1.1150 +    iState.count[0] = iState.count[1] = 0;
  1.1151 +    iState.abcd[0] = 0x67452301;
  1.1152 +    iState.abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
  1.1153 +    iState.abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
  1.1154 +    iState.abcd[3] = 0x10325476;
  1.1155 +}
  1.1156 +
  1.1157 +
  1.1158 +/**
  1.1159 +    Update MD5 with some data
  1.1160 +    @param aMessage descriptor with data
  1.1161 +*/
  1.1162 +void TMD5::Update(const TDesC8& aMessage)
  1.1163 +{
  1.1164 +    Md5_append((const TUint8*)aMessage.Ptr(), aMessage.Length());
  1.1165 +}
  1.1166 +
  1.1167 +/**
  1.1168 +    Finalise MD5 calculation
  1.1169 +    @param  aMessage descriptor with data
  1.1170 +    @return pointer to 16-byte array with MD5 hash
  1.1171 +*/
  1.1172 +TPtrC8 TMD5::Final(const TDesC8& aMessage)
  1.1173 +{
  1.1174 +    Update(aMessage);
  1.1175 +    Md5_finish();
  1.1176 +    return TPtrC8(iDigest, HashSize);
  1.1177 +}
  1.1178 +
  1.1179 +
  1.1180 +/**
  1.1181 +    Finalise MD5 calculation
  1.1182 +    @return pointer to 16-byte array with MD5 hash
  1.1183 +*/
  1.1184 +TPtrC8 TMD5::Final()
  1.1185 +{
  1.1186 +    Md5_finish();
  1.1187 +    return TPtrC8(iDigest, HashSize);
  1.1188 +}
  1.1189 +
  1.1190 +
  1.1191 +
  1.1192 +
  1.1193 +
  1.1194 +
  1.1195 +
  1.1196 +
  1.1197 +
  1.1198 +
  1.1199 +
  1.1200 +
  1.1201 +
  1.1202 +
  1.1203 +
  1.1204 +
  1.1205 +
  1.1206 +
  1.1207 +
  1.1208 +
  1.1209 +
  1.1210 +