os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_checkdisk.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_checkdisk.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,677 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// f32test\server\t_CHECKDISK.cpp
    1.18 +//
    1.19 +//
    1.20 +#define __E32TEST_EXTENSION__
    1.21 +#include <f32file.h>
    1.22 +#include <e32test.h>
    1.23 +//#include <e32svr.h>
    1.24 +//#include <f32dbg.h>
    1.25 +#include "t_server.h"
    1.26 +//#include <e32twin.h>
    1.27 +
    1.28 +RTest test(_L("T_CHECKDISK"));
    1.29 +
    1.30 +RFs TheFs;
    1.31 +TInt gDrive;
    1.32 +TFileName gSessionPath;
    1.33 +TChar gDriveToTest;
    1.34 +
    1.35 +
    1.36 +HBufC8* gBuf = NULL;
    1.37 +TPtr8 gBufReadPtr(NULL, 0);
    1.38 +HBufC8* gBufSec = NULL;
    1.39 +TPtr8 gBufWritePtr(NULL, 0);
    1.40 +
    1.41 +const TInt KOneK = 1024;
    1.42 +const TInt KOneMeg = KOneK * 1024;
    1.43 +const TInt KBlockSize = KOneK * 129 ;
    1.44 +const TInt KWaitRequestsTableSize = 70;
    1.45 +
    1.46 +TInt gBigFileSize = 0;
    1.47 +TInt gSmallFileSize = 0;
    1.48 +TInt64 gMediaSize = 0;
    1.49 +TBool gSkip=EFalse;
    1.50 +TInt writeSize = KBlockSize;
    1.51 +TInt seekSize = 0;
    1.52 +TSeek seekType = ESeekAddress;
    1.53 +TInt reduceSize = 0;
    1.54 +
    1.55 +TTimeIntervalMicroSeconds32 gTimeTakenBigFile(0);
    1.56 +TBuf16<45> gSmallFile, gBigFile;
    1.57 +LOCAL_D TInt gNextFile=0;
    1.58 +TTime gTime1;
    1.59 +TTime gTime2;
    1.60 +
    1.61 +LOCAL_D RSemaphore gSync;
    1.62 +
    1.63 +// Concurrent Threads
    1.64 +RThread gBig;
    1.65 +RThread gSmall;
    1.66 +LOCAL_D RSemaphore client;
    1.67 +LOCAL_D const TInt KHeapSize=0x4000;
    1.68 +LOCAL_D const TInt KMaxHeapSize=0x100000;
    1.69 +TRequestStatus gStatus[KWaitRequestsTableSize];
    1.70 +
    1.71 +enum TTestState
    1.72 +	{
    1.73 +	EThreadWait,
    1.74 +	EThreadSignal,
    1.75 +	ENoThreads
    1.76 +	};
    1.77 +
    1.78 +//
    1.79 +// Generates a name of the form FFFFF*<aPos>.TXT (aLong.3)
    1.80 +//
    1.81 +GLDEF_C void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos)
    1.82 +	{
    1.83 +	TInt padding;
    1.84 +	TInt i=0;
    1.85 +	TBuf16<10> tempbuf;
    1.86 +
    1.87 +	_LIT(KNumber,"%d");
    1.88 +	tempbuf.Format(KNumber,aPos);
    1.89 +	padding=aLong-tempbuf.Size()/2;
    1.90 +	aBuffer=_L("");
    1.91 +	while(i<padding)
    1.92 +		{
    1.93 +		aBuffer.Append('F');
    1.94 +		i++;
    1.95 +		}
    1.96 +	aBuffer.Append(tempbuf);
    1.97 +
    1.98 +	_LIT(KExtension1, ".TXT");
    1.99 +	aBuffer.Append(KExtension1);
   1.100 +	}
   1.101 +
   1.102 +
   1.103 +
   1.104 +
   1.105 +//
   1.106 +// Expects a drive letter as a parameter
   1.107 +//
   1.108 +LOCAL_C void parseCommandLine()
   1.109 +	{
   1.110 +	TBuf<0x100> cmd;
   1.111 +	User::CommandLine(cmd);
   1.112 +	TLex lex(cmd);
   1.113 +	TPtrC token=lex.NextToken();
   1.114 +	TInt r=0;
   1.115 +
   1.116 +	if(token.Length()!=0)
   1.117 +		{
   1.118 +		gDriveToTest=token[0];
   1.119 +		gDriveToTest.UpperCase();
   1.120 +		}
   1.121 +	else
   1.122 +		{
   1.123 +		gDriveToTest='C';
   1.124 +		}
   1.125 +
   1.126 +		r=TheFs.CharToDrive(gDriveToTest,gDrive);
   1.127 +		test_KErrNone(r);
   1.128 +		gSessionPath=_L("?:\\F32-TST\\");
   1.129 +		gSessionPath[0]=(TText)gDriveToTest;
   1.130 +		test.Printf(_L("\nCLP=%S\n"),&token);
   1.131 +	}
   1.132 +
   1.133 +//
   1.134 +// Fills a buffer with character aC
   1.135 +//
   1.136 +LOCAL_C void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
   1.137 +	{
   1.138 +	test (aBuffer.MaxLength() >= aLength);
   1.139 +	for(TInt i=0; i<aLength; i++)
   1.140 +		{
   1.141 +		aBuffer.Append(aC);
   1.142 +		}
   1.143 +	}
   1.144 +
   1.145 +//
   1.146 +// Waits for all the TRequestStatus in status[] to complete
   1.147 +//
   1.148 +LOCAL_C void WaitForAll(TRequestStatus status[], TInt aSize)
   1.149 +	{
   1.150 +	TInt i=0;
   1.151 +
   1.152 +	while(i<aSize)
   1.153 +		{
   1.154 +		User::WaitForRequest(status[i++]);
   1.155 +		}
   1.156 +	}
   1.157 +
   1.158 +
   1.159 +//
   1.160 +// Writes a file synchronously in blocks of aBlockSize size
   1.161 +// this function can be called from another thread, therefore requires its own RTest instance
   1.162 +LOCAL_C TInt WriteFile(RFs& fs, TDes16& aFile, TInt aSize, TInt aBlockSize, TTestState aState)
   1.163 +	{
   1.164 +	RTest test(_L(""));
   1.165 +
   1.166 +	TInt r=0;
   1.167 +	RFile fileWrite;
   1.168 +
   1.169 +	test(aBlockSize>0);				// Block size must be greater than 0
   1.170 +
   1.171 +	if(aState==EThreadWait)
   1.172 +		{
   1.173 +		gSync.Wait();
   1.174 +		}
   1.175 +	r=fileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite);
   1.176 +	test_KErrNone(r);
   1.177 +
   1.178 +	TInt j=0;
   1.179 +	while(j<aSize)
   1.180 +		{
   1.181 +		r=fileWrite.Write(gBufWritePtr, writeSize);
   1.182 +		test_KErrNone(r);
   1.183 +		if(seekType)
   1.184 +			{
   1.185 +			r=fileWrite.Seek(seekType, seekSize);
   1.186 +			test_KErrNone(r);
   1.187 +
   1.188 +			if (writeSize + reduceSize >= 0)
   1.189 +				writeSize += reduceSize;
   1.190 +
   1.191 +			writeSize = Min(writeSize, gBufWritePtr.Length());
   1.192 +
   1.193 +			}
   1.194 +		if((j==0)&&(aState==EThreadSignal))
   1.195 +			{
   1.196 +			gSync.Signal();
   1.197 +			}
   1.198 +		j+=aBlockSize;
   1.199 +		}
   1.200 +
   1.201 +	fileWrite.Close();
   1.202 +
   1.203 +	return KErrNone;
   1.204 +	}
   1.205 +
   1.206 +LOCAL_C void IniStatus(TRequestStatus aStatus[], TInt aSize)
   1.207 +	{
   1.208 +	TInt i=0;
   1.209 +
   1.210 +	while(i<aSize)
   1.211 +		{
   1.212 +		aStatus[i++]=KRequestPending;
   1.213 +		}
   1.214 +	}
   1.215 +
   1.216 +//
   1.217 +// Write big file
   1.218 +// This is a thread function, therefore requires its own RTest instance
   1.219 +LOCAL_C TInt WriteBigFile(TAny* )
   1.220 +	{
   1.221 +	RTest test(_L(""));
   1.222 +	RFs fs;
   1.223 +	TInt r=fs.Connect(gDriveToTest);
   1.224 +	test_KErrNone(r);
   1.225 +
   1.226 +	r=fs.SetSessionPath(gSessionPath);
   1.227 +	test_KErrNone(r);
   1.228 +
   1.229 +	WriteFile(fs, gBigFile, gBigFileSize, KBlockSize, EThreadSignal);
   1.230 +	gTime1.HomeTime();
   1.231 +
   1.232 +	client.Signal();
   1.233 +	return ETrue;
   1.234 +	}
   1.235 +
   1.236 +//
   1.237 +// Writes a file asynchronously in blocks of aBlockSize size
   1.238 +// this function can be called from another thread, therefore requires its own RTest instance
   1.239 +LOCAL_C void WriteFileAsync(RFs& fs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aBlockSize, TRequestStatus aStatus[])
   1.240 +	{
   1.241 +	RTest test(_L(""));
   1.242 +
   1.243 +	TInt r=0;
   1.244 +
   1.245 +	test(aBlockSize>0);				// Block size must be greater than 0
   1.246 +	test((aSize%aBlockSize)==0); 	// Ensure the size of the file is a multiple of the block size
   1.247 +
   1.248 +	r=aFileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite);
   1.249 +	test_KErrNone(r);
   1.250 +
   1.251 +	TInt j=0,i=0;
   1.252 +	while(j<aSize)
   1.253 +		{
   1.254 +		aFileWrite.Write(gBufWritePtr,aStatus[i++]);
   1.255 +		j+=aBlockSize;
   1.256 +		}
   1.257 +	}
   1.258 +
   1.259 +
   1.260 +
   1.261 +//
   1.262 +// Write big file async
   1.263 +// This is a thread function, therefore requires its own RTest instance
   1.264 +LOCAL_C TInt WriteBigFileAsync(TAny* )
   1.265 +	{
   1.266 +	RTest test(_L(""));
   1.267 +	RFs fs;
   1.268 +	TInt r=fs.Connect(gDriveToTest);
   1.269 +	test_KErrNone(r);
   1.270 +
   1.271 +	r=fs.SetSessionPath(gSessionPath);
   1.272 +	test_KErrNone(r);
   1.273 +
   1.274 +
   1.275 +	RFile bigFile;
   1.276 +
   1.277 +	IniStatus(gStatus,KWaitRequestsTableSize);
   1.278 +	WriteFileAsync(fs, bigFile, gSmallFile, gBigFileSize, KBlockSize,gStatus);
   1.279 +	gSync.Signal();
   1.280 +	WaitForAll(gStatus, gBigFileSize/KBlockSize);
   1.281 +
   1.282 +	return ETrue;
   1.283 +	}
   1.284 +
   1.285 +static void TestClientDies()
   1.286 +	{
   1.287 +	test.Next(_L("Client dying unexpectedly"));
   1.288 +
   1.289 +	TInt r=0;
   1.290 +	TBuf<20> unit=_L("?:\\");
   1.291 +	unit[0]=(TText)gDriveToTest;
   1.292 +
   1.293 +	//-------------------------------------------
   1.294 +	test.Printf(_L("Sync test\n"));
   1.295 +
   1.296 +	r=gBig.Create(_L("TEST1"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.297 +	test_KErrNone(r);
   1.298 +
   1.299 +	gBig.Resume();
   1.300 +	gSync.Wait();
   1.301 +
   1.302 +	gBig.Kill(-2);
   1.303 +	gBig.Close();
   1.304 +	User::After(500000);
   1.305 +
   1.306 +	r=TheFs.CheckDisk(unit);
   1.307 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.308 +
   1.309 +	//-------------------------------------------
   1.310 +	test.Printf(_L("Async test\n"));
   1.311 +	r=gSmall.Create(_L("TEST2"),WriteBigFileAsync,KDefaultStackSize*2,KHeapSize,KMaxHeapSize,NULL);
   1.312 +	test_KErrNone(r);
   1.313 +
   1.314 +	gSmall.Resume();
   1.315 +	gSync.Wait();
   1.316 +
   1.317 +	gSmall.Kill(-2);
   1.318 +	gSmall.Close();
   1.319 +	User::After(500000);
   1.320 +
   1.321 +	r=TheFs.CheckDisk(unit);
   1.322 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.323 +
   1.324 +	//-------------------------------------------
   1.325 +	test.Printf(_L("Testing for size not multiple of blocksize\n"));
   1.326 +
   1.327 +	writeSize = 5000;
   1.328 +	r=gBig.Create(_L("TEST3"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.329 +	test_KErrNone(r);
   1.330 +	gBig.Resume();
   1.331 +	gSync.Wait();
   1.332 +
   1.333 +	gBig.Kill(-2);
   1.334 +	gBig.Close();
   1.335 +	User::After(500000);
   1.336 +
   1.337 +	r=TheFs.CheckDisk(unit);
   1.338 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.339 +
   1.340 +	//-------------------------------------------
   1.341 +	test.Printf(_L("Testing with seek current and write inside the file boundary\n"));
   1.342 +
   1.343 +	writeSize = 5000;
   1.344 +	seekType = ESeekCurrent;
   1.345 +	seekSize = -5000;
   1.346 +	reduceSize = -3000;
   1.347 +	r=gBig.Create(_L("TEST4"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.348 +	test_KErrNone(r);
   1.349 +	gBig.Resume();
   1.350 +	gSync.Wait();
   1.351 +
   1.352 +	gBig.Kill(-2);
   1.353 +	gBig.Close();
   1.354 +	User::After(500000);
   1.355 +
   1.356 +	r=TheFs.CheckDisk(unit);
   1.357 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.358 +
   1.359 +	//-------------------------------------------
   1.360 +	test.Printf(_L("Testing with seek current and overwrite entire file\n"));
   1.361 +	writeSize = 5000;
   1.362 +	seekType = ESeekCurrent;
   1.363 +	seekSize = -5000;
   1.364 +	reduceSize = 0;
   1.365 +	r=gBig.Create(_L("TEST5"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.366 +	test_KErrNone(r);
   1.367 +	gBig.Resume();
   1.368 +	gSync.Wait();
   1.369 +
   1.370 +	gBig.Kill(-2);
   1.371 +	gBig.Close();
   1.372 +	User::After(500000);
   1.373 +
   1.374 +	r=TheFs.CheckDisk(unit);
   1.375 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.376 +
   1.377 +	//-------------------------------------------
   1.378 +	test.Printf(_L("Testing with seek current and write outside the file boundary\n"));
   1.379 +
   1.380 +	writeSize = 5000;
   1.381 +	seekType = ESeekCurrent;
   1.382 +	seekSize = -5000;
   1.383 +	reduceSize = 5000;
   1.384 +	r=gBig.Create(_L("TEST6"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.385 +	test_KErrNone(r);
   1.386 +	gBig.Resume();
   1.387 +	gSync.Wait();
   1.388 +
   1.389 +	gBig.Kill(-2);
   1.390 +	gBig.Close();
   1.391 +	User::After(500000);
   1.392 +
   1.393 +	r=TheFs.CheckDisk(unit);
   1.394 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.395 +
   1.396 +	//-------------------------------------------
   1.397 +	test.Printf(_L("Testing with seek current and write within the file boundary\n"));
   1.398 +	writeSize = 5000;
   1.399 +	seekType = ESeekCurrent;
   1.400 +	seekSize = -3000;
   1.401 +	reduceSize = -4000;
   1.402 +	r=gBig.Create(_L("TEST7"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.403 +	test_KErrNone(r);
   1.404 +	gBig.Resume();
   1.405 +	gSync.Wait();
   1.406 +
   1.407 +	gBig.Kill(-2);
   1.408 +	gBig.Close();
   1.409 +	User::After(500000);
   1.410 +
   1.411 +	r=TheFs.CheckDisk(unit);
   1.412 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.413 +
   1.414 +	//-------------------------------------------
   1.415 +	test.Printf(_L("Testing with seek current and write exactly to file size\n"));
   1.416 +	writeSize = 5000;
   1.417 +	seekType = ESeekCurrent;
   1.418 +	seekSize = -3000;
   1.419 +	reduceSize = -3000;
   1.420 +	r=gBig.Create(_L("TEST8"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.421 +	test_KErrNone(r);
   1.422 +	gBig.Resume();
   1.423 +	gSync.Wait();
   1.424 +
   1.425 +	gBig.Kill(-2);
   1.426 +	gBig.Close();
   1.427 +	User::After(500000);
   1.428 +
   1.429 +	r=TheFs.CheckDisk(unit);
   1.430 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.431 +
   1.432 +	//-------------------------------------------
   1.433 +	test.Printf(_L("Testing with seek current and write greater than file size\n"));
   1.434 +	writeSize = 5000;
   1.435 +	seekType = ESeekCurrent;
   1.436 +	seekSize = -3000;
   1.437 +	reduceSize = 10000;
   1.438 +	r=gBig.Create(_L("TEST9"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   1.439 +	test_KErrNone(r);
   1.440 +	gBig.Resume();
   1.441 +	gSync.Wait();
   1.442 +
   1.443 +	gBig.Kill(-2);
   1.444 +	gBig.Close();
   1.445 +	User::After(500000);
   1.446 +
   1.447 +	r=TheFs.CheckDisk(unit);
   1.448 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.449 +
   1.450 +	TInt retries = 0;
   1.451 +
   1.452 +	do
   1.453 +		{
   1.454 +		r=TheFs.ScanDrive(unit);
   1.455 +		if (r != KErrNone)
   1.456 +			test.Printf(_L("ScanDrive() returned %d\n"), r);
   1.457 +		if (r == KErrInUse)
   1.458 +			User::After(500000);
   1.459 +		}
   1.460 +	while (r == KErrInUse && ++retries < 5);
   1.461 +
   1.462 +	test_Value(r, r == KErrNone || r == KErrNotSupported);
   1.463 +
   1.464 +	}
   1.465 +
   1.466 +
   1.467 +//---------------------------------------------------------------------
   1.468 +/**
   1.469 +    Test that CheckDisk will not cause stack overflow on very deep directory structure.
   1.470 +*/
   1.471 +void TestCheckDisk_VeryDeepDirectory()
   1.472 +	{
   1.473 +	test.Next(_L("Testing deep dir structure check"));
   1.474 +
   1.475 +	TInt nRes;
   1.476 +	TBuf<20> unit=_L("?:\\");
   1.477 +	unit[0]=(TText)gDriveToTest;
   1.478 +
   1.479 +	//-- 1. create deep dir structure, like \\0\\1\\2\\...... 90 levels deep
   1.480 +	const TInt KMaxDirDepth = 90;
   1.481 +
   1.482 +	test.Printf(_L("Creating directory with %d subdirs.\n"),KMaxDirDepth);
   1.483 +
   1.484 +	TFileName fn;
   1.485 +	for(TInt i=0; i<KMaxDirDepth; ++i)
   1.486 +		{
   1.487 +		fn.AppendFormat(_L("\\%d"), i%10);
   1.488 +		}
   1.489 +	fn.Append(_L("\\"));
   1.490 +
   1.491 +	nRes = TheFs.MkDirAll(fn);
   1.492 +	test_Value(nRes, nRes == KErrNone || nRes == KErrAlreadyExists);
   1.493 +
   1.494 +	//-- 2. invoke Check Disk and ensure that target doesn't die from stack overflow.
   1.495 +	test.Printf(_L("Running Check Disk...\n"));
   1.496 +	nRes = TheFs.CheckDisk(unit);
   1.497 +
   1.498 +	test_Value(nRes, nRes == KErrNone || nRes == KErrTooBig);
   1.499 +	}
   1.500 +
   1.501 +
   1.502 +//---------------------------------------------------------------------
   1.503 +//
   1.504 +// This test tries to read a small file while writing a big one
   1.505 +//
   1.506 +GLDEF_C void CallTestsL()
   1.507 +	{
   1.508 +	TBuf16<45> dir;
   1.509 +
   1.510 +	test.Next(_L("Preparing the environmnet\n"));
   1.511 +
   1.512 +	FileNameGen(gSmallFile, 8, gNextFile++);
   1.513 +	FileNameGen(gBigFile, 8, gNextFile++);
   1.514 +	dir=gSessionPath;
   1.515 +	dir.Append(gSmallFile);
   1.516 +	gSmallFile=dir;
   1.517 +	dir=gSessionPath;
   1.518 +	dir.Append(gBigFile);
   1.519 +	gBigFile=dir;
   1.520 +
   1.521 +	TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1));
   1.522 +	test(res == KErrNone && gBuf != NULL);
   1.523 +
   1.524 +	gBufWritePtr.Set(gBuf->Des());
   1.525 +	FillBuffer(gBufWritePtr, KBlockSize, 'B');
   1.526 +
   1.527 +	TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1));
   1.528 +	test(res2 == KErrNone && gBufSec != NULL);
   1.529 +	gBufReadPtr.Set(gBufSec->Des());
   1.530 +
   1.531 +	//---------------------------
   1.532 +
   1.533 +	TestClientDies();
   1.534 +	TestCheckDisk_VeryDeepDirectory();
   1.535 +
   1.536 +	delete gBuf;
   1.537 +	delete gBufSec;
   1.538 +	}
   1.539 +
   1.540 +LOCAL_C void DoTests()
   1.541 +	{
   1.542 + 	TInt r=0;
   1.543 +
   1.544 + 	r=client.CreateLocal(0);
   1.545 +	test_KErrNone(r);
   1.546 +
   1.547 +  	r=gSync.CreateLocal(0);
   1.548 +	test_KErrNone(r);
   1.549 +
   1.550 +	r=TheFs.SetSessionPath(gSessionPath);
   1.551 +	test_KErrNone(r);
   1.552 +
   1.553 +	r=TheFs.MkDirAll(gSessionPath);
   1.554 +	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
   1.555 +
   1.556 +	TheFs.ResourceCountMarkStart();
   1.557 +	TRAP(r,CallTestsL());
   1.558 +	test_KErrNone(r);
   1.559 +	TheFs.ResourceCountMarkEnd();
   1.560 +	}
   1.561 +
   1.562 +TBool CheckForDiskSize()
   1.563 +	{
   1.564 +	TVolumeInfo volInfo;
   1.565 +	TInt r = TheFs.Volume(volInfo, gDrive);
   1.566 +	test_KErrNone(r);
   1.567 +
   1.568 +	gMediaSize = volInfo.iSize;
   1.569 +	gSmallFileSize = KBlockSize;
   1.570 +	gBigFileSize = KBlockSize*20;
   1.571 +	while(((2*gBigFileSize)+KOneMeg) > gMediaSize )
   1.572 +		{
   1.573 +			gBigFileSize -= (2*KBlockSize);
   1.574 +		}
   1.575 +
   1.576 +	if(gBigFileSize< (3*gSmallFileSize))
   1.577 +		return EFalse;
   1.578 +	else
   1.579 +		return ETrue;
   1.580 +	}
   1.581 +
   1.582 +void Format(TInt aDrive)
   1.583 +	{
   1.584 +
   1.585 +	test.Next(_L("Format"));
   1.586 +	TBuf<4> driveBuf=_L("?:\\");
   1.587 +	driveBuf[0]=(TText)(aDrive+'A');
   1.588 +	RFormat format;
   1.589 +	TInt count;
   1.590 +	TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
   1.591 +	test_KErrNone(r);
   1.592 +
   1.593 +	while(count)
   1.594 +		{
   1.595 +		TInt r=format.Next(count);
   1.596 +		test_KErrNone(r);
   1.597 +		}
   1.598 +	format.Close();
   1.599 +	}
   1.600 +
   1.601 +
   1.602 +static TBool IsFAT(RFs &aFsSession, TInt aDrive)
   1.603 +{
   1.604 +	_LIT(KFatName, "Fat");
   1.605 +
   1.606 +	TFileName f;
   1.607 +	TInt r = aFsSession.FileSystemName(f, aDrive);
   1.608 +	test_Value(r, r == KErrNone || r == KErrNotFound);
   1.609 +	return (f.CompareF(KFatName) == 0);
   1.610 +}
   1.611 +
   1.612 +
   1.613 +GLDEF_C TInt E32Main()
   1.614 +	{
   1.615 +
   1.616 +	CTrapCleanup* cleanup;
   1.617 +	cleanup=CTrapCleanup::New();
   1.618 +
   1.619 +	__UHEAP_MARK;
   1.620 +	test.Title();
   1.621 +	test.Start(_L("Starting tests..."));
   1.622 +	parseCommandLine();
   1.623 +
   1.624 +	TInt r = TheFs.Connect();
   1.625 +	test_KErrNone(r);
   1.626 +
   1.627 +	TDriveInfo info;
   1.628 +	TVolumeInfo volInfo;
   1.629 +	r=TheFs.Drive(info,gDrive);
   1.630 +	test_KErrNone(r);
   1.631 +
   1.632 +	if(info.iMediaAtt&KMediaAttVariableSize)
   1.633 +		{// Not testing in RAM Drives
   1.634 +		test.Printf(_L("Tests skipped in RAM drive\n"));
   1.635 +		goto out;
   1.636 +        }
   1.637 +
   1.638 +	r = TheFs.Volume(volInfo, gDrive);
   1.639 +	if (r == KErrNotReady)
   1.640 +		{
   1.641 +		if (info.iType == EMediaNotPresent)
   1.642 +			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
   1.643 +		else
   1.644 +			test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType);
   1.645 +		}
   1.646 +	else if (r == KErrCorrupt)
   1.647 +		{
   1.648 +		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
   1.649 +		}
   1.650 +	test_KErrNone(r);
   1.651 +
   1.652 +	if(!IsFAT(TheFs, gDrive))
   1.653 +        {
   1.654 +		test.Printf(_L("Tests skipped on non-FAT drive\n"));
   1.655 +		goto out;
   1.656 +        }
   1.657 +
   1.658 +	if ((volInfo.iDrive.iMediaAtt & KMediaAttFormattable))
   1.659 +		Format(gDrive);
   1.660 +
   1.661 +	if(CheckForDiskSize())
   1.662 +		{
   1.663 +		DoTests();
   1.664 +		if ((volInfo.iDrive.iMediaAtt & KMediaAttFormattable))
   1.665 +		   Format(gDrive);
   1.666 +		}
   1.667 +	else
   1.668 +		{
   1.669 +		test.Printf(_L("Skipping tests due to lack of space to perform them in this unit\n"));
   1.670 +		}
   1.671 +out:
   1.672 +	test.End();
   1.673 +
   1.674 +	TheFs.Close();
   1.675 +	test.Close();
   1.676 +
   1.677 +	__UHEAP_MARKEND;
   1.678 +	delete cleanup;
   1.679 +	return(KErrNone);
   1.680 +    }