--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/demandpaging/t_clamp.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -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 <e32test.h>
+RTest test(_L("T_CLAMP"));
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+
+#include <f32file.h>
+#include <f32dbg.h>
+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<KMaxFileSystemNameLength> fsName;
+ TBuf<KMaxFileSystemExtNameLength> fsExtName_0;
+ TBuf<KMaxFileSystemExtNameLength> 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<KMaxFileSystemNameLength> 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<N)
+// - Clamp M times.
+// - Unclamp N times
+
+#define MY_N 16
+#define MY_M 12
+
+ // Create a file for use
+ 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();
+ // 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<KMaxDrives) && !drivesFound; drvNum++)
+ {
+ TChar drvLetter='?';
+ TFileName fileSystem;
+ if(!driveList[drvNum])
+ continue;
+ test(TheFs.Drive(driveInfo, drvNum) == KErrNone);
+ test(TheFs.DriveToChar(drvNum,drvLetter) == KErrNone);
+ r=TheFs.FileSystemName(fileSystem,drvNum);
+ fileSystem.UpperCase();
+ test((r==KErrNone)||(r==KErrNotFound));
+ if (!(driveInfo.iDriveAtt & KDriveAttInternal))
+ continue;
+ // Check for FAT on NAND
+ if(NandFatDrv=='?')
+ {
+ if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KFATName)==0))
+ NandFatDrv=drvLetter;
+ }
+ // Check for ROFS
+ if(RofsDrv=='?')
+ {
+ if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KROFSName)==0))
+ RofsDrv=drvLetter;
+ }
+ // Check for LFFS
+ if(LffsDrv=='?')
+ {
+ if((driveInfo.iType==EMediaFlash) && (fileSystem.Compare(KLFFSName)==0))
+ LffsDrv=drvLetter;
+ }
+ // Check for CompFSys
+ if(CompDrv=='?')
+ {
+ if((driveInfo.iType==EMediaRom) && ((fileSystem.Compare(KROMName)==0)||(fileSystem.Compare(KCOMPName)==0)))
+ CompDrv=drvLetter;
+ }
+ drivesFound=((NandFatDrv!='?')&&(RofsDrv!='?')&&(LffsDrv!='?')&&(CompDrv!='?'));
+ }
+ if(NandFatDrv!='?')
+ test((NandFatDrv!=RofsDrv)&&(NandFatDrv!=LffsDrv)&&(NandFatDrv!=CompDrv));
+ if(RofsDrv!='?')
+ test((RofsDrv!=LffsDrv)&&(RofsDrv!=CompDrv));
+ if(LffsDrv!='?')
+ test(LffsDrv!=CompDrv);
+
+ RDebug::Printf("T_CLAMP: FAT drive=%C, ROFS drive=%C, LFFS drive=%C, ROM-COMP drive=%C \n",(TText)NandFatDrv,(TText)RofsDrv,(TText)LffsDrv,(TText)CompDrv);
+ return;
+ }
+
+
+//
+// E32Main
+//
+
+TInt E32Main()
+ {
+ TInt r;
+ test.Title();
+ test.Start(_L("Starting T_CLAMP ..."));
+ test(TheFs.Connect()==KErrNone);
+
+ GetDriveLetters();
+ TBuf<256> 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