os/kernelhwsrv/kerneltest/f32test/demandpaging/t_clamp.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32test\demandpaging\t_clamp.cpp
    15 // Test suite for file clamping, file clamping is used to prevent files
    16 // (exes or dlls) from being deleted whilst in use.
    17 // 002 GetDriveLetters()
    18 // 003 Test1() Basic clamp operation
    19 // 004 Test2() Invalid clamp requests
    20 // 005 Test3() Denied FS requests when file(s) are clamped
    21 // 006 Test3Operations() Test other RFile, RFs operations
    22 // 007 Test3Operations() Increase number of clamps to MY_N
    23 // 008 Test3Operations() Decrease number of clamps by MY_M
    24 // 009 Test3Operations() Increase number of clamps by MY_M
    25 // 010 TestDeferredDismount() Open and clamp file, register for dismount 
    26 // notification, then issue dismount instruction.
    27 // 011 Test4() Clamp tests for non-writable file system
    28 // 012 Test5() Clamp requests on non-clamping file systems
    29 // 
    30 //
    31 
    32 //! @SYMTestCaseID			KBASE-T_CLAMP-0328
    33 //! @SYMTestType			UT
    34 //! @SYMPREQ				PREQ1110
    35 //! @SYMTestCaseDesc		Demand Paging File Clamp tests
    36 //! @SYMTestActions			001 Starting T_CLAMP
    37 //! @SYMTestExpectedResults All tests should pass.
    38 //! @SYMTestPriority        High
    39 //! @SYMTestStatus          Implemented
    40 
    41 #define __E32TEST_EXTENSION__
    42 
    43 #include <e32test.h>
    44 RTest test(_L("T_CLAMP"));
    45 
    46 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
    47 
    48 #include <f32file.h>
    49 #include <f32dbg.h>
    50 #include <e32ldr_private.h>
    51 RFs TheFs;
    52 
    53 _LIT(KFATName,"FAT");
    54 //_LIT(KFAT32Name,"FAT32");
    55 _LIT(KROFSName,"ROFS");
    56 _LIT(KLFFSName,"LFFS");
    57 _LIT(KCOMPName,"COMPOSITE"); // Z: name if Composite File System
    58 //#ifdef __WINS__
    59 //_LIT(KROMName,"WIN32");	// Clamping is not supported for non-composite filing system on Z:
    60 //#else
    61 _LIT(KROMName,"ROM");		 // Z: name if ROMFS (on hardware, not emulator)
    62 //#endif
    63 
    64 TChar NandFatDrv='?';
    65 TChar RofsDrv='?';
    66 TChar LffsDrv='?';
    67 TChar CompDrv='?';
    68 
    69 
    70 LOCAL_C void Test1()
    71 	{
    72 // Basic clamp operation
    73 	test.Next(_L("T_Clamp - Test1()"));
    74 
    75 	TBuf<256> fileName;	
    76 	TBuf<256> buf(_L("buffer for file used"));
    77 
    78 	fileName = _L("clampFile.tst");
    79 	RFile testFile;
    80 	TInt r=testFile.Replace(TheFs,fileName,EFileWrite);
    81 	test(r==KErrNone);
    82 	TPtrC8 pBuf((TUint8*)&buf);
    83 	testFile.Write(pBuf);
    84 	testFile.Flush();
    85 
    86 	// Clamp file
    87 	RFileClamp handle;
    88 	r=handle.Clamp(testFile);
    89 	test(r==KErrNone);
    90 	TInt64 storedCookie_0=handle.iCookie[0];
    91 	TInt64 storedCookie_1=handle.iCookie[1];
    92 
    93 	// Try to clamp previously-clamped file
    94 	RFileClamp handle1;
    95 	r=handle1.Clamp(testFile);
    96 	test(r==KErrNone);
    97 
    98 	// Unclamp file
    99 	r=handle.Close(TheFs);
   100 	test (r==KErrNone);
   101 	// Check cookie content has been re-initialised
   102 	test((0==handle.iCookie[0])&&(0==handle.iCookie[1]));
   103 
   104 	// Try to unclamp a file that is not clamped
   105 	handle.iCookie[0]=storedCookie_0;
   106 	handle.iCookie[1]=storedCookie_1;
   107 	r=handle.Close(TheFs);
   108 	test (r==KErrNotFound);
   109 
   110 	// Check that attempting to unclamp with a zero-content cookie
   111 	// yields no error
   112 	handle.iCookie[0]=0;
   113 	handle.iCookie[1]=0;
   114 	r=handle.Close(TheFs);
   115 	test (r==KErrNone);
   116 
   117 	// Clamp the file (again)
   118 	r=handle.Clamp(testFile);
   119 	test(r==KErrNone);
   120 
   121 	// Create and clamp a second file ...
   122 	fileName = _L("clampFile2.tst");
   123 	RFile testFile2;
   124 	r=testFile2.Replace(TheFs,fileName,EFileWrite);
   125 	test(r==KErrNone);
   126 	buf=_L("buffer for file 2");
   127 	testFile2.Write(pBuf);
   128 	testFile2.Flush();
   129 	RFileClamp handle2;
   130 	r=handle2.Clamp(testFile2);
   131 	test(r==KErrNone);
   132 
   133 	// Create and clamp a third file ...
   134 	RFileClamp handle3;
   135 	fileName = _L("clampFile3.tst");
   136 	RFile testFile3;
   137 	r=testFile3.Replace(TheFs,fileName,EFileWrite);
   138 	test(r==KErrNone);
   139 	buf=_L("buffer for file 3");
   140 	testFile3.Write(pBuf);
   141 	testFile3.Flush();
   142 	r=handle3.Clamp(testFile3);
   143 	test(r==KErrNone);
   144 
   145 	// Test can unclamp then reclamp first file
   146 	// then repeat for the third file
   147 	r=handle.Close(TheFs);
   148 	test (r==KErrNone);
   149 	r=handle.Clamp(testFile);
   150 	test(r==KErrNone);
   151 	r=handle3.Close(TheFs);
   152 	test (r==KErrNone);
   153 	r=handle3.Clamp(testFile3);
   154 	test(r==KErrNone);
   155 
   156 	// Tidy up
   157 	r=handle.Close(TheFs);
   158 	test (r==KErrNone);
   159 	r=handle1.Close(TheFs);
   160 	test (r==KErrNone);
   161 	testFile.Close();
   162 	r=TheFs.Delete(_L("clampFile.tst"));
   163 	test (r==KErrNone);
   164 
   165 	r=handle2.Close(TheFs);
   166 	test (r==KErrNone);
   167 	testFile2.Close();
   168 	r=TheFs.Delete(_L("clampFile2.tst"));
   169 	test (r==KErrNone);
   170 
   171 	r=handle3.Close(TheFs);
   172 	test (r==KErrNone);
   173 	testFile3.Close();
   174 	r=TheFs.Delete(_L("clampFile3.tst"));
   175 	test (r==KErrNone);
   176 	}
   177 
   178 
   179 LOCAL_C void Test2()
   180 	{
   181 // Invalid clamp requests
   182 	test.Next(_L("T_Clamp - Test2()"));
   183 	
   184 	// Test attempt to clamp empty file is rejected
   185 	RFileClamp handle4;
   186 	TBuf<256> file4Name;	
   187 	file4Name = _L("clampFile4.tst");
   188 	RFile testFile4;
   189 	TInt r=testFile4.Replace(TheFs,file4Name,EFileWrite);
   190 	test(r==KErrNone);
   191 	r=handle4.Clamp(testFile4);
   192 	test(r==KErrEof);
   193 
   194 	// Preparation for next test - create a valid clamp handle
   195 	TBuf<256> buf4(_L("buffer for file 4"));
   196 	TPtrC8 pBuf4((TUint8*)&buf4);
   197 	testFile4.Write(pBuf4);
   198 	testFile4.Flush();
   199 	r=handle4.Clamp(testFile4);
   200 	test(r==KErrNone);
   201 
   202 	// Try to unclamp non-existant file
   203 	RFileClamp handle5;
   204 	memcpy((TAny*)&handle5,(TAny*)&handle4,sizeof(RFileClamp));
   205 	handle5.iCookie[0] = MAKE_TINT64(-1,-1); // iCookie[0] holds the unique ID
   206 	r=handle5.Close(TheFs);
   207 	test (r==KErrNotFound);
   208 
   209 	// Tidy up
   210 	r=handle4.Close(TheFs);
   211 	test (r==KErrNone);
   212 	testFile4.Close();
   213 	r=TheFs.Delete(_L("clampFile4.tst"));
   214 	test (r==KErrNone);
   215 	}
   216 
   217 
   218 
   219 LOCAL_C void TestDeferredDismount(TDesC& aRoot, TDesC& aFileName, RFileClamp* handlePtr)
   220 	{
   221 	// Open and clamp file, register for dismount notification, then issue 
   222 	// dismount instruction.
   223 	// Since there are no other clients registered for dismount notification,
   224 	// this would normally lead too dismount being instigated. However, since
   225 	// the file is clamped, dismount should be deferred
   226 	test.Next(_L("T_Clamp - TestDeferredDismount()"));
   227 
   228 	// File system details required for clean-up
   229 	const TInt KMaxFileSystemNameLength=100; // Arbitrary length
   230 	const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length
   231 	TBuf<KMaxFileSystemNameLength> fsName;
   232 	TBuf<KMaxFileSystemExtNameLength> fsExtName_0;
   233 	TBuf<KMaxFileSystemExtNameLength> fsExtName_1;
   234 	TBool fsExt0Present=EFalse;
   235 	TBool fsExt1Present=EFalse;
   236 	TInt driveNo, r;
   237 	r=TheFs.CharToDrive(aRoot[0], driveNo);
   238 	test(r==KErrNone);
   239 	r=TheFs.FileSystemName(fsName, driveNo);
   240 	test(r==KErrNone);
   241 	r=TheFs.ExtensionName(fsExtName_0,driveNo,0);
   242 	if(r==KErrNone)
   243 		fsExt0Present=ETrue;
   244 	r=TheFs.ExtensionName(fsExtName_1,driveNo,1);
   245 	if(r==KErrNone)
   246 		fsExt1Present=ETrue;
   247 
   248 	// Create a file & write to it so that we can test whether dismounting works correctly with dirty data
   249 	TDriveInfo driveInfo;
   250 	test(TheFs.Drive(driveInfo, driveNo) == KErrNone);
   251 	TFileName dirtyFileName(_L("dirtyFile.tst"));
   252 	RFile dirtyFile;
   253 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   254 		{
   255 		r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite);
   256 		test(r==KErrNone);
   257 		r=dirtyFile.Write(_L8("My name is Michael Caine"));
   258 		test(r==KErrNone);
   259 		}
   260 
   261 
   262 	RFile testFile;
   263 	r=testFile.Open(TheFs,aFileName,EFileRead);
   264 	test(r==KErrNone);
   265 	r=handlePtr->Clamp(testFile);
   266 	test(r==KErrNone);
   267 	testFile.Close();
   268 
   269 	TRequestStatus clientNotify=KErrNone;
   270 	TRequestStatus clientDismount=KErrNone;
   271 	TheFs.NotifyDismount(driveNo, clientNotify); // Register for notification
   272 	test(clientNotify == KRequestPending);
   273 	
   274 	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
   275 	test(clientDismount == KRequestPending);
   276 	User::WaitForRequest(clientNotify);
   277 	test(clientNotify == KErrNone);
   278 
   279 	r=TheFs.AllowDismount(driveNo);	// Respond to dismount notification
   280 	test(r == KErrNone);
   281 	test(clientDismount == KRequestPending); // Dismount is deferred
   282 
   283 	//
   284 	// Now unclamp the file, and check that the deferred dismount is performed.
   285 	r=handlePtr->Close(TheFs);
   286 	test(r==KErrNone);
   287 	User::WaitForRequest(clientDismount);
   288 	test(clientDismount == KErrNone);	
   289 
   290 	// Try to write to the opened file: this should return KErrNotReady as there is no drive thread
   291 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   292 		{
   293 		r=dirtyFile.Write(_L8("My name isn't really Michael Caine"));
   294 		test(r==KErrNotReady);
   295 		}
   296 
   297 	// Re-mount the file system
   298 	if(fsExt0Present)
   299 		{
   300 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
   301 		test(r==KErrNone);
   302 		}
   303 	else if(fsExt1Present) // untested !
   304 		{
   305 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
   306 		test(r==KErrNone);
   307 		}
   308 	else 
   309 		{
   310 		r=TheFs.MountFileSystem(fsName,driveNo);
   311 		test_KErrNone(r);
   312 		}
   313 
   314 	// create some more dirty data to verify that the file server can cope with the drive thread 
   315 	// having gone & come back again
   316 	if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   317 		{
   318 		r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish."));
   319 		test(r==KErrDisMounted);
   320 
   321 		dirtyFile.Close();
   322 		r = TheFs.Delete(dirtyFileName);
   323 		test(r == KErrNone);
   324 		}
   325 
   326 	// Issue a EFsDismountNotifyClients with no clients but with files clamped
   327 	// & verify that the dismount request completes when clamps are removed
   328 	r=testFile.Open(TheFs,aFileName,EFileRead);
   329 	test(r==KErrNone);
   330 	r=handlePtr->Clamp(testFile);
   331 	test(r==KErrNone);
   332 	testFile.Close();
   333 	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients);
   334 	
   335 	test(clientDismount == KRequestPending);
   336 	r=handlePtr->Close(TheFs);
   337 	test(r==KErrNone);
   338 	User::WaitForRequest(clientDismount);
   339 	test(clientDismount == KErrNone);	
   340 	// Re-mount the file system again
   341 	if(fsExt0Present)
   342 		{
   343 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
   344 		test(r==KErrNone);
   345 		}
   346 	else if(fsExt1Present) // untested !
   347 		{
   348 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
   349 		test(r==KErrNone);
   350 		}
   351 	else 
   352 		{
   353 		r=TheFs.MountFileSystem(fsName,driveNo);
   354 		test_KErrNone(r);
   355 		}
   356 
   357 
   358 	// Issue a EFsDismountForceDismount with no clients but with files clamped
   359 	// & verify that the dismount request completes when clamps are removed
   360 	r=testFile.Open(TheFs,aFileName,EFileRead);
   361 	test(r==KErrNone);
   362 	r=handlePtr->Clamp(testFile);
   363 	test(r==KErrNone);
   364 	testFile.Close();
   365 	TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountForceDismount);
   366 	
   367 	test(clientDismount == KRequestPending);
   368 	r=handlePtr->Close(TheFs);
   369 	test(r==KErrNone);
   370 	User::WaitForRequest(clientDismount);
   371 	test(clientDismount == KErrNone);	
   372 	// Re-mount the file system again
   373 	if(fsExt0Present)
   374 		{
   375 		r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo);
   376 		test(r==KErrNone);
   377 		}
   378 	else if(fsExt1Present) // untested !
   379 		{
   380 		r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo);
   381 		test(r==KErrNone);
   382 		}
   383 	else 
   384 		{
   385 		r=TheFs.MountFileSystem(fsName,driveNo);
   386 		test_KErrNone(r);
   387 		}
   388 
   389 	}
   390 
   391 
   392 
   393 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName)
   394 	{
   395 	test.Next(_L("T_Clamp - Test3Operations()"));
   396 	// RFormat::Open
   397 #ifdef __WINS__
   398 	if (User::UpperCase(aRoot[0]) != 'C')
   399 #endif
   400 		{
   401 		TBuf<4> driveBuf=_L("?:\\");
   402 		driveBuf[0] = aRoot[0];
   403 		RFormat format;
   404 		TInt count;
   405 		TInt r=format.Open(TheFs,driveBuf,EFullFormat,count);
   406 		test(r==KErrInUse);
   407 		format.Close();
   408 		}
   409 
   410 	// Dismount: synchronous requests
   411 	// RFs::DismountFileSystem, RFs::SwapFileSystem
   412 	const TInt KMaxFileSystemNameLength=100; // Arbitrary length
   413 	TBuf<KMaxFileSystemNameLength> fileSysName;
   414 	TInt driveNo, r;
   415 	r=TheFs.CharToDrive(aRoot[0], driveNo);
   416 	test(r==KErrNone);
   417 	r=TheFs.FileSystemName(fileSysName,driveNo);
   418 	test(r==KErrNone);
   419 
   420 	r=TheFs.DismountFileSystem(fileSysName,driveNo);
   421 	test(r==KErrInUse);
   422 	
   423 	r=TheFs.SwapFileSystem(fileSysName,fileSysName,driveNo);
   424 	test(r==KErrInUse);
   425 
   426 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   427 	// The cancellation of deferred dismounts requires controlIO 
   428 	// functionality available in debug versions of the code.
   429 
   430 	// Dismount: asynchronous requests
   431 	// RFs::NotifyDismount, RFs::AllowDismount
   432 	const TInt KNumClients = 5;
   433     RFs clientFs[KNumClients];
   434 	TRequestStatus clientNotify[KNumClients];
   435 	TRequestStatus clientComplete;
   436 	TInt i=0;
   437 	for(i=0; i< KNumClients; i++)
   438 		{
   439    		r=clientFs[i].Connect();
   440 		test(r==KErrNone);
   441 		}
   442 	// Cancel any deferred dismount in preparation for the next test
   443 	r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount);
   444 	test(r==KErrNone);	
   445 
   446 	// Use case 1: Orderly dismount
   447 	// All clients register for dismount notification
   448 	for(i=0; i< KNumClients; i++)
   449 		{
   450 		clientNotify[i] = KErrNone;
   451    		clientFs[i].NotifyDismount(driveNo, clientNotify[i]);
   452 		test(clientNotify[i] == KRequestPending);
   453 		}
   454 	// First client notifies intent to dismount
   455 	clientComplete = KErrNone;
   456    	clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients);
   457 	test(clientComplete == KRequestPending);
   458 	// Check all clients have received the notification
   459 	for(i=0; i< KNumClients; i++)
   460 		{
   461 		test(clientNotify[i] == KErrNone);
   462 		}
   463 	// All clients invoke AllowDismount
   464 	for(i=0; i< KNumClients; i++)
   465 		{
   466 		r=clientFs[i].AllowDismount(driveNo);
   467 		test(r==KErrNone);
   468 		}
   469 	// Dismount is deferred
   470 	test(clientComplete == KRequestPending);
   471 
   472 
   473 	// Cancel the deferred dismount in preparation for the next test
   474 	clientFs[0].NotifyDismountCancel(clientComplete);
   475 	test(clientComplete == KErrCancel);
   476 	r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount);
   477 	test(r==KErrNone);	
   478 	clientComplete=KErrNone; // Re-initialise the TRequestStatus
   479 
   480 
   481 	// Use case 2: Forced dismount
   482 	// All clients register for dismount notification
   483 	for(i=0; i< KNumClients; i++)
   484 		{
   485    		clientFs[i].NotifyDismount(driveNo, clientNotify[i]);
   486 		test(clientNotify[i] == KRequestPending);
   487 		}
   488 	// First client notifies intent to dismount
   489    	clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients);
   490 	test(clientComplete == KRequestPending);
   491 	// Check all clients have received the notification
   492 	for(i=0; i< KNumClients; i++)
   493 		{
   494 		test(clientNotify[i] == KErrNone);
   495 		}
   496 	// Not all other clients invoke AllowDismount
   497 	for(i=0; i< KNumClients-1; i++)
   498 		{
   499 		clientFs[i].AllowDismount(driveNo);
   500 		}
   501 	// First client attempts forced dismount
   502 	test(clientComplete == KRequestPending);
   503    	clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountForceDismount);
   504 	// Dismount is deferred
   505 	test(clientComplete == KRequestPending);
   506 
   507 	// Cancel the deferred dismount in preparation for the next test
   508 	// Also cancel the 'un-Allowed' notification request
   509 	clientFs[0].NotifyDismountCancel(clientComplete);
   510 	test(clientComplete == KErrCancel);
   511 	r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount);
   512 	test(r==KErrNone);	
   513 	clientComplete=KErrNone; // Re-initialise the TRequestStatus
   514 #endif
   515 
   516 	// RFile::Open with EFileWrite
   517 	RFile testFile;
   518 	r=testFile.Open(TheFs,aFileName,EFileWrite|EFileShareReadersOrWriters);
   519 	test(r==KErrInUse);
   520 
   521 	// RFile::Replace
   522 	RFile testFile2;
   523 	r=testFile2.Replace(TheFs,aFileName,EFileRead);
   524 	test(r==KErrInUse);
   525 	testFile2.Close();
   526 
   527 	// RFile::Set - this should not be prevented by clamping
   528 	r=testFile.Open(TheFs,aFileName,EFileRead|EFileShareAny);
   529 	test(r == KErrNone);
   530 
   531 	TTime origTime;
   532 	TUint origAtt;
   533 	r=testFile.Att(origAtt);
   534 	test(r==KErrNone);
   535 	r=testFile.Modified(origTime);
   536 	test(r==KErrNone);
   537 
   538 	TTime time;									// Arbitrary value
   539 	TUint setMask=0xA5A5&~KEntryAttReadOnly;	// Not read-only, otherwise arbitrary value
   540 	TUint clearMask=0x5A5A & KEntryAttReadOnly;	// Not read-only, otherwise arbitrary value
   541 	r=testFile.Set(time,setMask,clearMask);
   542 	test(r==KErrNone);
   543 
   544 	r=testFile.Set(origTime,origAtt,~origAtt); // restore original values
   545 	test(r==KErrNone);
   546 	testFile.Close();
   547 
   548 	// RFs::Rename - this should not be prevented by clamping
   549 	r=TheFs.Rename(aFileName,_L("aDummyName"));
   550 	test(r==KErrNone);
   551 	r=TheFs.Rename(_L("aDummyName"),aFileName); // restore original name
   552 	test(r==KErrNone);
   553 
   554 	// RFs::Replace
   555 	r=TheFs.Replace(aFileName,_L("aDummyName"));
   556 	test(r==KErrInUse);
   557 
   558 	// RFs::SetEntry - this should not be prevented by clamping
   559 	r=TheFs.SetEntry(aFileName,time,setMask,clearMask);
   560 	test(r==KErrNone);
   561 	r=TheFs.SetEntry(aFileName,origTime,origAtt,~origAtt); // restore original values
   562 	test(r==KErrNone);
   563 
   564 	// RFs::Delete
   565 	r=TheFs.Delete(aFileName);
   566 	test(r==KErrInUse);
   567 
   568 	// RRawDisk::Open (*** no longer required ***)
   569 	}
   570 
   571 LOCAL_C void Test3(TDesC& aRoot)
   572 	{
   573 // Denied FS requests when file(s) are clamped.
   574 	test.Next(_L("T_Clamp - Test3()"));
   575 
   576 // Clamping is reference counted, so we need a test to check that
   577 // a file clamped N times cannot be modified until it has been unclamped N times.
   578 // Should also check
   579 // - Clamp N times
   580 // - Unclamp M times (M<N)
   581 // - Clamp M times.
   582 // - Unclamp N times
   583 
   584 #define MY_N 16
   585 #define MY_M 12
   586 
   587 	// Create a file for use
   588 	TBuf<256> fileName;	
   589 	TBuf<256> buf(_L("buffer for file used"));
   590 	fileName = _L("clampFile.tst");
   591 	RFile testFile;
   592 	TInt r=testFile.Replace(TheFs,fileName,EFileWrite);
   593 	test(r==KErrNone);
   594 	TPtrC8 pBuf((TUint8*)&buf);
   595 	testFile.Write(pBuf);
   596 	testFile.Flush();
   597 	// Close file,then re-open (to support clamping) in sharable mode
   598 	// (to allow testing of RFile::Open with EFileWrite)
   599 	testFile.Close();
   600 	r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters);
   601 	test(r==KErrNone);
   602 	// Show, prior to clamping, that the file can be opened with EFileWrite
   603 	RFile testFile2;
   604 	r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters);
   605 	test(r==KErrNone);
   606 	// Close the second RFile instance
   607 	testFile2.Close();
   608 
   609 	// Clamp and unclamp a number of times, and invoke the
   610 	// operations to test
   611 	RFileClamp myHandles[MY_N];
   612 	RFileClamp *handlePtr = myHandles;
   613 	TInt i = 0;
   614 
   615 	// Clamp once
   616 	r=handlePtr->Clamp(testFile);
   617 	test(r==KErrNone);
   618 	i++;
   619 
   620 	// RFile::SetAtt - this should not be prevented by clamping
   621 	TTime origTime;
   622 	TUint origAtt;
   623 	r=testFile.Att(origAtt);
   624 	test(r==KErrNone);
   625 	r=testFile.Modified(origTime);
   626 	test(r==KErrNone);
   627 	TTime time;									// Arbitrary value
   628 	TUint setMask=0xA5A5&~KEntryAttReadOnly;	// Not read-only, otherwise arbitrary value
   629 	TUint clearMask=0x5A5A & KEntryAttReadOnly;	// Not read-only, otherwise arbitrary value
   630 	r=testFile.Att(origAtt);
   631 	test(r==KErrNone);
   632 	r=testFile.SetAtt(setMask,clearMask);
   633 	test(r==KErrNone);
   634 	r=testFile.Set(origTime,origAtt,~origAtt); // restore original values
   635 	test(r==KErrNone);
   636 
   637 	// RFile::SetModified - this should not be prevented by clamping
   638 	r=testFile.Modified(origTime);
   639 	test(r==KErrNone);
   640 	r=testFile.SetModified(time);
   641 	test(r==KErrNone);
   642 	r=testFile.SetModified(origTime); // restore original value
   643 	test(r==KErrNone);
   644 
   645 	// RFile::Rename - this should not be prevented by clamping
   646 	// Need file to be opened in EFileShareExclusive sharing mode,
   647 	// so close, unclamp, re-open appropriately and re-clamp
   648 	testFile.Close();
   649 	r=handlePtr->Close(TheFs);
   650 	test(r==KErrNone);
   651 	i--;
   652 	r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareExclusive);
   653 	test(r==KErrNone);
   654 	r=handlePtr->Clamp(testFile);
   655 	test(r==KErrNone);
   656 	i++;
   657 	r=testFile.Rename(_L("aDummyName"));
   658 	test(r==KErrNone);
   659 	r=testFile.Rename(fileName);
   660 	test(r==KErrNone);
   661 
   662 	// RFile::SetSize
   663 	r=testFile.SetSize(1000); // Arbitrary value
   664 	test(r==KErrInUse);
   665 
   666 	// Test other RFile, RFs operations
   667 	testFile.Close();
   668 	Test3Operations(aRoot,fileName);
   669 
   670 	// Increase number of clamps to MY_N
   671 	r=testFile.Open(TheFs,fileName,EFileRead);
   672 	test(r==KErrNone);
   673 	for(; i < MY_N; i++)
   674 		{
   675 		handlePtr++;
   676 		r=handlePtr->Clamp(testFile);
   677 		test(r==KErrNone);
   678 		}
   679 	testFile.Close();
   680 	Test3Operations(aRoot,fileName);
   681 
   682 	// Decrease number of clamps by MY_M
   683 	for(;i > (MY_N - MY_M); i--)
   684 		{
   685 		r=handlePtr->Close(TheFs);
   686 		test(r==KErrNone);
   687 		if(handlePtr!=myHandles)
   688 			handlePtr--;
   689 		else
   690 			break;
   691 		}
   692 	Test3Operations(aRoot,fileName);
   693 
   694 	// Increase number of clamps by MY_M
   695 	r=testFile.Open(TheFs,fileName,EFileRead);
   696 	test(r == KErrNone);
   697 	TInt j=0;
   698 	for(;j < MY_M; j++)
   699 		{
   700 		handlePtr++;
   701 		r=handlePtr->Clamp(testFile);
   702 		test(r==KErrNone);
   703 		i++;
   704 		}
   705 	testFile.Close();
   706 	Test3Operations(aRoot,fileName);
   707 
   708 	// Decrease number of clamps by MY_N
   709 	for(;i > 0; i--)
   710 		{
   711 		r=handlePtr->Close(TheFs);
   712 		test(r==KErrNone);
   713 		if(handlePtr!=myHandles)
   714 			handlePtr--;
   715 		else
   716 			break;
   717 		}
   718 
   719 	// Test deferred dismount - use next free handle
   720 	TestDeferredDismount(aRoot,fileName,handlePtr);
   721 
   722 	// Re-create the test directory
   723 	r=TheFs.MkDirAll(aRoot);
   724 	test(r==KErrNone || r== KErrAlreadyExists);
   725 	TheFs.SetSessionPath(aRoot);
   726 
   727 	// No clamps remain - prove RFile::Open with EFileWrite
   728 	r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters);
   729 	test(r==KErrNone);
   730 	testFile2.Close();
   731 
   732 	// No clamps remain - prove that file can now be deleted
   733 	r=TheFs.Delete(_L("clampFile.tst"));
   734 	test (r==KErrNone);
   735 	}
   736 
   737 
   738 LOCAL_C void Test4(TDesC& aRoot)
   739 	{
   740 // Clamp tests for non-writable file system
   741 	test.Next(_L("T_Clamp - Test4()"));
   742 
   743 	// Tests are limited to clamp, unclamp and denied requests
   744 	// when clamps are present.
   745 	TBuf<256> pathName;	
   746 #ifdef __WINS__
   747 	if((aRoot[0]=='Z')||(aRoot[0]=='z'))
   748 		pathName=_L("clean.txt");
   749 	else
   750 		pathName=_L("root.txt");
   751 #else
   752 	if((aRoot[0]=='Z')||(aRoot[0]=='z'))
   753 		pathName=_L("UnicodeData.txt");
   754 	else
   755 		pathName=_L("\\Test\\clamp.txt");	// For (non-composite) ROFS drive
   756 #endif
   757 	RFile testFile;
   758 	TInt r=testFile.Open(TheFs, pathName, EFileRead);
   759 	test(r==KErrNone);
   760 
   761 	// Clamp file
   762 	RFileClamp handle;
   763 	r=handle.Clamp(testFile);
   764 	test(r==KErrNone);
   765 	TInt64 storedCookie_0=handle.iCookie[0];
   766 	TInt64 storedCookie_1=handle.iCookie[1];
   767 
   768 	// Try to clamp previously-clamped file
   769 	RFileClamp handle1;
   770 	r=handle1.Clamp(testFile);
   771 	test(r==KErrNone);
   772 
   773 	// Unclamp file
   774 	r=handle.Close(TheFs);
   775 	test (r==KErrNone);
   776 	// Check cookie content has been re-initialised
   777 	test((0==handle.iCookie[0])&&(0==handle.iCookie[1]));
   778 
   779 	// Try to unclamp a file that is not clamped
   780 	handle.iCookie[0]=storedCookie_0;
   781 	handle.iCookie[1]=storedCookie_1;
   782 	r=handle.Close(TheFs);
   783 	test (r==KErrNotFound);
   784 	// Remove remaining clamp
   785 	r=handle1.Close(TheFs);
   786 	test (r==KErrNone);
   787 
   788 	testFile.Close();
   789 
   790 	if((aRoot[0]!='Z')&&(aRoot[0]!='z'))	// Can not dismount Z:
   791 		TestDeferredDismount(aRoot,pathName,&handle);
   792 	}
   793 
   794 
   795 LOCAL_C void Test5()
   796 	{
   797 // Clamp requests on non-clamping file systems
   798 	test.Next(_L("T_Clamp - Test5()"));
   799 
   800 	TBuf<256> unsuppFile;	
   801 	unsuppFile = _L("unsuppFile.tst");
   802 	RFile testFile;
   803 	TInt r=testFile.Replace(TheFs,unsuppFile,EFileWrite);
   804 	test(r==KErrNone);
   805 
   806 	// Try to clamp a file on a file system that does
   807 	// not support clamping
   808 	RFileClamp handle;
   809 	r=handle.Clamp(testFile);
   810 	test(r==KErrNotSupported);
   811 
   812 	// Tidy up
   813 	testFile.Close();
   814 	r=TheFs.Delete(_L("unsuppFile.tst"));
   815 	test (r==KErrNone);
   816 	}	
   817 
   818 
   819 LOCAL_C void GetDriveLetters()
   820 	{
   821 // Assign the first drive that matches the required criteria
   822 	test.Next(_L("T_Clamp - GetDriveLetters()"));
   823 
   824 	TDriveList driveList;
   825 	TDriveInfo driveInfo;
   826 	TInt r=TheFs.DriveList(driveList);
   827 	test(r==KErrNone);
   828 	TInt drvNum;
   829 	TBool drivesFound = EFalse;
   830 	for(drvNum=0; (drvNum<KMaxDrives) && !drivesFound; drvNum++)
   831 		{
   832 		TChar drvLetter='?';
   833 		TFileName fileSystem;
   834 		if(!driveList[drvNum])
   835 			continue;
   836 		test(TheFs.Drive(driveInfo, drvNum) == KErrNone);
   837 		test(TheFs.DriveToChar(drvNum,drvLetter) == KErrNone);
   838 		r=TheFs.FileSystemName(fileSystem,drvNum);
   839 		fileSystem.UpperCase();
   840 		test((r==KErrNone)||(r==KErrNotFound));
   841 		if (!(driveInfo.iDriveAtt & KDriveAttInternal))
   842 			continue;
   843 		// Check for FAT on NAND
   844 		if(NandFatDrv=='?')
   845 			{
   846 			if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KFATName)==0))
   847 				NandFatDrv=drvLetter;
   848 			}
   849 		// Check for ROFS
   850 		if(RofsDrv=='?')
   851 			{
   852 			if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KROFSName)==0))
   853 				RofsDrv=drvLetter;
   854 			}
   855 		// Check for LFFS
   856 		if(LffsDrv=='?')
   857 			{
   858 			if((driveInfo.iType==EMediaFlash) && (fileSystem.Compare(KLFFSName)==0))
   859 				LffsDrv=drvLetter;
   860 			}
   861 		// Check for CompFSys
   862 		if(CompDrv=='?')
   863 			{
   864 			if((driveInfo.iType==EMediaRom) && ((fileSystem.Compare(KROMName)==0)||(fileSystem.Compare(KCOMPName)==0)))
   865 				CompDrv=drvLetter;
   866 			}
   867 		drivesFound=((NandFatDrv!='?')&&(RofsDrv!='?')&&(LffsDrv!='?')&&(CompDrv!='?'));
   868 		}
   869 	if(NandFatDrv!='?')
   870 		test((NandFatDrv!=RofsDrv)&&(NandFatDrv!=LffsDrv)&&(NandFatDrv!=CompDrv));
   871 	if(RofsDrv!='?')
   872 		test((RofsDrv!=LffsDrv)&&(RofsDrv!=CompDrv));
   873 	if(LffsDrv!='?')
   874 		test(LffsDrv!=CompDrv);
   875 
   876 	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);
   877 	return;
   878 	}
   879 
   880 
   881 //
   882 // E32Main
   883 //
   884 
   885 TInt E32Main()
   886 	{
   887 	TInt r;
   888 	test.Title();
   889 	test.Start(_L("Starting T_CLAMP ..."));
   890 	test(TheFs.Connect()==KErrNone);
   891 
   892 	GetDriveLetters();
   893 	TBuf<256> pathName;	
   894 
   895 	//************************************************************************
   896 	//
   897 	// Test on FAT (writable file system)
   898 	//
   899 	//************************************************************************
   900 	if(NandFatDrv!='?')
   901 		{
   902 		pathName=_L("?:\\CLAMP-TST\\");	// FAT on NAND
   903 		pathName[0]=(TText)NandFatDrv;
   904 		r=TheFs.MkDirAll(pathName);
   905 		test(r==KErrNone || r== KErrAlreadyExists);
   906 		TheFs.SetSessionPath(pathName);
   907 		test.Printf( _L("T_CLAMP: testing FAT drive on %C\n"),(TText)NandFatDrv);
   908 
   909 		Test1();		// Basic clamp operation
   910 		Test2();		// Invalid clamp requests
   911 		Test3(pathName);// Denied FS requests when files are clamped
   912 
   913 		r=TheFs.RmDir(pathName);
   914 		test(r==KErrNone);
   915 		}
   916 	else
   917 		test.Printf( _L("T_CLAMP: FAT drive not tested\n"));
   918 
   919 	//************************************************************************
   920 	//
   921 	// Test on ROFS (non-writable file system) 
   922 	//
   923 	//************************************************************************
   924 	if(RofsDrv!='?')
   925 		{
   926 		pathName=_L("?:\\");
   927 		pathName[0]=(TText)RofsDrv;
   928 		TheFs.SetSessionPath(pathName);
   929 		test.Printf( _L("T_CLAMP: testing ROFS drive on %C\n"),(TText)RofsDrv);
   930 
   931 		Test4(pathName);	// Clamp tests for non-writable file system
   932 		}
   933 	else
   934 		test.Printf( _L("T_CLAMP: ROFS drive not tested\n"));
   935 
   936 	//************************************************************************
   937 	//
   938 	// Test on Z: - Composite File System, or ROMFS (non-writable file system)
   939 	//
   940 	//************************************************************************
   941 	if(CompDrv!='?')
   942 		{
   943 		pathName=_L("?:\\TEST\\");
   944 		pathName[0]=(TText)CompDrv;
   945 		TheFs.SetSessionPath(pathName);
   946 		test.Printf( _L("T_CLAMP: testing Z drive (on %C)\n"),(TText)CompDrv);
   947 
   948 		Test4(pathName);	// Clamp tests for non-writable file system
   949 		}
   950 	else
   951 		test.Printf( _L("T_CLAMP: Z drive not tested\n"));
   952 
   953 	//************************************************************************
   954 	//
   955 	// Test on LFFS (non-clampable file system)
   956 	//
   957 	//************************************************************************
   958 	if(LffsDrv!='?')
   959 		{
   960 		TBuf<256> unsuppPath;	
   961 		unsuppPath=_L("?:\\CLAMP-TST\\");
   962 		unsuppPath[0]=(TText)LffsDrv;
   963 		r=TheFs.MkDirAll(unsuppPath);
   964 		test(r==KErrNone || r== KErrAlreadyExists);
   965 		TheFs.SetSessionPath(unsuppPath);
   966 		test.Printf( _L("T_CLAMP: testing LFFS drive on %C\n"),(TText)LffsDrv);
   967 
   968 		Test5();		// Clamp requests on non-clamping file systems
   969 		}
   970 	else
   971 		test.Printf( _L("T_CLAMP: LFFS drive not tested\n"));
   972 
   973 	test.End();
   974 	return 0;
   975 	}
   976 
   977 #else
   978 
   979 TInt E32Main()
   980 	{
   981 	test.Title();
   982 	test.Start(_L("Test does not run on UREL builds."));
   983 	test.End();
   984 	return 0;
   985 	}
   986 #endif