diff -r 000000000000 -r 96e5fb8b040d kerneltest/f32test/demandpaging/t_clamp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/demandpaging/t_clamp.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,985 @@ +// Copyright (c) 2006-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: +// f32test\demandpaging\t_clamp.cpp +// Test suite for file clamping, file clamping is used to prevent files +// (exes or dlls) from being deleted whilst in use. +// 002 GetDriveLetters() +// 003 Test1() Basic clamp operation +// 004 Test2() Invalid clamp requests +// 005 Test3() Denied FS requests when file(s) are clamped +// 006 Test3Operations() Test other RFile, RFs operations +// 007 Test3Operations() Increase number of clamps to MY_N +// 008 Test3Operations() Decrease number of clamps by MY_M +// 009 Test3Operations() Increase number of clamps by MY_M +// 010 TestDeferredDismount() Open and clamp file, register for dismount +// notification, then issue dismount instruction. +// 011 Test4() Clamp tests for non-writable file system +// 012 Test5() Clamp requests on non-clamping file systems +// +// + +//! @SYMTestCaseID KBASE-T_CLAMP-0328 +//! @SYMTestType UT +//! @SYMPREQ PREQ1110 +//! @SYMTestCaseDesc Demand Paging File Clamp tests +//! @SYMTestActions 001 Starting T_CLAMP +//! @SYMTestExpectedResults All tests should pass. +//! @SYMTestPriority High +//! @SYMTestStatus Implemented + +#define __E32TEST_EXTENSION__ + +#include +RTest test(_L("T_CLAMP")); + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + +#include +#include +RFs TheFs; + +_LIT(KFATName,"FAT"); +//_LIT(KFAT32Name,"FAT32"); +_LIT(KROFSName,"ROFS"); +_LIT(KLFFSName,"LFFS"); +_LIT(KCOMPName,"COMPOSITE"); // Z: name if Composite File System +//#ifdef __WINS__ +//_LIT(KROMName,"WIN32"); // Clamping is not supported for non-composite filing system on Z: +//#else +_LIT(KROMName,"ROM"); // Z: name if ROMFS (on hardware, not emulator) +//#endif + +TChar NandFatDrv='?'; +TChar RofsDrv='?'; +TChar LffsDrv='?'; +TChar CompDrv='?'; + + +LOCAL_C void Test1() + { +// Basic clamp operation + test.Next(_L("T_Clamp - Test1()")); + + TBuf<256> fileName; + TBuf<256> buf(_L("buffer for file used")); + + fileName = _L("clampFile.tst"); + RFile testFile; + TInt r=testFile.Replace(TheFs,fileName,EFileWrite); + test(r==KErrNone); + TPtrC8 pBuf((TUint8*)&buf); + testFile.Write(pBuf); + testFile.Flush(); + + // Clamp file + RFileClamp handle; + r=handle.Clamp(testFile); + test(r==KErrNone); + TInt64 storedCookie_0=handle.iCookie[0]; + TInt64 storedCookie_1=handle.iCookie[1]; + + // Try to clamp previously-clamped file + RFileClamp handle1; + r=handle1.Clamp(testFile); + test(r==KErrNone); + + // Unclamp file + r=handle.Close(TheFs); + test (r==KErrNone); + // Check cookie content has been re-initialised + test((0==handle.iCookie[0])&&(0==handle.iCookie[1])); + + // Try to unclamp a file that is not clamped + handle.iCookie[0]=storedCookie_0; + handle.iCookie[1]=storedCookie_1; + r=handle.Close(TheFs); + test (r==KErrNotFound); + + // Check that attempting to unclamp with a zero-content cookie + // yields no error + handle.iCookie[0]=0; + handle.iCookie[1]=0; + r=handle.Close(TheFs); + test (r==KErrNone); + + // Clamp the file (again) + r=handle.Clamp(testFile); + test(r==KErrNone); + + // Create and clamp a second file ... + fileName = _L("clampFile2.tst"); + RFile testFile2; + r=testFile2.Replace(TheFs,fileName,EFileWrite); + test(r==KErrNone); + buf=_L("buffer for file 2"); + testFile2.Write(pBuf); + testFile2.Flush(); + RFileClamp handle2; + r=handle2.Clamp(testFile2); + test(r==KErrNone); + + // Create and clamp a third file ... + RFileClamp handle3; + fileName = _L("clampFile3.tst"); + RFile testFile3; + r=testFile3.Replace(TheFs,fileName,EFileWrite); + test(r==KErrNone); + buf=_L("buffer for file 3"); + testFile3.Write(pBuf); + testFile3.Flush(); + r=handle3.Clamp(testFile3); + test(r==KErrNone); + + // Test can unclamp then reclamp first file + // then repeat for the third file + r=handle.Close(TheFs); + test (r==KErrNone); + r=handle.Clamp(testFile); + test(r==KErrNone); + r=handle3.Close(TheFs); + test (r==KErrNone); + r=handle3.Clamp(testFile3); + test(r==KErrNone); + + // Tidy up + r=handle.Close(TheFs); + test (r==KErrNone); + r=handle1.Close(TheFs); + test (r==KErrNone); + testFile.Close(); + r=TheFs.Delete(_L("clampFile.tst")); + test (r==KErrNone); + + r=handle2.Close(TheFs); + test (r==KErrNone); + testFile2.Close(); + r=TheFs.Delete(_L("clampFile2.tst")); + test (r==KErrNone); + + r=handle3.Close(TheFs); + test (r==KErrNone); + testFile3.Close(); + r=TheFs.Delete(_L("clampFile3.tst")); + test (r==KErrNone); + } + + +LOCAL_C void Test2() + { +// Invalid clamp requests + test.Next(_L("T_Clamp - Test2()")); + + // Test attempt to clamp empty file is rejected + RFileClamp handle4; + TBuf<256> file4Name; + file4Name = _L("clampFile4.tst"); + RFile testFile4; + TInt r=testFile4.Replace(TheFs,file4Name,EFileWrite); + test(r==KErrNone); + r=handle4.Clamp(testFile4); + test(r==KErrEof); + + // Preparation for next test - create a valid clamp handle + TBuf<256> buf4(_L("buffer for file 4")); + TPtrC8 pBuf4((TUint8*)&buf4); + testFile4.Write(pBuf4); + testFile4.Flush(); + r=handle4.Clamp(testFile4); + test(r==KErrNone); + + // Try to unclamp non-existant file + RFileClamp handle5; + memcpy((TAny*)&handle5,(TAny*)&handle4,sizeof(RFileClamp)); + handle5.iCookie[0] = MAKE_TINT64(-1,-1); // iCookie[0] holds the unique ID + r=handle5.Close(TheFs); + test (r==KErrNotFound); + + // Tidy up + r=handle4.Close(TheFs); + test (r==KErrNone); + testFile4.Close(); + r=TheFs.Delete(_L("clampFile4.tst")); + test (r==KErrNone); + } + + + +LOCAL_C void TestDeferredDismount(TDesC& aRoot, TDesC& aFileName, RFileClamp* handlePtr) + { + // Open and clamp file, register for dismount notification, then issue + // dismount instruction. + // Since there are no other clients registered for dismount notification, + // this would normally lead too dismount being instigated. However, since + // the file is clamped, dismount should be deferred + test.Next(_L("T_Clamp - TestDeferredDismount()")); + + // File system details required for clean-up + const TInt KMaxFileSystemNameLength=100; // Arbitrary length + const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length + TBuf fsName; + TBuf fsExtName_0; + TBuf fsExtName_1; + TBool fsExt0Present=EFalse; + TBool fsExt1Present=EFalse; + TInt driveNo, r; + r=TheFs.CharToDrive(aRoot[0], driveNo); + test(r==KErrNone); + r=TheFs.FileSystemName(fsName, driveNo); + test(r==KErrNone); + r=TheFs.ExtensionName(fsExtName_0,driveNo,0); + if(r==KErrNone) + fsExt0Present=ETrue; + r=TheFs.ExtensionName(fsExtName_1,driveNo,1); + if(r==KErrNone) + fsExt1Present=ETrue; + + // Create a file & write to it so that we can test whether dismounting works correctly with dirty data + TDriveInfo driveInfo; + test(TheFs.Drive(driveInfo, driveNo) == KErrNone); + TFileName dirtyFileName(_L("dirtyFile.tst")); + RFile dirtyFile; + if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) + { + r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite); + test(r==KErrNone); + r=dirtyFile.Write(_L8("My name is Michael Caine")); + test(r==KErrNone); + } + + + RFile testFile; + r=testFile.Open(TheFs,aFileName,EFileRead); + test(r==KErrNone); + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + testFile.Close(); + + TRequestStatus clientNotify=KErrNone; + TRequestStatus clientDismount=KErrNone; + TheFs.NotifyDismount(driveNo, clientNotify); // Register for notification + test(clientNotify == KRequestPending); + + TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); + test(clientDismount == KRequestPending); + User::WaitForRequest(clientNotify); + test(clientNotify == KErrNone); + + r=TheFs.AllowDismount(driveNo); // Respond to dismount notification + test(r == KErrNone); + test(clientDismount == KRequestPending); // Dismount is deferred + + // + // Now unclamp the file, and check that the deferred dismount is performed. + r=handlePtr->Close(TheFs); + test(r==KErrNone); + User::WaitForRequest(clientDismount); + test(clientDismount == KErrNone); + + // Try to write to the opened file: this should return KErrNotReady as there is no drive thread + if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) + { + r=dirtyFile.Write(_L8("My name isn't really Michael Caine")); + test(r==KErrNotReady); + } + + // Re-mount the file system + if(fsExt0Present) + { + r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); + test(r==KErrNone); + } + else if(fsExt1Present) // untested ! + { + r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); + test(r==KErrNone); + } + else + { + r=TheFs.MountFileSystem(fsName,driveNo); + test_KErrNone(r); + } + + // create some more dirty data to verify that the file server can cope with the drive thread + // having gone & come back again + if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) + { + r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish.")); + test(r==KErrDisMounted); + + dirtyFile.Close(); + r = TheFs.Delete(dirtyFileName); + test(r == KErrNone); + } + + // Issue a EFsDismountNotifyClients with no clients but with files clamped + // & verify that the dismount request completes when clamps are removed + r=testFile.Open(TheFs,aFileName,EFileRead); + test(r==KErrNone); + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + testFile.Close(); + TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); + + test(clientDismount == KRequestPending); + r=handlePtr->Close(TheFs); + test(r==KErrNone); + User::WaitForRequest(clientDismount); + test(clientDismount == KErrNone); + // Re-mount the file system again + if(fsExt0Present) + { + r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); + test(r==KErrNone); + } + else if(fsExt1Present) // untested ! + { + r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); + test(r==KErrNone); + } + else + { + r=TheFs.MountFileSystem(fsName,driveNo); + test_KErrNone(r); + } + + + // Issue a EFsDismountForceDismount with no clients but with files clamped + // & verify that the dismount request completes when clamps are removed + r=testFile.Open(TheFs,aFileName,EFileRead); + test(r==KErrNone); + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + testFile.Close(); + TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountForceDismount); + + test(clientDismount == KRequestPending); + r=handlePtr->Close(TheFs); + test(r==KErrNone); + User::WaitForRequest(clientDismount); + test(clientDismount == KErrNone); + // Re-mount the file system again + if(fsExt0Present) + { + r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); + test(r==KErrNone); + } + else if(fsExt1Present) // untested ! + { + r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); + test(r==KErrNone); + } + else + { + r=TheFs.MountFileSystem(fsName,driveNo); + test_KErrNone(r); + } + + } + + + +LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName) + { + test.Next(_L("T_Clamp - Test3Operations()")); + // RFormat::Open +#ifdef __WINS__ + if (User::UpperCase(aRoot[0]) != 'C') +#endif + { + TBuf<4> driveBuf=_L("?:\\"); + driveBuf[0] = aRoot[0]; + RFormat format; + TInt count; + TInt r=format.Open(TheFs,driveBuf,EFullFormat,count); + test(r==KErrInUse); + format.Close(); + } + + // Dismount: synchronous requests + // RFs::DismountFileSystem, RFs::SwapFileSystem + const TInt KMaxFileSystemNameLength=100; // Arbitrary length + TBuf fileSysName; + TInt driveNo, r; + r=TheFs.CharToDrive(aRoot[0], driveNo); + test(r==KErrNone); + r=TheFs.FileSystemName(fileSysName,driveNo); + test(r==KErrNone); + + r=TheFs.DismountFileSystem(fileSysName,driveNo); + test(r==KErrInUse); + + r=TheFs.SwapFileSystem(fileSysName,fileSysName,driveNo); + test(r==KErrInUse); + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + // The cancellation of deferred dismounts requires controlIO + // functionality available in debug versions of the code. + + // Dismount: asynchronous requests + // RFs::NotifyDismount, RFs::AllowDismount + const TInt KNumClients = 5; + RFs clientFs[KNumClients]; + TRequestStatus clientNotify[KNumClients]; + TRequestStatus clientComplete; + TInt i=0; + for(i=0; i< KNumClients; i++) + { + r=clientFs[i].Connect(); + test(r==KErrNone); + } + // Cancel any deferred dismount in preparation for the next test + r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); + test(r==KErrNone); + + // Use case 1: Orderly dismount + // All clients register for dismount notification + for(i=0; i< KNumClients; i++) + { + clientNotify[i] = KErrNone; + clientFs[i].NotifyDismount(driveNo, clientNotify[i]); + test(clientNotify[i] == KRequestPending); + } + // First client notifies intent to dismount + clientComplete = KErrNone; + clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); + test(clientComplete == KRequestPending); + // Check all clients have received the notification + for(i=0; i< KNumClients; i++) + { + test(clientNotify[i] == KErrNone); + } + // All clients invoke AllowDismount + for(i=0; i< KNumClients; i++) + { + r=clientFs[i].AllowDismount(driveNo); + test(r==KErrNone); + } + // Dismount is deferred + test(clientComplete == KRequestPending); + + + // Cancel the deferred dismount in preparation for the next test + clientFs[0].NotifyDismountCancel(clientComplete); + test(clientComplete == KErrCancel); + r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); + test(r==KErrNone); + clientComplete=KErrNone; // Re-initialise the TRequestStatus + + + // Use case 2: Forced dismount + // All clients register for dismount notification + for(i=0; i< KNumClients; i++) + { + clientFs[i].NotifyDismount(driveNo, clientNotify[i]); + test(clientNotify[i] == KRequestPending); + } + // First client notifies intent to dismount + clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); + test(clientComplete == KRequestPending); + // Check all clients have received the notification + for(i=0; i< KNumClients; i++) + { + test(clientNotify[i] == KErrNone); + } + // Not all other clients invoke AllowDismount + for(i=0; i< KNumClients-1; i++) + { + clientFs[i].AllowDismount(driveNo); + } + // First client attempts forced dismount + test(clientComplete == KRequestPending); + clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountForceDismount); + // Dismount is deferred + test(clientComplete == KRequestPending); + + // Cancel the deferred dismount in preparation for the next test + // Also cancel the 'un-Allowed' notification request + clientFs[0].NotifyDismountCancel(clientComplete); + test(clientComplete == KErrCancel); + r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); + test(r==KErrNone); + clientComplete=KErrNone; // Re-initialise the TRequestStatus +#endif + + // RFile::Open with EFileWrite + RFile testFile; + r=testFile.Open(TheFs,aFileName,EFileWrite|EFileShareReadersOrWriters); + test(r==KErrInUse); + + // RFile::Replace + RFile testFile2; + r=testFile2.Replace(TheFs,aFileName,EFileRead); + test(r==KErrInUse); + testFile2.Close(); + + // RFile::Set - this should not be prevented by clamping + r=testFile.Open(TheFs,aFileName,EFileRead|EFileShareAny); + test(r == KErrNone); + + TTime origTime; + TUint origAtt; + r=testFile.Att(origAtt); + test(r==KErrNone); + r=testFile.Modified(origTime); + test(r==KErrNone); + + TTime time; // Arbitrary value + TUint setMask=0xA5A5&~KEntryAttReadOnly; // Not read-only, otherwise arbitrary value + TUint clearMask=0x5A5A & KEntryAttReadOnly; // Not read-only, otherwise arbitrary value + r=testFile.Set(time,setMask,clearMask); + test(r==KErrNone); + + r=testFile.Set(origTime,origAtt,~origAtt); // restore original values + test(r==KErrNone); + testFile.Close(); + + // RFs::Rename - this should not be prevented by clamping + r=TheFs.Rename(aFileName,_L("aDummyName")); + test(r==KErrNone); + r=TheFs.Rename(_L("aDummyName"),aFileName); // restore original name + test(r==KErrNone); + + // RFs::Replace + r=TheFs.Replace(aFileName,_L("aDummyName")); + test(r==KErrInUse); + + // RFs::SetEntry - this should not be prevented by clamping + r=TheFs.SetEntry(aFileName,time,setMask,clearMask); + test(r==KErrNone); + r=TheFs.SetEntry(aFileName,origTime,origAtt,~origAtt); // restore original values + test(r==KErrNone); + + // RFs::Delete + r=TheFs.Delete(aFileName); + test(r==KErrInUse); + + // RRawDisk::Open (*** no longer required ***) + } + +LOCAL_C void Test3(TDesC& aRoot) + { +// Denied FS requests when file(s) are clamped. + test.Next(_L("T_Clamp - Test3()")); + +// Clamping is reference counted, so we need a test to check that +// a file clamped N times cannot be modified until it has been unclamped N times. +// Should also check +// - Clamp N times +// - Unclamp M times (M fileName; + TBuf<256> buf(_L("buffer for file used")); + fileName = _L("clampFile.tst"); + RFile testFile; + TInt r=testFile.Replace(TheFs,fileName,EFileWrite); + test(r==KErrNone); + TPtrC8 pBuf((TUint8*)&buf); + testFile.Write(pBuf); + testFile.Flush(); + // Close file,then re-open (to support clamping) in sharable mode + // (to allow testing of RFile::Open with EFileWrite) + testFile.Close(); + r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); + test(r==KErrNone); + // Show, prior to clamping, that the file can be opened with EFileWrite + RFile testFile2; + r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); + test(r==KErrNone); + // Close the second RFile instance + testFile2.Close(); + + // Clamp and unclamp a number of times, and invoke the + // operations to test + RFileClamp myHandles[MY_N]; + RFileClamp *handlePtr = myHandles; + TInt i = 0; + + // Clamp once + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + i++; + + // RFile::SetAtt - this should not be prevented by clamping + TTime origTime; + TUint origAtt; + r=testFile.Att(origAtt); + test(r==KErrNone); + r=testFile.Modified(origTime); + test(r==KErrNone); + TTime time; // Arbitrary value + TUint setMask=0xA5A5&~KEntryAttReadOnly; // Not read-only, otherwise arbitrary value + TUint clearMask=0x5A5A & KEntryAttReadOnly; // Not read-only, otherwise arbitrary value + r=testFile.Att(origAtt); + test(r==KErrNone); + r=testFile.SetAtt(setMask,clearMask); + test(r==KErrNone); + r=testFile.Set(origTime,origAtt,~origAtt); // restore original values + test(r==KErrNone); + + // RFile::SetModified - this should not be prevented by clamping + r=testFile.Modified(origTime); + test(r==KErrNone); + r=testFile.SetModified(time); + test(r==KErrNone); + r=testFile.SetModified(origTime); // restore original value + test(r==KErrNone); + + // RFile::Rename - this should not be prevented by clamping + // Need file to be opened in EFileShareExclusive sharing mode, + // so close, unclamp, re-open appropriately and re-clamp + testFile.Close(); + r=handlePtr->Close(TheFs); + test(r==KErrNone); + i--; + r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareExclusive); + test(r==KErrNone); + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + i++; + r=testFile.Rename(_L("aDummyName")); + test(r==KErrNone); + r=testFile.Rename(fileName); + test(r==KErrNone); + + // RFile::SetSize + r=testFile.SetSize(1000); // Arbitrary value + test(r==KErrInUse); + + // Test other RFile, RFs operations + testFile.Close(); + Test3Operations(aRoot,fileName); + + // Increase number of clamps to MY_N + r=testFile.Open(TheFs,fileName,EFileRead); + test(r==KErrNone); + for(; i < MY_N; i++) + { + handlePtr++; + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + } + testFile.Close(); + Test3Operations(aRoot,fileName); + + // Decrease number of clamps by MY_M + for(;i > (MY_N - MY_M); i--) + { + r=handlePtr->Close(TheFs); + test(r==KErrNone); + if(handlePtr!=myHandles) + handlePtr--; + else + break; + } + Test3Operations(aRoot,fileName); + + // Increase number of clamps by MY_M + r=testFile.Open(TheFs,fileName,EFileRead); + test(r == KErrNone); + TInt j=0; + for(;j < MY_M; j++) + { + handlePtr++; + r=handlePtr->Clamp(testFile); + test(r==KErrNone); + i++; + } + testFile.Close(); + Test3Operations(aRoot,fileName); + + // Decrease number of clamps by MY_N + for(;i > 0; i--) + { + r=handlePtr->Close(TheFs); + test(r==KErrNone); + if(handlePtr!=myHandles) + handlePtr--; + else + break; + } + + // Test deferred dismount - use next free handle + TestDeferredDismount(aRoot,fileName,handlePtr); + + // Re-create the test directory + r=TheFs.MkDirAll(aRoot); + test(r==KErrNone || r== KErrAlreadyExists); + TheFs.SetSessionPath(aRoot); + + // No clamps remain - prove RFile::Open with EFileWrite + r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); + test(r==KErrNone); + testFile2.Close(); + + // No clamps remain - prove that file can now be deleted + r=TheFs.Delete(_L("clampFile.tst")); + test (r==KErrNone); + } + + +LOCAL_C void Test4(TDesC& aRoot) + { +// Clamp tests for non-writable file system + test.Next(_L("T_Clamp - Test4()")); + + // Tests are limited to clamp, unclamp and denied requests + // when clamps are present. + TBuf<256> pathName; +#ifdef __WINS__ + if((aRoot[0]=='Z')||(aRoot[0]=='z')) + pathName=_L("clean.txt"); + else + pathName=_L("root.txt"); +#else + if((aRoot[0]=='Z')||(aRoot[0]=='z')) + pathName=_L("UnicodeData.txt"); + else + pathName=_L("\\Test\\clamp.txt"); // For (non-composite) ROFS drive +#endif + RFile testFile; + TInt r=testFile.Open(TheFs, pathName, EFileRead); + test(r==KErrNone); + + // Clamp file + RFileClamp handle; + r=handle.Clamp(testFile); + test(r==KErrNone); + TInt64 storedCookie_0=handle.iCookie[0]; + TInt64 storedCookie_1=handle.iCookie[1]; + + // Try to clamp previously-clamped file + RFileClamp handle1; + r=handle1.Clamp(testFile); + test(r==KErrNone); + + // Unclamp file + r=handle.Close(TheFs); + test (r==KErrNone); + // Check cookie content has been re-initialised + test((0==handle.iCookie[0])&&(0==handle.iCookie[1])); + + // Try to unclamp a file that is not clamped + handle.iCookie[0]=storedCookie_0; + handle.iCookie[1]=storedCookie_1; + r=handle.Close(TheFs); + test (r==KErrNotFound); + // Remove remaining clamp + r=handle1.Close(TheFs); + test (r==KErrNone); + + testFile.Close(); + + if((aRoot[0]!='Z')&&(aRoot[0]!='z')) // Can not dismount Z: + TestDeferredDismount(aRoot,pathName,&handle); + } + + +LOCAL_C void Test5() + { +// Clamp requests on non-clamping file systems + test.Next(_L("T_Clamp - Test5()")); + + TBuf<256> unsuppFile; + unsuppFile = _L("unsuppFile.tst"); + RFile testFile; + TInt r=testFile.Replace(TheFs,unsuppFile,EFileWrite); + test(r==KErrNone); + + // Try to clamp a file on a file system that does + // not support clamping + RFileClamp handle; + r=handle.Clamp(testFile); + test(r==KErrNotSupported); + + // Tidy up + testFile.Close(); + r=TheFs.Delete(_L("unsuppFile.tst")); + test (r==KErrNone); + } + + +LOCAL_C void GetDriveLetters() + { +// Assign the first drive that matches the required criteria + test.Next(_L("T_Clamp - GetDriveLetters()")); + + TDriveList driveList; + TDriveInfo driveInfo; + TInt r=TheFs.DriveList(driveList); + test(r==KErrNone); + TInt drvNum; + TBool drivesFound = EFalse; + for(drvNum=0; (drvNum pathName; + + //************************************************************************ + // + // Test on FAT (writable file system) + // + //************************************************************************ + if(NandFatDrv!='?') + { + pathName=_L("?:\\CLAMP-TST\\"); // FAT on NAND + pathName[0]=(TText)NandFatDrv; + r=TheFs.MkDirAll(pathName); + test(r==KErrNone || r== KErrAlreadyExists); + TheFs.SetSessionPath(pathName); + test.Printf( _L("T_CLAMP: testing FAT drive on %C\n"),(TText)NandFatDrv); + + Test1(); // Basic clamp operation + Test2(); // Invalid clamp requests + Test3(pathName);// Denied FS requests when files are clamped + + r=TheFs.RmDir(pathName); + test(r==KErrNone); + } + else + test.Printf( _L("T_CLAMP: FAT drive not tested\n")); + + //************************************************************************ + // + // Test on ROFS (non-writable file system) + // + //************************************************************************ + if(RofsDrv!='?') + { + pathName=_L("?:\\"); + pathName[0]=(TText)RofsDrv; + TheFs.SetSessionPath(pathName); + test.Printf( _L("T_CLAMP: testing ROFS drive on %C\n"),(TText)RofsDrv); + + Test4(pathName); // Clamp tests for non-writable file system + } + else + test.Printf( _L("T_CLAMP: ROFS drive not tested\n")); + + //************************************************************************ + // + // Test on Z: - Composite File System, or ROMFS (non-writable file system) + // + //************************************************************************ + if(CompDrv!='?') + { + pathName=_L("?:\\TEST\\"); + pathName[0]=(TText)CompDrv; + TheFs.SetSessionPath(pathName); + test.Printf( _L("T_CLAMP: testing Z drive (on %C)\n"),(TText)CompDrv); + + Test4(pathName); // Clamp tests for non-writable file system + } + else + test.Printf( _L("T_CLAMP: Z drive not tested\n")); + + //************************************************************************ + // + // Test on LFFS (non-clampable file system) + // + //************************************************************************ + if(LffsDrv!='?') + { + TBuf<256> unsuppPath; + unsuppPath=_L("?:\\CLAMP-TST\\"); + unsuppPath[0]=(TText)LffsDrv; + r=TheFs.MkDirAll(unsuppPath); + test(r==KErrNone || r== KErrAlreadyExists); + TheFs.SetSessionPath(unsuppPath); + test.Printf( _L("T_CLAMP: testing LFFS drive on %C\n"),(TText)LffsDrv); + + Test5(); // Clamp requests on non-clamping file systems + } + else + test.Printf( _L("T_CLAMP: LFFS drive not tested\n")); + + test.End(); + return 0; + } + +#else + +TInt E32Main() + { + test.Title(); + test.Start(_L("Test does not run on UREL builds.")); + test.End(); + return 0; + } +#endif