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 +