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