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