--- /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 <e32test.h>
+#include <dptest.h>
+#include <e32hal.h>
+#include <u32exec.h>
+#include <e32svr.h>
+#include <e32panic.h>
+#include "u32std.h"
+
+#include <f32file.h>
+#include <f32dbg.h>
+#include <f32fsys.h>
+
+#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<KMaxPersistentStore> 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<TLocalDriveCapsV5> 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<KTestBufLen> 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<KTestBufLen> 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<TLocalDriveCapsV4> 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<aCaps.iSerialNumLength; n+=16)
+ {
+ for (TUint m=n; m<n+16; m++)
+ {
+ TBuf16<3> 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<len; n+=16)
+ {
+ for (TInt m=n; m<n+16; m++)
+ {
+ TBuf16<3> 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<TLocalDriveCapsV5> 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<TLocalDriveCapsV5> 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<TLocalDriveCapsV5> 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<KMaxDrives /* && fsDriveNumber == KErrNotFound*/; n++)
+ {
+ r = fs.Drive(di, n);
+
+ TMediaSerialNumber serialNum;
+ fs.GetMediaSerialNumber(serialNum, n);
+
+ TFSName fsName;
+ fs.FileSystemName(fsName, n);
+
+ if (r != KErrNone )
+ continue;
+
+ TPtrC mediaType = GetMediaType(di.iType);
+ test.Printf(_L("Drive %C Type %S DriveAtt 0x%x MediaAtt 0x%x FileSysId %S SerialNum %S\n"),
+ 'A' + n, &mediaType, di.iDriveAtt, di.iMediaAtt, &fsName, &GetSerialNumber(serialNum));
+
+ di.iDriveAtt&= KDriveAttMask;
+ di.iMediaAtt&= KMediaAttMask;
+
+ if ((di.iType == dpDriveCaps.iType) &&
+ (di.iDriveAtt == dpDriveCaps.iDriveAtt) &&
+ (di.iMediaAtt == dpDriveCaps.iMediaAtt) &&
+ (serialNum.Compare(dpDriveSerialNum) == 0))
+ {
+ if (fsDriveNumber == KErrNotFound)
+ fsDriveNumber = n;
+ }
+ }
+
+ fs.Close();
+
+ return fsDriveNumber;
+ }
+
+TInt E32Main()
+ {
+
+ // To use in command line
+ TBool callPasswordRelated = EFalse;
+
+ TBuf<256> 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;
+ }