diff -r 000000000000 -r a41df078684a kerneltest/e32test/demandpaging/t_tbus_datapaging.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/demandpaging/t_tbus_datapaging.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,822 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\demandpaging\t_tbus_datapaging.cpp +// Functional tests for data paging. +// 002 ??? +// 003 ??? +// + +//! @SYMTestCaseID KBASE-T_TBUS_DATAPAGING +//! @SYMTestType UT +//! @SYMPREQ ??? +//! @SYMTestCaseDesc Data Paging functional tests with TBusLocalDrive. +//! @SYMTestActions 001 ??? +//! @SYMTestExpectedResults All tests should pass. +//! @SYMTestPriority High +//! @SYMTestStatus Implementation on-going + +#define __E32TEST_EXTENSION__ +#include +#include +#include +#include +#include +#include +#include "u32std.h" + +#include +#include +#include + +#include "t_dpcmn.h" +#include "../secure/d_sldd.h" +#include "../mmu/mmudetect.h" + +const TInt KMaxLengthOfStoreMapping = 16 + sizeof(TInt32) + KMaxMediaPassword; +const TInt KMaxPersistentStore(TPasswordStore::EMaxPasswordLength+KMaxLengthOfStoreMapping); +typedef TBuf8 TPersistentStore; + +RChunk gMyChunk; +TUint gOffset = 0; +TUint8* gData = NULL; +const TUint8 KClearValue = 0xed; +const TUint KChunkSizeInPages = 64; // 64 * 4096 = 256K +const TInt KTestBufLen=256; + + +#define __DECLARE_VAR_IN_CHUNK(type, varRef) \ + type varRef = *(type*) (gData+gOffset); \ + gOffset += Max(gPageSize, sizeof(type)); \ + test(gOffset <= gPageSize * KChunkSizeInPages); + +#define __DECLARE_AND_INIT_VAR_IN_CHUNK(type, var) \ + type &var = *(type*) (gData+gOffset); \ + var = type(); \ + gOffset += Max(gPageSize, sizeof(type)); \ + test(gOffset <= gPageSize * KChunkSizeInPages); + + +#define __DECLARE_ARRAY_IN_CHUNK(type, var, size) \ + type *var = (type*) (gData+gOffset); \ + gOffset += Max(gPageSize, (sizeof(type) * size)); \ + test(gOffset <= gPageSize * KChunkSizeInPages); + +#define __FLUSH_AND_CALL_API_METHOD(return, function) \ + DPTest::FlushCache(); \ + return = function; + + +LOCAL_D RFs TheFs; +TInt gFsDriveNumber = -1; + +RTest test(_L("T_TBUS_DATAPAGING")); +_LIT(KChunkName, "t_datapaging chunk"); + +const TUint KDriveAttMask = KDriveAttLocal | KDriveAttRom | KDriveAttInternal | KDriveAttRemovable | KDriveAttRemote; +const TUint KMediaAttMask = KMediaAttVariableSize | KMediaAttDualDensity | KMediaAttLockable | KMediaAttLocked | KMediaAttHasPassword | KMediaAttReadWhileWrite; + +void CreatePagedChunk(TInt aSizeInPages, TInt aWipeByte = -1) + { + test_Equal(0,gMyChunk.Handle()); + + TChunkCreateInfo createInfo; + TInt size = aSizeInPages * gPageSize; + createInfo.SetNormal(size, size); + createInfo.SetPaging(TChunkCreateInfo::EPaged); + createInfo.SetOwner(EOwnerProcess); + createInfo.SetGlobal(KChunkName); + if (aWipeByte != -1) + createInfo.SetClearByte(aWipeByte); + test_KErrNone(gMyChunk.Create(createInfo)); + test(gMyChunk.IsPaged()); // this is only ever called if data paging is supported + + gData = gMyChunk.Base(); + } + +TInt TestDriveConnectAndCaps(TBusLocalDrive &aDrive, TInt &aLocalDriveNumber) + { + + test.Next(_L("Test Drive Connect And Caps")); + + __DECLARE_VAR_IN_CHUNK(TInt, &r); + + test.Printf(_L("changeFlag...\n")); + __DECLARE_VAR_IN_CHUNK(TBool, &changeFlag); + changeFlag = EFalse; + + test.Printf(_L("call aDrive.Connect()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Connect(aLocalDriveNumber,changeFlag)); + + test.Printf(_L("r:%d\n"),r); + test_Equal(KErrNone, r); + + test.Printf(_L("call aDrive.Caps()...\n")); + __DECLARE_VAR_IN_CHUNK(TLocalDriveCapsV5, &driveCaps); + + TPckg capsPckg(driveCaps); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Caps(capsPckg)); + + test_Equal(KErrNone, r); + test.Printf(_L("r:%d\n"),r); + test.Printf(_L("driveCaps.iDriveAtt :0x%08x\n"), driveCaps.iDriveAtt); + test.Printf(_L("driveCaps.iSize :%ld\n"), driveCaps.iSize); + test.Printf(_L("driveCaps.iSerialNumLength :%d\n"), driveCaps.iSerialNumLength); + + return I64LOW(driveCaps.iSize); + } + +void TestDriveSizeRelatedMethods(TBusLocalDrive &aDrive, TInt aNewSize, TInt aOldSize) + { + TInt r; + + test.Next(_L("Test Drive Size Related Methods")); + test.Printf(_L("newDriveSize...\n")); + __DECLARE_VAR_IN_CHUNK(TInt, &newDriveSize); + newDriveSize = aNewSize; + + test.Printf(_L("call aDrive.Enlarge()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Enlarge(newDriveSize)); + test.Printf(_L("r:%d\n"),r); + test((KErrNone == r) || (KErrNotSupported == r) || (KErrNotReady == r)); + if(r != KErrNone ) + { + test.Printf(_L("errInfo...\n")); + __DECLARE_ARRAY_IN_CHUNK(TUint8, errInfo, KTestBufLen); + + TPtr8 pErrInfoBuff(errInfo, KTestBufLen); + + __FLUSH_AND_CALL_API_METHOD(r, aDrive.GetLastErrorInfo(pErrInfoBuff)); + test.Printf(_L("r:%d\n"),r); + test((KErrNone == r) || (KErrNotSupported == r)); + } + + + test.Printf(_L("call aDrive.ReduceSize()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.ReduceSize(0, aOldSize)); + test((KErrNone == r) || (KErrNotSupported == r) || (KErrNotReady == r)); + + } + +void TestWriteReadRelatedMethods(TBusLocalDrive &aDrive) + { + + test.Next(_L("Test Write & Read Related Methods")); + + __DECLARE_VAR_IN_CHUNK(TInt, &r); + + test.Printf(_L("msgHandle...\n")); + __DECLARE_VAR_IN_CHUNK(TInt, &msgHandle); + msgHandle = KLocalMessageHandle; + + + __DECLARE_VAR_IN_CHUNK(TUint, &i); + test.Printf(_L("wrBuf...\n")); + TBuf8 wrBuf(KTestBufLen); + for (i=0 ; i<(TUint)KTestBufLen ; i++) + wrBuf[i]=(TUint8)i; + + + test.Printf(_L("wrBuf2...\n")); + __DECLARE_ARRAY_IN_CHUNK(TUint8, wrBuf2, KTestBufLen); + + test.Printf(_L("fill wrBuf2...\n")); + for (i=0 ; i<(TUint)KTestBufLen ; i++) + wrBuf2[i]=(TUint8)i; + + TPtr8 pWrBuf2(wrBuf2, KTestBufLen, KTestBufLen); + + test.Printf(_L("rdBuf...\n")); + TBuf8 rdBuf(KTestBufLen); + + + test.Printf(_L("rdBuf2...\n")); + __DECLARE_ARRAY_IN_CHUNK(TUint8, rdBuf2, KTestBufLen); + + TPtr8 pRdBuf2(rdBuf2, KTestBufLen); + + test.Printf(_L("call aDrive.Write()...\n")); + rdBuf.Fill(0,KTestBufLen); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Write(0,KTestBufLen,&wrBuf,msgHandle,0)); + test_Equal(KErrNone, r); + + + test.Printf(_L("call aDrive.Read()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Read(0,KTestBufLen,&rdBuf,msgHandle,0)); + test_Equal(KErrNone, r); + + for (i=0 ; i<(TUint)KTestBufLen ; i++) + test_Equal(wrBuf[i], rdBuf[i]); + + test.Printf(_L("call aDrive.Write()...\n")); + pRdBuf2.Fill(0,KTestBufLen); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Write(0,pWrBuf2)); + test_Equal(KErrNone, r); + + + test.Printf(_L("call aDrive.Read()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Read(0,KTestBufLen, pRdBuf2)); + test_Equal(KErrNone, r); + + for (i=0 ; i<(TUint)KTestBufLen ; i++) + test_Equal(wrBuf2[i], rdBuf2[i]); + + } + +void TestPasswordRelatedMethods(TBusLocalDrive &aDrive) + { + TInt r; + + test.Next(_L("Test Password Related Methods")); + //__DECLARE_VAR_IN_CHUNK(TPersistentStore, &wStore); + + TPersistentStore* pstoreAB; + test((pstoreAB = new TPersistentStore) != 0); + TPersistentStore& wStore = *pstoreAB; + + //__DECLARE_AND_INIT_VAR_IN_CHUNK(TPersistentStore, wStore); + + // Password related API methods call + test.Printf(_L("call aDrive.WritePasswordData() to clear passwords...\n")); + __DECLARE_VAR_IN_CHUNK(TInt, &passwordStoreLength); + + TBuf8<1> nulSt; + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(nulSt)); + test( r == KErrNone);// empty + + test.Printf(_L("call aDrive.PasswordStoreLengthInBytes()...\n")); + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test_Equal(0, passwordStoreLength); + + + test.Printf(_L("call aDrive.ErasePassword()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.ErasePassword()); + test.Printf(_L("r:%d\n"),r); + + + test.Printf(_L("wStore.Size():%d\n"),wStore.Size()); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(wStore)); + + test.Printf(_L("r:%d\n"),r); + test((KErrNone == r)); // || (KErrCorrupt == r)); // TO-DO Why Corrupt??? + + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test((r == KErrNone ? (wStore.Size() == passwordStoreLength) : (0 == passwordStoreLength) )); + + + + test.Printf(_L("Set and store a password...\n")); + TDes8 &st = wStore; + TMediaPassword a((const TUint8*) "CID0ccccccccccc#"); + TUint8 passLen[sizeof(TInt32)]; + passLen[0] = 0; + passLen[1] = 0; + passLen[2] = 0; + passLen[3] = 16; + + //test.Printf(_L("Password3:'%S'\n"), &a); + + st.Append(a); + st.Append(passLen, sizeof(TInt32)); + st.Append(a); + + test.Printf(_L("wStore.Size():%d\n"),wStore.Size()); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(wStore)); + + test.Printf(_L("r:%d\n"),r); + test((KErrNone == r)); + + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test((r == KErrNone ? (wStore.Size() == passwordStoreLength) : (0 == passwordStoreLength) )); + + test.Printf(_L("call aDrive.ErasePassword()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.ErasePassword()); + test.Printf(_L("r:%d\n"),r); + + test.Printf(_L("call aDrive.WritePasswordData() to set password again...\n")); + test.Printf(_L("wStore.Size():%d\n"),wStore.Size()); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(wStore)); + + test.Printf(_L("r:%d\n"),r); + test((KErrNone == r)); + + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test((r == KErrNone ? (wStore.Size() == passwordStoreLength) : (0 == passwordStoreLength) )); + + + // Finally erase password + test.Printf(_L("call aDrive.WritePasswordData() to erase password...\n")); + wStore.Zero(); // empty password store + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(wStore)) + test( r == KErrNone);// Clear + + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test((r == KErrNone ? (wStore.Size() == passwordStoreLength) : (0 == passwordStoreLength) )); + + + + // Test SetPassword + TMediaPassword nul(nulSt); + + test.Printf(_L("call aDrive.SetPassword()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.SetPassword(nul, a, EFalse)); + test.Printf(_L("r:%d\n"),r); + test_Equal(KErrNone, r); + + // Erase Password + test.Printf(_L("call aDrive.ErasePassword()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.ErasePassword()); + test.Printf(_L("r:%d\n"),r); + + + test.Printf(_L("call aDrive.SetPassword()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.SetPassword(nul, a, EFalse)); + test.Printf(_L("r:%d\n"),r); + test_Equal(KErrNone, r); + + // Erase Clear + test.Printf(_L("call aDrive.Clear()...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.Clear(a)); + test.Printf(_L("r:%d\n"),r); + + + test.Printf(_L("call aDrive.SetPassword() to clear again...\n")); + __FLUSH_AND_CALL_API_METHOD(r, aDrive.SetPassword(a, nul, EFalse)); + test.Printf(_L("r:%d\n"),r); + test_Equal(KErrAccessDenied, r); + + + // Finally erase password + test.Printf(_L("call aDrive.WritePasswordData() to erase password...\n")); + wStore.Zero(); // empty password store + __FLUSH_AND_CALL_API_METHOD(r, aDrive.WritePasswordData(wStore)) + test( r == KErrNone);// Clear + + __FLUSH_AND_CALL_API_METHOD(passwordStoreLength, aDrive.PasswordStoreLengthInBytes()); + + test.Printf(_L("passwordStoreLength:%d\n"), passwordStoreLength); + test((r == KErrNone ? (wStore.Size() == passwordStoreLength) : (0 == passwordStoreLength) )); + + } + +void TestFormatRelatedMethods(TBusLocalDrive &aDrive, TInt aSize ) + { + test.Next(_L("Test Format Related Methods")); + + test.Printf(_L("call aDrive.Format(TFormatInfo)...\n")); + __DECLARE_AND_INIT_VAR_IN_CHUNK(TFormatInfo, fi); + __DECLARE_VAR_IN_CHUNK(TInt, &ret); + __DECLARE_VAR_IN_CHUNK(TInt, &attempt); + + __FLUSH_AND_CALL_API_METHOD(ret, aDrive.Format(fi)); + test.Printf(_L("ret:%d\n"),ret); + while(ret!=KErrEof) + { + if( ret == KErrNotReady ) + { + attempt = 100; + while( (ret= aDrive.Format(fi)) == KErrNotReady && --attempt) + { + test.Printf(_L("attempt:%d\n"),attempt); + User::After(1000000); + } + test(attempt); + } + else + { + test(ret==KErrNone); + ret= aDrive.Format(fi); + } + } + + + test.Printf(_L("call aDrive.Format(pos, length)...\n")); + User::After(1000000); + + __DECLARE_VAR_IN_CHUNK(TInt64, &pos); + pos = 0; + __DECLARE_VAR_IN_CHUNK(TInt, &length); + length = aSize; + + attempt = 100; + __FLUSH_AND_CALL_API_METHOD(ret, aDrive.Format(pos, length)); + while( ret == KErrNotReady && --attempt) + { + User::After(1000000); + ret= aDrive.Format(pos, length); + } + test(attempt); + test_Equal(KErrNone, ret); + + test.Printf(_L("End of TestFormatRelatedMethods)...\n")); + } + +void RestoreDriveState(void) + { + TBuf<3> bfDrv; + + const TText KDrvLtr = 'A' + gFsDriveNumber; + + bfDrv.Append(KDrvLtr); + _LIT(KBP, ":\\"); + bfDrv.Append(KBP); + + + TheFs.Connect(); + RFormat fmt; + TInt count; + + test(fmt.Open(TheFs, bfDrv, EHighDensity, count) == KErrNone); + while (count > 0) + { + test.Printf(_L("\rfmt:%d "), count); + test(fmt.Next(count) == KErrNone); + } + test.Printf(_L("\n")); + fmt.Close(); + + TheFs.Close(); + } + + +TInt FindDataPagingDrive() +/** +Find the drive containing a swap partition. + +@return Local drive identifier. +*/ + { + TInt drive = KErrNotFound; + + test.Printf(_L("Searching for data paging drive:\n")); + + for(TInt i = 0; i < KMaxLocalDrives && drive < 0; ++i) + { + RLocalDrive d; + TBool change = EFalse; + + if(d.Connect(i, change) == KErrNone) + { + TLocalDriveCapsV4 dc; + TPckg capsPack(dc); + + if(d.Caps(capsPack) == KErrNone) + { + if ((dc.iMediaAtt & KMediaAttPageable) && + (dc.iPartitionType == KPartitionTypePagedData)) + { + test.Printf(_L("Found swap partition on local drive %d\n"), i); + drive = i; + + TPageDeviceInfo pageDeviceInfo; + + TPtr8 pageDeviceInfoBuf((TUint8*) &pageDeviceInfo, sizeof(pageDeviceInfo)); + pageDeviceInfoBuf.FillZ(); + + TInt r = d.QueryDevice(RLocalDrive::EQueryPageDeviceInfo, pageDeviceInfoBuf); + + test.Printf(_L("EQueryPageDeviceInfo on local drive %d returned %d\n"), i, r); + } + } + d.Close(); + } + } + return drive; + } + +TDes& GetSerialNumber(TLocalDriveCapsV5& aCaps) + { + static TBuf16<80> serialNumBuf; + + serialNumBuf.SetLength(0); + + for (TUint n=0; n hexBuf; + hexBuf.Format(_L("%02X "), aCaps.iSerialNum[m]); + serialNumBuf.Append(hexBuf); + } + } + + return serialNumBuf; + } + +TDes& GetSerialNumber(TMediaSerialNumber& aSerialNum) + { + static TBuf16<80> serialNumBuf; + + serialNumBuf.SetLength(0); + + TInt len = aSerialNum.Length(); + for (TInt n=0; n hexBuf; + hexBuf.Format(_L("%02X "), aSerialNum[m]); + serialNumBuf.Append(hexBuf); + } + } + + return serialNumBuf; + } + +TPtrC GetMediaType(TMediaType aType) + { + switch(aType) + { + case EMediaNotPresent: return _L("NotPresent"); + case EMediaUnknown: return _L("Unknown"); + case EMediaFloppy: return _L("Floppy"); + case EMediaHardDisk: return _L("HardDisk"); + case EMediaCdRom: return _L("CdRom"); + case EMediaRam: return _L("Ram"); + case EMediaFlash: return _L("Flash"); + case EMediaRom: return _L("Rom"); + case EMediaRemote: return _L("Remote"); + case EMediaNANDFlash: return _L("NANDFlash"); + case EMediaRotatingMedia : return _L("RotatingMedia "); + default:return _L("Unrecognised"); + } + } + +TPtrC GetFileSystemId(TUint aFileSystemId) + { + switch(aFileSystemId) + { + case KDriveFileSysFAT: return _L("FAT"); + case KDriveFileSysROM: return _L("ROM"); + case KDriveFileSysLFFS: return _L("LFFS"); + case KDriveFileSysROFS: return _L("ROFS"); + case KDriveFileNone: return _L("None"); + default:return _L("Unrecognised"); + } + } + + + +// Find a drive which contains the swap partition; if this succeeds, find and return the FAT drive on the same media. +// This isn't fool-proof as it works by comparing media types/drive attributes/media attributes/serial numbers +TInt FindFatDriveOnDataPagingMedia() + { + TInt dataPagingDrive = FindDataPagingDrive(); + if (dataPagingDrive == KErrNotFound) + return KErrNotFound; + + TInt fatDriveNumber = KErrNotFound; + + test.Printf(_L("Finding Fat drive on datapaging media...\n")); + + RLocalDrive dpDrive; + TBool change = EFalse; + + TInt r = dpDrive.Connect(dataPagingDrive, change); + test(r == KErrNone); + TLocalDriveCapsV5 dpDriveCaps; + TPckg capsPack(dpDriveCaps); + r = dpDrive.Caps(capsPack); + test(r == KErrNone); + TPtrC8 dpDriveSerialNum(dpDriveCaps.iSerialNum, dpDriveCaps.iSerialNumLength); + dpDrive.Close(); + + TPtrC mediaType = GetMediaType(dpDriveCaps.iType); + TPtrC fileSystemId = GetFileSystemId(dpDriveCaps.iFileSystemId); + test.Printf(_L("Swap Drive %2d Type %S DriveAtt 0x%x MediaAtt 0x%x FileSysId %S SerialNum %S\n"), + dataPagingDrive, &mediaType, dpDriveCaps.iDriveAtt, dpDriveCaps.iMediaAtt, &fileSystemId, &GetSerialNumber(dpDriveCaps)); + + // swap partition should be hidden + test (dpDriveCaps.iDriveAtt & KDriveAttHidden); + + // search for a FAT drive on the same media by searching for a drive which has + // 'similar' drive & media attributes as the the swap drive + + dpDriveCaps.iDriveAtt&= KDriveAttMask; + dpDriveCaps.iMediaAtt&= KMediaAttMask; + + for (TInt i = 0; i < KMaxLocalDrives /*&& fatDriveNumber == KErrNotFound*/; ++i) + { + RLocalDrive d; + TBool change = EFalse; + + if(d.Connect(i, change) == KErrNone) + { + TLocalDriveCapsV5 caps; + TPckg capsPack(caps); + + r = d.Caps(capsPack); + if (r != KErrNone) + continue; + + TPtrC8 localSerialNum(caps.iSerialNum, caps.iSerialNumLength); + TPtrC mediaType = GetMediaType(caps.iType); + TPtrC fileSystemId = GetFileSystemId(caps.iFileSystemId); + test.Printf(_L("Drive %2d Type %S DriveAtt 0x%x MediaAtt 0x%x FileSysId %S SerialNum %S\n"), + i, &mediaType, caps.iDriveAtt, caps.iMediaAtt, &fileSystemId, &GetSerialNumber(caps)); + + // Turn off bits which may be different + caps.iDriveAtt&= KDriveAttMask; + caps.iMediaAtt&= KMediaAttMask; + + if ((caps.iType == dpDriveCaps.iType) && + (caps.iDriveAtt == dpDriveCaps.iDriveAtt) && + (caps.iMediaAtt == dpDriveCaps.iMediaAtt) && + (localSerialNum.Compare(dpDriveSerialNum) == 0) && + (caps.iFileSystemId == KDriveFileSysFAT)) + { + if (fatDriveNumber == KErrNotFound) + fatDriveNumber = i; + } + d.Close(); + } + } + + + return fatDriveNumber; + } + + +// Find and return the File Server drive number (0-25) corresponing to the passed local drive number +// This isn't fool-proof as it works by comparing media types/drive attributes/media attributes/serial numbers +TInt FindFsDriveNumber(TInt aLocalDriveNumber) + { + TInt fsDriveNumber = KErrNotFound; + + RLocalDrive dpDrive; + TBool change = EFalse; + + TInt r = dpDrive.Connect(aLocalDriveNumber, change); + test(r == KErrNone); + TLocalDriveCapsV5 dpDriveCaps; + TPckg capsPack(dpDriveCaps); + r = dpDrive.Caps(capsPack); + test(r == KErrNone); + TPtrC8 dpDriveSerialNum(dpDriveCaps.iSerialNum, dpDriveCaps.iSerialNumLength); + dpDrive.Close(); + + dpDriveCaps.iDriveAtt&= KDriveAttMask; + dpDriveCaps.iMediaAtt&= KMediaAttMask; + + RFs fs; + r = fs.Connect(); + test(r == KErrNone); + + TDriveInfo di; + + for (TInt n=0; n cmdline; + User::CommandLine(cmdline); + TLex lex(cmdline); + + FOREVER + { + TPtrC token=lex.NextToken(); + if(token.Length() != 0) + { + if (token == _L("-p")) + { + callPasswordRelated = ETrue; + } + else + test.Printf(_L("Unknown argument '%S' was ignored.\n"), &token); + } + else + break; + + } + + test.Title(); + TInt r; + + test.Start(_L("Verify the global and this process's data paging attributes")); + test_KErrNone(GetGlobalPolicies()); + + if (IsDataPagingSupported()) + { + test.Printf(_L("Data paging supported\n")); + } + else + {// The system doesn't support data paging so this process shouldn't be + // data paged. + test.Printf(_L("Data paging not supported\n")); + test_Equal(EFalse, gProcessPaged); + test.End(); + return 0; + } + + r = UserHal::PageSizeInBytes(gPageSize); + test_KErrNone(r); + + TInt fatDriveNumber = FindFatDriveOnDataPagingMedia(); + if (fatDriveNumber == KErrNotFound) + { + test.Printf(_L("Could not find FAT partition on data paging media\n")); + test(0); + } + gFsDriveNumber = FindFsDriveNumber(fatDriveNumber); + if (gFsDriveNumber == KErrNotFound) + { + test.Printf(_L("Could not File Server drive\n")); + test(0); + } + + test.Printf(_L("Found FAT drive on %C: (local drive #%d) on data paging media\n"), 'A'+gFsDriveNumber, fatDriveNumber); + +// User::SetDebugMask(0x10000000); //KMMU2 +// User::SetDebugMask(0x40000000, 1); //KPAGING + + test.Next(_L("Create a paged chunk")); + CreatePagedChunk(KChunkSizeInPages, KClearValue); + + test.Next(_L("Chunk created, declare variables")); + + __DECLARE_VAR_IN_CHUNK(TBusLocalDrive, &drive) + TInt driveSize = TestDriveConnectAndCaps(drive, fatDriveNumber); + + TestDriveSizeRelatedMethods(drive, 0x00001000, driveSize); + + TestWriteReadRelatedMethods(drive); + + TestFormatRelatedMethods(drive, driveSize); + + if(callPasswordRelated) + { + TestPasswordRelatedMethods(drive); + } + + //Disconnect drive + test.Next(_L("call aDrive.Disconnect()...")); + DPTest::FlushCache(); + drive.Disconnect(); + + gMyChunk.Close(); + + RestoreDriveState(); + + test.End(); + + User::SetDebugMask(0x00000000); // No debug info + User::SetDebugMask(0x00000000, 1); //No KPAGING + return 0; + }