os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_tscan32.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_tscan32.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2055 @@
     1.4 +// Copyright (c) 1998-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\scndrv\t_tscan32.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <f32file.h>
    1.22 +#include <e32test.h>
    1.23 +
    1.24 +#include "t_server.h"
    1.25 +
    1.26 +#include "fat_utils.h"
    1.27 +using namespace Fat_Test_Utils;
    1.28 +
    1.29 +/*
    1.30 +Series of tests to check that the combination of a ruggedised fat file
    1.31 +system and scandisk prevents the file system from becoming corrupt in the
    1.32 +event of a power failure. CheckDisk is used to test that directory
    1.33 +structure is not corrupt. This test is only suitable with a drive that uses
    1.34 +the fat file system but not the internal ram drive (due to the indirection)
    1.35 +table. Only works with debug builds due to RFs::ControlIo only debug function
    1.36 +*/
    1.37 +
    1.38 +GLDEF_D TFileName StartupExeName=_L(""); // initialised at run time
    1.39 +
    1.40 +#ifdef _DEBUG
    1.41 +GLREF_D RTest test;
    1.42 +GLDEF_D TInt TheFunctionNumber;
    1.43 +GLDEF_D TInt TheOpNumber;
    1.44 +GLDEF_D TInt TheFailCount;
    1.45 +GLDEF_D TBool IsReset;
    1.46 +GLDEF_D TFileName TestExeName=_L("?:\\T_SCANDR.EXE"); //Renaming it to fit in one root dir entry.
    1.47 +GLDEF_D TFileName LogFileName=_L("?:\\T_SCANDR.LOG"); //Renaming it to fit in one root dir entry.
    1.48 +
    1.49 +const TInt KControlIoWriteFailOn=0;		// commands to pass into RFs::ControlIo
    1.50 +const TInt KControlIoWriteFailOff=1;
    1.51 +const TInt KMaxFatEntries  = 2048;
    1.52 +const TInt KDirAttrReadOnly  = 0x01;
    1.53 +const TInt KDirAttrHidden    = 0x02;
    1.54 +const TInt KDirAttrSystem    = 0x04;
    1.55 +const TInt KDirAttrVolumeId  = 0x08;
    1.56 +const TInt KDirAttrDirectory = 0x10;
    1.57 +const TInt KDirAttrArchive   = 0x20;
    1.58 +const TInt KDirAttrLongName  = KDirAttrReadOnly | KDirAttrHidden | KDirAttrSystem | KDirAttrVolumeId;
    1.59 +const TInt KDirAttrLongMask  = KDirAttrLongName | KDirAttrDirectory | KDirAttrArchive;
    1.60 +const TInt KDirLastLongEntry = 0x40;
    1.61 +
    1.62 +GLDEF_D TInt WriteFailValue;
    1.63 +
    1.64 +LOCAL_C TFatBootSector BootSector;	
    1.65 +LOCAL_D RRawDisk TheRawDisk;
    1.66 +
    1.67 +static TFatType gDiskType = EInvalid;
    1.68 +
    1.69 +LOCAL_D TInt gTotalSectors;
    1.70 +LOCAL_D TInt gBytesPerCluster;
    1.71 +LOCAL_D TInt gRootDirSectors;
    1.72 +LOCAL_D TInt gRootDirEntries;
    1.73 +LOCAL_D TInt gRootDirStart;
    1.74 +LOCAL_D TInt gRootSector;
    1.75 +LOCAL_D TInt gFatStartBytes;
    1.76 +LOCAL_D TInt gFatTestEntries;
    1.77 +LOCAL_D TInt gFatSizeSectors;
    1.78 +LOCAL_D TInt gFirstDataSector;
    1.79 +LOCAL_D TInt gDataStartBytes;
    1.80 +LOCAL_D TInt gClusterCount;
    1.81 +
    1.82 +LOCAL_D HBufC8* gFatBuf  = NULL;
    1.83 +LOCAL_D TInt    gFatAddr = -1;
    1.84 +
    1.85 +enum TFatChain {EChainStd,EChainAlternate,EChainBackwards,EChainForwards};
    1.86 +
    1.87 +LOCAL_C TBool IsInternalRam()
    1.88 +//
    1.89 +// Returns true if the selected drive is variable size (i.e. RAM drive)
    1.90 +//
    1.91 +	{
    1.92 +	TVolumeInfo v;
    1.93 +	TInt r=TheFs.Volume(v,gSessionPath[0]-'A');
    1.94 +	test(r==KErrNone);
    1.95 +	return(v.iDrive.iMediaAtt&KMediaAttVariableSize);
    1.96 +	}
    1.97 +
    1.98 +LOCAL_C void WriteLogFile()
    1.99 +//
   1.100 +// Writes state of test to end of LogFileName
   1.101 +//
   1.102 +	{
   1.103 +	test.Printf(_L("Writelogfile()\n"));
   1.104 +	RFile log;
   1.105 +	TInt r=log.Open(TheFs,LogFileName,EFileShareExclusive|EFileWrite);
   1.106 +	if(r!=KErrNone)
   1.107 +		test.Printf(_L("error=%d\n"),r);
   1.108 +	test(r==KErrNone);
   1.109 +	TInt size;
   1.110 +	r=log.Size(size);
   1.111 +	test(r==KErrNone);
   1.112 +	TBuf8<16> buf;
   1.113 +	buf.SetLength(4);
   1.114 +	buf[0]=(TUint8)TheFunctionNumber;
   1.115 +	buf[1]=(TUint8)TheOpNumber;
   1.116 +	buf[2]=(TUint8)TheFailCount;
   1.117 +	buf[3]='\n';
   1.118 +	r=log.Write(size,buf,buf.Length());
   1.119 +	test(r==KErrNone);
   1.120 +	test.Printf(_L("Written func=%d,op=%d,fail=%d\n"),TheFunctionNumber,TheOpNumber,TheFailCount);
   1.121 +	log.Close();
   1.122 +	}
   1.123 +
   1.124 +LOCAL_C TInt SetWriteFailOn(TInt aFailCount)
   1.125 +//
   1.126 +// Sets write to metadata to fail on aFailCount with WriteFailValue
   1.127 +//
   1.128 +	{
   1.129 +	TInt16 args[2];
   1.130 +	TPtr8 des((TUint8*)args,4,4);
   1.131 +	args[0]=(TUint16)aFailCount;
   1.132 +	args[1]=(TUint16)WriteFailValue;
   1.133 +	TInt r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOn,des);
   1.134 +	return(r);
   1.135 +	}
   1.136 +
   1.137 +GLDEF_C void ReadLogFile()
   1.138 +//
   1.139 +// Reads state of test from end of LogFileName and sets global variables
   1.140 +//
   1.141 +	{
   1.142 +	test.Next(_L("ReadLogFile"));
   1.143 +	RFile log;
   1.144 +	TInt r=log.Open(TheFs,LogFileName,EFileShareExclusive);
   1.145 +	if(r!=KErrNone)
   1.146 +		test.Printf(_L("error in ReadLogFile()=%d\n"),r);
   1.147 +	test(r==KErrNone);
   1.148 +	test(r==KErrNone);
   1.149 +	TInt fileSize;
   1.150 +	r=log.Size(fileSize);
   1.151 +	if(fileSize==0)
   1.152 +		{
   1.153 +		TheFunctionNumber=0;
   1.154 +		TheOpNumber=0;
   1.155 +		TheFailCount=0;
   1.156 +		}
   1.157 +	else
   1.158 +		{
   1.159 +		TBuf8<4> buf;
   1.160 +		r=log.Read(fileSize-4,buf,4);
   1.161 +		TheFunctionNumber=buf[0];
   1.162 +		TheOpNumber=buf[1];
   1.163 +		TheFailCount=buf[2];
   1.164 +		}
   1.165 +	log.Close();
   1.166 +	test.Printf(_L("func=%d,op=%d,fail=%d\n"),TheFunctionNumber,TheOpNumber,TheFailCount);
   1.167 +	}
   1.168 +
   1.169 +LOCAL_C TUint32 MaxClusters()
   1.170 +	//
   1.171 +	// Return the number of data clusters on the disk
   1.172 +	//
   1.173 +	{
   1.174 +	TUint32 totSec = (BootSector.TotalSectors() ? BootSector.TotalSectors() : BootSector.HugeSectors());
   1.175 +	TUint32 numSec = totSec - gFirstDataSector;
   1.176 +	return numSec / BootSector.SectorsPerCluster();
   1.177 +	}
   1.178 +
   1.179 +LOCAL_C TInt ClusterToByte(TInt aCluster)
   1.180 +	//
   1.181 +	// converts cluster number to byte offset on disk
   1.182 +	//
   1.183 +	{
   1.184 +	TInt sector = (aCluster - 2) * gBytesPerCluster + gFirstDataSector * BootSector.BytesPerSector();
   1.185 +	return sector;
   1.186 +	}
   1.187 +
   1.188 +/**
   1.189 +    Fill media with zeroes from aStartPos to aEndPos
   1.190 +*/
   1.191 +static void DoZeroFillMedia(TInt64 aStartPos, TInt64 aEndPos, RRawDisk& aWriter)
   1.192 +{
   1.193 +    test(aStartPos >=0 && aEndPos >=0 && aStartPos < aEndPos);
   1.194 +    
   1.195 +    if(aStartPos == aEndPos)
   1.196 +        return;
   1.197 +
   1.198 +    RBuf8 buf;
   1.199 +    TInt  nRes;  
   1.200 +
   1.201 +    const TUint32 KBufSz=65536*2; //-- buffer with zeroes
   1.202 +    
   1.203 +    nRes = buf.CreateMax(KBufSz);
   1.204 +    test(nRes == KErrNone);
   1.205 +
   1.206 +    buf.FillZ();
   1.207 +
   1.208 +    TUint32 rem = (TUint32)(aEndPos - aStartPos);
   1.209 +    while(rem)
   1.210 +    {
   1.211 +        const TUint32 bytesToWrite=Min(rem, KBufSz);
   1.212 +    
   1.213 +        TPtrC8 ptr(buf.Ptr(), bytesToWrite);
   1.214 +        nRes = aWriter.Write(aStartPos, ptr);
   1.215 +        test(nRes == KErrNone || nRes == KErrDiskFull);
   1.216 +
   1.217 +        aStartPos+=bytesToWrite;
   1.218 +        rem-=bytesToWrite;
   1.219 +    }
   1.220 +
   1.221 +
   1.222 +    buf.Close();
   1.223 +}
   1.224 +
   1.225 +//
   1.226 +// Clear the disk data area to a known value which won't be confused with
   1.227 +// directory entries etc.
   1.228 +//
   1.229 +LOCAL_C void ClearDiskData()
   1.230 +	{
   1.231 +
   1.232 +	TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
   1.233 +	test(r==KErrNone);
   1.234 +
   1.235 +	TUint32 startPos = gDataStartBytes;
   1.236 +	if (gDiskType == EFat32)
   1.237 +		startPos += gBytesPerCluster;
   1.238 +
   1.239 +    const TUint32 endPos = startPos + gFatTestEntries*gBytesPerCluster;
   1.240 +
   1.241 +    test.Printf(_L("ClearDiskData() from pos:%u to pos:%u\n"), startPos, endPos);
   1.242 +
   1.243 +    DoZeroFillMedia(startPos, endPos, TheRawDisk);
   1.244 +
   1.245 +	TheRawDisk.Close();
   1.246 +	}
   1.247 +
   1.248 +LOCAL_C TInt PosInBytes(TInt aFatIndex)
   1.249 +//
   1.250 +// Return number of bytes into the FAT
   1.251 +//
   1.252 +	{
   1.253 +	TInt fatPosInBytes = -1;
   1.254 +	switch (gDiskType)
   1.255 +		{
   1.256 +		case EFat32:
   1.257 +			fatPosInBytes=aFatIndex<<2;
   1.258 +			break;
   1.259 +		case EFat16:
   1.260 +			fatPosInBytes=aFatIndex<<1;
   1.261 +			break;
   1.262 +		case EFat12:
   1.263 +			fatPosInBytes=(aFatIndex*3>>1);
   1.264 +			break;
   1.265 +		default:
   1.266 +			test(0);
   1.267 +		}
   1.268 +	return(fatPosInBytes);
   1.269 +	}
   1.270 +
   1.271 +static void DoReadBootSector()
   1.272 +	{
   1.273 +	
   1.274 +    TInt nRes = ReadBootSector(TheFs, CurrentDrive(), KBootSectorNum<<KDefaultSectorLog2, BootSector);
   1.275 +    test(nRes == KErrNone);
   1.276 +
   1.277 +    if(!BootSector.IsValid())
   1.278 +        {
   1.279 +        test.Printf(_L("Wrong bootsector! Dump:\n"));
   1.280 +        BootSector.PrintDebugInfo();
   1.281 +        test(0);
   1.282 +        }
   1.283 +	// Calculate derived variables (fixed for a particular disk format)
   1.284 +	gBytesPerCluster   = BootSector.BytesPerSector() * BootSector.SectorsPerCluster();
   1.285 +	gRootDirSectors    = ((BootSector.RootDirEntries() * KSizeOfFatDirEntry + BootSector.BytesPerSector() - 1) / BootSector.BytesPerSector());
   1.286 +	gFatStartBytes     = BootSector.ReservedSectors() * BootSector.BytesPerSector();
   1.287 +	gFatSizeSectors    = (BootSector.FatSectors() ? BootSector.FatSectors() : BootSector.FatSectors32());
   1.288 +	gRootSector        = BootSector.ReservedSectors() + BootSector.NumberOfFats() * gFatSizeSectors;
   1.289 +	gRootDirStart      = gRootSector * BootSector.BytesPerSector();
   1.290 +	gFirstDataSector   = gRootSector + gRootDirSectors;
   1.291 +
   1.292 +	gFatTestEntries = MaxClusters();
   1.293 +	if (gFatTestEntries > KMaxFatEntries)
   1.294 +		gFatTestEntries = KMaxFatEntries;
   1.295 +
   1.296 +	if (BootSector.RootDirEntries() == 0)
   1.297 +		{
   1.298 +		test.Printf(_L("**** Is Fat32\n"));
   1.299 +		gDiskType = EFat32;
   1.300 +		gRootDirEntries = BootSector.RootDirEntries();
   1.301 +		}
   1.302 +	else if (BootSector.FatType() == EFat16)
   1.303 +		{
   1.304 +		test.Printf(_L("**** Is Fat16\n"));
   1.305 +		gDiskType = EFat16;
   1.306 +		gRootDirEntries = BootSector.RootDirEntries();
   1.307 +		}
   1.308 +	else
   1.309 +		{
   1.310 +		test.Printf(_L("**** Is Fat12\n"));
   1.311 +		gDiskType = EFat12;
   1.312 +		gRootDirEntries = gBytesPerCluster * 1 / KSizeOfFatDirEntry;
   1.313 +		}
   1.314 +	gTotalSectors   = (BootSector.TotalSectors() ? BootSector.TotalSectors() : BootSector.HugeSectors());
   1.315 +	gClusterCount   = (gTotalSectors - gFirstDataSector) / BootSector.SectorsPerCluster();
   1.316 +	gDataStartBytes = gFirstDataSector * BootSector.BytesPerSector();
   1.317 +	}
   1.318 +
   1.319 +GLDEF_C TUint32 GetFatEntry(TUint32 aIndex, const TUint8* aFat=NULL)
   1.320 +//
   1.321 +// Read a single FAT entry from disk or FAT copy and return it
   1.322 +//
   1.323 +	{
   1.324 +
   1.325 +
   1.326 +	if (!gFatBuf)
   1.327 +		{
   1.328 +		gFatBuf=HBufC8::New(gBytesPerCluster);
   1.329 +		test(gFatBuf!=NULL);
   1.330 +		gFatAddr = -1;
   1.331 +		}
   1.332 +
   1.333 +	const TUint8* ptr;
   1.334 +
   1.335 +	if (aFat)
   1.336 +		{
   1.337 +		ptr = (TUint8*)aFat + PosInBytes(aIndex);
   1.338 +		}
   1.339 +	else
   1.340 +		{
   1.341 +		TInt pos = PosInBytes(aIndex) + gFatStartBytes;
   1.342 +		if (gFatAddr < 0 || pos < gFatAddr || pos >= gFatAddr + gBytesPerCluster)
   1.343 +			{
   1.344 +			TPtr8 ptr=gFatBuf->Des();
   1.345 +		TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
   1.346 +			test(r==KErrNone);
   1.347 +			r=TheRawDisk.Read(pos, ptr);
   1.348 +			test(r==KErrNone);
   1.349 +			TheRawDisk.Close();
   1.350 +			gFatAddr = pos;
   1.351 +			}
   1.352 +		ptr = gFatBuf->Ptr() + pos-gFatAddr;
   1.353 +		}
   1.354 +
   1.355 +	TUint32 val = 0;
   1.356 +	switch (gDiskType)
   1.357 +		{
   1.358 +		case EFat32:
   1.359 +			val = *(TUint32*)ptr;
   1.360 +			break;
   1.361 +		case EFat16:
   1.362 +			val = *(TUint16*)ptr;
   1.363 +			break;
   1.364 +		case EFat12:
   1.365 +			val = *(TUint16*)ptr;
   1.366 +			if (aIndex & 1)
   1.367 +				val >>= 4;
   1.368 +			val &= 0xFFF;
   1.369 +			break;
   1.370 +		default:
   1.371 +			test(0);
   1.372 +		}
   1.373 +	return val;
   1.374 +	}
   1.375 +
   1.376 +GLDEF_C void DumpBootSector()
   1.377 +//
   1.378 +// Display (in log) TFatBootSector structure
   1.379 +//
   1.380 +	{
   1.381 +	RDebug::Print(_L("iBytesPerSector    = %8d"), BootSector.BytesPerSector());
   1.382 +	RDebug::Print(_L("iSectorsPerCluster = %8d"), BootSector.SectorsPerCluster());
   1.383 +	RDebug::Print(_L("iReservedSectors   = %8d"), BootSector.ReservedSectors());
   1.384 +	RDebug::Print(_L("iNumberOfFats      = %8d"), BootSector.NumberOfFats());
   1.385 +	RDebug::Print(_L("iRootDirEntries    = %8d"), BootSector.RootDirEntries());
   1.386 +	RDebug::Print(_L("iTotalSectors      = %8d"), BootSector.TotalSectors());
   1.387 +	RDebug::Print(_L("iMediaDescriptor   = %8d"), BootSector.MediaDescriptor());
   1.388 +	RDebug::Print(_L("iFatSectors        = %8d"), BootSector.FatSectors());
   1.389 +	RDebug::Print(_L("iSectorsPerTrack   = %8d"), BootSector.SectorsPerTrack());
   1.390 +	RDebug::Print(_L("iNumberOfHeads     = %8d"), BootSector.NumberOfHeads());
   1.391 +	RDebug::Print(_L("iHiddenSectors     = %8d"), BootSector.HiddenSectors());
   1.392 +	RDebug::Print(_L("iHugeSectors       = %8d"), BootSector.HugeSectors());
   1.393 +
   1.394 +	//New for FAT32
   1.395 +
   1.396 +	if(BootSector.RootDirEntries() == 0)	//indicates we have FAT32 volume
   1.397 +		{
   1.398 +		RDebug::Print(_L("FatSectors32      = %8d"), BootSector.FatSectors32());
   1.399 +		RDebug::Print(_L("FATFlags          = %8d"), BootSector.FATFlags());
   1.400 +		RDebug::Print(_L("VersionNumber     = %8d"), BootSector.VersionNumber());
   1.401 +		RDebug::Print(_L("RootClusterNum    = %8d (0x%08X)"), BootSector.RootClusterNum(), gRootDirStart);
   1.402 +		RDebug::Print(_L("FSInfoSectorNum   = %8d (0x%08X)"), BootSector.FSInfoSectorNum(), BootSector.FSInfoSectorNum() * BootSector.BytesPerSector());
   1.403 +		RDebug::Print(_L("BkBootRecSector   = %8d (0x%08X)"), BootSector.BkBootRecSector(), BootSector.BkBootRecSector() * BootSector.BytesPerSector());
   1.404 +		}
   1.405 +	TInt fatEntries = gFatSizeSectors*BootSector.BytesPerSector();
   1.406 +	switch (gDiskType)
   1.407 +		{
   1.408 +		case EFat32:
   1.409 +			fatEntries /= 4;
   1.410 +			break;
   1.411 +		case EFat16:
   1.412 +			fatEntries /= 2;
   1.413 +			break;
   1.414 +		case EFat12:
   1.415 +			fatEntries *= 3;
   1.416 +			fatEntries /= 2;
   1.417 +			break;
   1.418 +		default:
   1.419 +			test(0);
   1.420 +		}
   1.421 +	RDebug::Print(_L("ClusterCount      = %8d (%d bytes)"), gClusterCount, gClusterCount*gBytesPerCluster);
   1.422 +	RDebug::Print(_L("FatEntries        = %8d (%d sectors)"), fatEntries, gFatSizeSectors);
   1.423 +	RDebug::Print(_L("RootSector        = %8d (0x%08X)"), gRootSector, gRootDirStart);
   1.424 +	RDebug::Print(_L("FirstDataSector   = %8d (0x%08X)"), gFirstDataSector, gDataStartBytes);
   1.425 +	}
   1.426 +
   1.427 +GLDEF_C void DumpFat(const TUint8* aFat=NULL)
   1.428 +// 
   1.429 +// Dump to the log all those FAT entries which are non-zero
   1.430 +//
   1.431 +	{
   1.432 +	TInt32 max = MaxClusters();
   1.433 +	if (max > KMaxFatEntries)
   1.434 +		max = KMaxFatEntries;
   1.435 +	RDebug::Print(_L("---------------- DUMP OF FAT ---------------"));
   1.436 +	for (TInt32 i = 0; i < max; i++)
   1.437 +		{
   1.438 +		TInt32 val = GetFatEntry(i, aFat);
   1.439 +		TInt32 msk = 0x0FFFFFFF;
   1.440 +		switch (gDiskType)
   1.441 +			{
   1.442 +			case EFat32:
   1.443 +				msk = 0x0FFFFFFF;
   1.444 +				break;
   1.445 +			case EFat16:
   1.446 +				msk = 0xFFFF;
   1.447 +				break;
   1.448 +			case EFat12:
   1.449 +				msk = 0x0FFF;
   1.450 +				break;
   1.451 +			default:
   1.452 +				test(0);
   1.453 +			}
   1.454 +		if ((val & msk) == (0x0FFFFFFF & msk))
   1.455 +			RDebug::Print(_L("    %8d -> EOC"), i);
   1.456 +		else if ((val & msk) == (0x0FFFFFF8 & msk))
   1.457 +			RDebug::Print(_L("    %8d -> Media"), i);
   1.458 +		else if ((val & msk) == (0x0FFFFFF7 & msk))
   1.459 +			RDebug::Print(_L("    %8d -> BAD"), i);
   1.460 +		else if (val > max)
   1.461 +			RDebug::Print(_L("    %8d -> 0x%08X"), i, val);
   1.462 +		else if (val != 0)
   1.463 +			RDebug::Print(_L("    %8d -> %d"), i, val);
   1.464 +		}
   1.465 +	RDebug::Print(_L("--------------------------------------------"));
   1.466 +	}
   1.467 +
   1.468 +GLDEF_C TDes* DirAttributes(TInt aAttrib)
   1.469 +// 
   1.470 +// Return a pointer to a local buffer containing the attribute letters.
   1.471 +//
   1.472 +	{
   1.473 +	LOCAL_D TBuf<6> str(_L("------"));
   1.474 +	LOCAL_D char*   atr = "RHSVDA";
   1.475 +	for (TInt i = 0; i < 6; i++)
   1.476 +		if ((aAttrib >> i) & 1)
   1.477 +			str[i] = atr[i];
   1.478 +	return &str;
   1.479 +	}
   1.480 +
   1.481 +GLDEF_C TBool IsValidDirChar(TUint8 aChar, TUint8 aMin=0x20)
   1.482 +//
   1.483 +// Test whether a character is valid as part of a short filename, aMin is to
   1.484 +// distinguish between first character (which can't be space) and later ones
   1.485 +// which can include space but nothing less.  Note that E5 is a valid character
   1.486 +// in any position, even though it means 'erased' in the first character.
   1.487 +//
   1.488 +	{
   1.489 +	const TUint8* inval = (TUint8*)"\x22\x2A\x2B\x2C\x2E\x2F\x3A\x3B\x3C\x3D\x3E\x3F\x5B\x5C\x5D\x7C";
   1.490 +	if (aChar < aMin)
   1.491 +		return EFalse;
   1.492 +	for (const TUint8* p = inval; *p; p++)
   1.493 +		if (aChar == *p)
   1.494 +			return EFalse;
   1.495 +	return ETrue;
   1.496 +	}
   1.497 +
   1.498 +GLDEF_C TBool IsValidDirEntry(TFatDirEntry* aDir)
   1.499 +// 
   1.500 +// Test whether buffer is a valid normal directory entry
   1.501 +//
   1.502 +	{
   1.503 +	// top two bits of attributes must be zero
   1.504 +	if (aDir->iData[11] & 0xC0)
   1.505 +		return EFalse;
   1.506 +	// first character must be 0x05 or greater than space
   1.507 +	if (!IsValidDirChar(aDir->iData[0], 0x21) && aDir->iData[0] != 0x05)
   1.508 +		return EFalse;
   1.509 +	// other characters in name must be not less than space
   1.510 +	for (TInt i = 1; i < 11; i++)
   1.511 +		if (!IsValidDirChar(aDir->iData[i]))
   1.512 +			return EFalse;
   1.513 +	return ETrue;
   1.514 +	}
   1.515 +
   1.516 +GLDEF_C void GetLongNamePart(TDes16& aName, const TUint8* aEntry, TInt aPos, TInt aOffset, TInt aLength)
   1.517 +// 
   1.518 +// Extract part of a long name entry into the name buffer.
   1.519 +//
   1.520 +// @param aName   buffer to put name
   1.521 +// @param aEntry  directory entry raw data
   1.522 +// @param aPos    character in buffer to start name segment
   1.523 +// @param aOffset offset in directory entry of the segment
   1.524 +// @param aLength number of characters in the segment
   1.525 +// 
   1.526 +	{
   1.527 +	for (TInt i = 0; i < aLength; i++)
   1.528 +		{
   1.529 +		TInt at = i * 2 + aOffset;
   1.530 +		TInt ch = aEntry[at] + aEntry[at+1] * 256;
   1.531 +		aName[aPos++] = TText(ch);
   1.532 +		}
   1.533 +	}
   1.534 +
   1.535 +GLDEF_C void ExtractNameString(TDes16& aName, const TUint8* aEntry)
   1.536 +//
   1.537 +// Extract a long name part from a directory entry, truncate it at the first
   1.538 +// NUL (0) character and put quotes round it.
   1.539 +//
   1.540 +	{
   1.541 +	aName.SetLength(15);
   1.542 +	TInt len = aName.Length() - 1;
   1.543 +	TText qu = '\'';
   1.544 +	aName[0] = qu;
   1.545 +	GetLongNamePart(aName, aEntry,  1,  1, 5);
   1.546 +	GetLongNamePart(aName, aEntry,  6, 14, 6);
   1.547 +	GetLongNamePart(aName, aEntry, 12, 28, 2);
   1.548 +	TInt i;
   1.549 +	for (i = 0; i < len; i++)
   1.550 +		if (aName[i] == 0)
   1.551 +			break;
   1.552 +	aName[i++] = qu;
   1.553 +	aName.SetLength(i);
   1.554 +	}
   1.555 +
   1.556 +GLDEF_C TBool DumpDirEntry(TInt aNum, const TUint8* aEntry)
   1.557 +// 
   1.558 +// Dump a single directory entry to the log.  Return false if it was end of
   1.559 +// directory or an invalid entry (and don't display it).
   1.560 +// 
   1.561 +	{
   1.562 +	TFatDirEntry* d = (TFatDirEntry*)aEntry;
   1.563 +	if (d->IsErased())
   1.564 +		{
   1.565 +		// RDebug::Print(_L("%5d: ERASED"), aNum);
   1.566 +		}
   1.567 +	else if (d->IsEndOfDirectory())
   1.568 +		return EFalse;
   1.569 +	else if ((d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
   1.570 +		{
   1.571 +		TBuf16<15> name;
   1.572 +		ExtractNameString(name, aEntry);
   1.573 +		TInt ord = aEntry[0];
   1.574 +		if (ord & KDirLastLongEntry)
   1.575 +			RDebug::Print(_L("%5d: %-15S #%-2d LAST"), aNum, &name, ord & ~KDirLastLongEntry);
   1.576 +		else
   1.577 +			RDebug::Print(_L("%5d: %-15S #%-2d"), aNum, &name, ord & ~KDirLastLongEntry);
   1.578 +		}
   1.579 +	else if (!IsValidDirEntry(d))
   1.580 +		return EFalse;
   1.581 +	else
   1.582 +		{
   1.583 +		TBuf<11> name;
   1.584 +		name.Copy(d->Name());
   1.585 +		RDebug::Print(_L("%5d: '%S'  %S  cluster %d"),
   1.586 +					  aNum, &name, DirAttributes(d->Attributes()), d->StartCluster());
   1.587 +		}
   1.588 +	return ETrue;
   1.589 +	}
   1.590 +
   1.591 +GLDEF_C void DumpDirCluster(const TUint8* aData, TInt aCluster=0)
   1.592 +//
   1.593 +// Dump directory entries until end of cluster or invalid/end entry found.
   1.594 +//
   1.595 +	{
   1.596 +	if (aCluster > 2)
   1.597 +		aData += (aCluster-2) * gBytesPerCluster;
   1.598 +	for (TInt i = 0; i < gBytesPerCluster; i += KSizeOfFatDirEntry)
   1.599 +		{
   1.600 +		if (DumpDirEntry(i/KSizeOfFatDirEntry, aData))
   1.601 +			aData += KSizeOfFatDirEntry;
   1.602 +		else
   1.603 +			break;
   1.604 +		}
   1.605 +	}
   1.606 +
   1.607 +GLDEF_C void DumpData(const TUint8* aFat, TInt aStart, TInt aEnd)
   1.608 +//
   1.609 +// Dump clusters from disk (allows dumping of clusters not in our buffers).
   1.610 +// Only look at clusters marked as 'used' in the FAT.  Note that if aFat is
   1.611 +// NULL the FAT entries will also be read from disk (slower but allows for ones
   1.612 +// outside our copy in memory).
   1.613 +//
   1.614 +	{
   1.615 +	if (aStart > gFatTestEntries)
   1.616 +		return;
   1.617 +	RDebug::Print(_L("--------------- DATA AREA ------------------"));
   1.618 +	if (aEnd > gFatTestEntries)
   1.619 +		aEnd = gFatTestEntries;
   1.620 +	for (TInt cluster = aStart; cluster < aEnd; cluster++)
   1.621 +		{
   1.622 +		if (GetFatEntry(cluster, aFat) != 0)
   1.623 +			{
   1.624 +			HBufC8* buf=HBufC8::New(gBytesPerCluster);
   1.625 +			test(buf!=NULL);
   1.626 +			TPtr8 ptr=buf->Des();
   1.627 +			TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
   1.628 +			test(r==KErrNone);
   1.629 +			r=TheRawDisk.Read(ClusterToByte(cluster), ptr);
   1.630 +			test(r==KErrNone);
   1.631 +			TheRawDisk.Close();
   1.632 +			RDebug::Print(_L("Cluster %d @ 0x%08X:"), cluster, ClusterToByte(cluster));
   1.633 +			DumpDirCluster(ptr.Ptr());
   1.634 +			delete buf;
   1.635 +			}
   1.636 +		}
   1.637 +	RDebug::Print(_L("--------------------------------------------"));
   1.638 +	}
   1.639 +
   1.640 +GLDEF_C void DumpHex(const TUint8* aData, TInt aLen)
   1.641 +//
   1.642 +// Dump a block of memory to the log in hex.
   1.643 +//
   1.644 +	{
   1.645 +	for (TInt base = 0; base < aLen; base += 16)
   1.646 +		{
   1.647 +		TBuf<16*3> buf;
   1.648 +		TInt off;
   1.649 +		for (off = base; off < aLen && off < base + 16; off++)
   1.650 +			{
   1.651 +			buf.Append(TText(' '));
   1.652 +			buf.AppendNumFixedWidth(aData[off], EHex, 2);
   1.653 +			}
   1.654 +		RDebug::Print(_L("%04X: %S"), off, &buf);
   1.655 +		}
   1.656 +	}
   1.657 +
   1.658 +static void QuickFormat()
   1.659 +    {
   1.660 +        /*
   1.661 +        TFatFormatParam fmt;
   1.662 +        fmt.iFatType = EFat32;
   1.663 +        fmt.iSecPerCluster =1;
   1.664 +        FormatFatDrive(TheFs, CurrentDrive(), ETrue, &fmt);
   1.665 +        */
   1.666 +        FormatFatDrive(TheFs, CurrentDrive(), ETrue);
   1.667 +    }
   1.668 +
   1.669 +
   1.670 +LOCAL_C void MakeVeryLongName(TFileName& aLong)
   1.671 +//
   1.672 +// appends a very long file name to aLong
   1.673 +//
   1.674 +	{
   1.675 +	// create a name to take up 18 vfat entries - (1 sector + 2 entries)
   1.676 +	for(TInt i=0;i<234;++i)
   1.677 +		{
   1.678 +		TInt c='a'+i%26;
   1.679 +		aLong.Append(c);
   1.680 +		}
   1.681 +	}
   1.682 +
   1.683 +LOCAL_C void MakeEntryName(TFileName& aName,TInt aLength)
   1.684 +//
   1.685 +// Appends aLength characters to aName
   1.686 +//
   1.687 +	{
   1.688 +	for(TInt i=0;i<aLength;++i)
   1.689 +		{
   1.690 +		TInt c='A'+i%26;
   1.691 +		aName.Append(c);
   1.692 +		}
   1.693 +	}
   1.694 +
   1.695 +LOCAL_C void FillUpRootDir(TInt aFree=0)
   1.696 +//
   1.697 +// Fill up root directory
   1.698 +//
   1.699 +	{
   1.700 +	TInt maxRootEntries = gRootDirEntries -aFree;
   1.701 +	TFileName dir=_L("\\??\\");
   1.702 +	TInt count=0;
   1.703 +	TInt entriesSoFar;
   1.704 +	if(IsReset)
   1.705 +		entriesSoFar=2+2+2+2; // \\t_scn32dr3.exe + \\sys + \\t_scn32dr3.log + \\f32-tst
   1.706 +	else
   1.707 +		entriesSoFar=0;
   1.708 +	TInt r;
   1.709 +	while(entriesSoFar<maxRootEntries)
   1.710 +		{
   1.711 +		dir[1]=TUint16(count/26+'a');
   1.712 +		dir[2]=TUint16(count%26+'a');
   1.713 +		r=TheFs.MkDir(dir);
   1.714 +		test(r==KErrNone);
   1.715 +		entriesSoFar+=2;
   1.716 +		++count;
   1.717 +		}
   1.718 +	}
   1.719 +
   1.720 +LOCAL_C void UnFillUpRootDir(TInt aFree=0)
   1.721 +//
   1.722 +// Reverse changes from FillUpRootDir()
   1.723 +//
   1.724 +	{
   1.725 +	TFileName dir=_L("\\??\\");
   1.726 +	TInt entriesSoFar=gRootDirEntries -aFree;
   1.727 +	TInt count=0;
   1.728 +	TInt r;
   1.729 +	TInt existing;
   1.730 +	if(IsReset)
   1.731 +		existing=2+2+2+2; // \\t_scn32dr3.exe + \\sys + \\t_scn32dr3.log + \\f32-tst
   1.732 +	else
   1.733 +		existing=0;
   1.734 +	while(entriesSoFar>existing)
   1.735 +		{
   1.736 +		dir[1]=TUint16(count/26+'a');
   1.737 +		dir[2]=TUint16(count%26+'a');
   1.738 +		r=TheFs.RmDir(dir);
   1.739 +		test(r==KErrNone);
   1.740 +		entriesSoFar-=2;
   1.741 +		++count;
   1.742 +		}
   1.743 +	}
   1.744 +
   1.745 +void InitialiseWriteBuffer(TDes8& buf)
   1.746 +//
   1.747 +//
   1.748 +//
   1.749 +	{
   1.750 +	for(TInt i=0;i<buf.Length();++i)
   1.751 +		buf[i]=(TUint8)('a'+i%26);
   1.752 +	}
   1.753 +
   1.754 +LOCAL_C TBool EntryExists(const TDesC& aName)	
   1.755 +//
   1.756 +// Returns ETrue if aName is found
   1.757 +//
   1.758 +	{
   1.759 +	TEntry entry;
   1.760 +	TInt r=TheFs.Entry(aName,entry);
   1.761 +	test(r==KErrNone||r==KErrNotFound);
   1.762 +	return(r==KErrNone?(TBool)ETrue:(TBool)EFalse);
   1.763 +	}
   1.764 +
   1.765 +LOCAL_C TInt EntriesPerFatSector()
   1.766 +//
   1.767 +// Returns number of entries in one fat table sector
   1.768 +//
   1.769 +	{
   1.770 +	switch (gDiskType)
   1.771 +		{
   1.772 +		case EFat32:
   1.773 +			return(BootSector.BytesPerSector()/4);
   1.774 +		case EFat16:
   1.775 +			return(BootSector.BytesPerSector()/2);
   1.776 +		case EFat12:
   1.777 +			return(BootSector.BytesPerSector()*2/3);
   1.778 +		default:
   1.779 +			test(0);
   1.780 +		}
   1.781 +	return -1;
   1.782 +	}
   1.783 +
   1.784 +LOCAL_C TBool OneEntryExists(const TDesC& aOldName,const TDesC& aNewName)
   1.785 +//
   1.786 +// Returns ETrue if only one of two entries exists
   1.787 +//
   1.788 +	{
   1.789 +	TBool oldExists=EntryExists(aOldName);
   1.790 +	TBool newExists=EntryExists(aNewName);
   1.791 +	return((!oldExists&&newExists)||(oldExists&&!newExists));
   1.792 +	}
   1.793 +
   1.794 +LOCAL_C void GetEntryDetails(const TDesC& aName,TEntry& aEntry)
   1.795 +//
   1.796 +// returns entry details for the entry with aName
   1.797 +//
   1.798 +	{
   1.799 +	TInt r=TheFs.Entry(aName,aEntry);
   1.800 +	test(r==KErrNone);
   1.801 +	}
   1.802 +
   1.803 +LOCAL_C TBool IsSameEntryDetails(TEntry aOldEntry,TEntry aNewEntry)
   1.804 +//
   1.805 +// 
   1.806 +//
   1.807 +	{
   1.808 +	return(aOldEntry.iAtt==aNewEntry.iAtt&&aOldEntry.iSize==aNewEntry.iSize&&aOldEntry.iModified==aNewEntry.iModified);
   1.809 +	}
   1.810 +
   1.811 +LOCAL_C void CreateAlternate(const TDesC& aNameOne,const TDesC& aNameTwo)
   1.812 +//
   1.813 +// Creates altenate entries which take up one sector of fat table.
   1.814 +// By subsequently deleting  one of these entries a new entry can be made 
   1.815 +// with cluster chain that is not contiguous.
   1.816 +//
   1.817 +	{
   1.818 +	TInt entries=EntriesPerFatSector();
   1.819 +	RFile file1,file2;
   1.820 +	TInt size1,size2;
   1.821 +	size1=size2=0;
   1.822 +	TInt r=file1.Create(TheFs,aNameOne,EFileShareAny);
   1.823 +	test(r==KErrNone);
   1.824 +	r=file2.Create(TheFs,aNameTwo,EFileShareAny);
   1.825 +	test(r==KErrNone);
   1.826 +	// one entry for file1 for every 40 entries for file2
   1.827 +	// if file 1 subseqently deleted then 7 entries available
   1.828 +	// in that fat sector - ~3.5kb file size - for fat16
   1.829 +	TInt ratio=40;
   1.830 +	TBool first=ETrue;
   1.831 +	while(entries>0)
   1.832 +		{
   1.833 +		if(first)
   1.834 +			{
   1.835 +			size1+=gBytesPerCluster;
   1.836 +			r=file1.SetSize(size1);
   1.837 +			test(r==KErrNone);
   1.838 +			first=EFalse;
   1.839 +			--entries;
   1.840 +			}
   1.841 +		else
   1.842 +			{
   1.843 +			size2+=gBytesPerCluster*ratio;
   1.844 +			r=file1.SetSize(size1);
   1.845 +			test(r==KErrNone);
   1.846 +			first=ETrue;
   1.847 +			entries-=ratio;
   1.848 +			}
   1.849 +		}
   1.850 +	file1.Close();
   1.851 +	file2.Close();
   1.852 +	}
   1.853 +
   1.854 +LOCAL_C TInt ThrottleDirEntries(TInt aDirEntries)
   1.855 +	{
   1.856 +	// throttle the number of entries needed, since for large cluster
   1.857 +	// sizes, this can take forever (eg 2GB card -> a cluster size of 32K
   1.858 +	// -> 1024 entries per cluster
   1.859 +	const TInt KMaxDirEntries = 2048;
   1.860 +	if (aDirEntries > KMaxDirEntries)
   1.861 +		{
   1.862 +		RDebug::Print(_L("Reducing directory entries from %d to %d"), 
   1.863 +			aDirEntries, KMaxDirEntries);
   1.864 +		aDirEntries = KMaxDirEntries;
   1.865 +		}
   1.866 +	return aDirEntries;
   1.867 +	}
   1.868 +
   1.869 +
   1.870 +LOCAL_C void CleanDirectory(const TDesC& aName,TInt aClusters)
   1.871 +//
   1.872 +// Removes entries in the directory
   1.873 +//
   1.874 +	{
   1.875 +	if (aClusters < 1)
   1.876 +		return;
   1.877 +	TInt entriesPerCluster=gBytesPerCluster/32;
   1.878 +	TInt entriesNeeded = entriesPerCluster * aClusters;
   1.879 +
   1.880 +	entriesNeeded = ThrottleDirEntries(entriesNeeded);
   1.881 +
   1.882 +	TInt maxFileNameLen = 250 - aName.Length();
   1.883 +	TInt nameEntries = 1 + (maxFileNameLen+12) / 13;
   1.884 +	TInt namesNeeded = (entriesNeeded + nameEntries-1) / nameEntries;
   1.885 +	TInt entry = 0;
   1.886 +	for(TInt i = 0; i < namesNeeded; ++i)
   1.887 +		{
   1.888 +		if (entriesNeeded - entry < nameEntries)
   1.889 +			maxFileNameLen = (entriesNeeded - entry - 1) * 13;
   1.890 +		TFileName fn;
   1.891 +		fn.AppendNum(entry);
   1.892 +		fn.Append('_');
   1.893 +		while (fn.Length() < maxFileNameLen)
   1.894 +			fn.Append('0');
   1.895 +		TFileName fullName(aName);
   1.896 +		fullName.Append(fn);
   1.897 +		TInt r = TheFs.Delete(fullName);
   1.898 +		test(r == KErrNone);
   1.899 +		entry += 1 + (fn.Length() + 12) / 13;
   1.900 +		}
   1.901 +	RDebug::Print(_L("CleanDirectory(%S, %d)"), &aName, aClusters);
   1.902 +	}
   1.903 +
   1.904 +LOCAL_C void ExpandDirectory(const TDesC& aName,TInt aClusters)
   1.905 +//
   1.906 +// Expands the directory by aClusters
   1.907 +//
   1.908 +	{
   1.909 +	if (aClusters < 1)
   1.910 +		return;
   1.911 +	TInt entriesPerCluster=gBytesPerCluster/32;
   1.912 +	TInt entriesNeeded = entriesPerCluster * aClusters;
   1.913 +
   1.914 +	entriesNeeded = ThrottleDirEntries(entriesNeeded);
   1.915 +
   1.916 +	TInt maxFileNameLen = 250 - aName.Length();
   1.917 +	TInt nameEntries = 1 + (maxFileNameLen+12) / 13;
   1.918 +	TInt namesNeeded = (entriesNeeded + nameEntries-1) / nameEntries;
   1.919 +	TInt entry = 0;
   1.920 +	for(TInt i = 0; i < namesNeeded; ++i)
   1.921 +		{
   1.922 +		if (entriesNeeded - entry < nameEntries)
   1.923 +			maxFileNameLen = (entriesNeeded - entry - 1) * 13;
   1.924 +		TFileName fn;
   1.925 +		fn.AppendNum(entry);
   1.926 +		fn.Append('_');
   1.927 +		while (fn.Length() < maxFileNameLen)
   1.928 +			fn.Append('0');
   1.929 +		TFileName fullName(aName);
   1.930 +		fullName.Append(fn);
   1.931 +		RFile file;
   1.932 +		TInt r = file.Create(TheFs,fullName,EFileShareAny);
   1.933 +		test(r == KErrNone);
   1.934 +		file.Close();
   1.935 +		entry += 1 + (fn.Length() + 12) / 13;
   1.936 +		}
   1.937 +	// to leave a directory expanded by aClusters but with no additional entries
   1.938 +	RDebug::Print(_L("ExpandDirectory(%S, %d)"), &aName, aClusters);
   1.939 +	CleanDirectory(aName,aClusters);
   1.940 +	}
   1.941 +
   1.942 +LOCAL_C TInt DeleteAlternateEntry(const TDesC& aName,TBool aIsDir)
   1.943 +//
   1.944 +// Deletes entry aName and corresponding entries created for EChainAlternate
   1.945 +//
   1.946 +	{
   1.947 +	TInt r=TheFs.Delete(_L("\\fat\\file2"));
   1.948 +	test(r==KErrNone||KErrNotFound);
   1.949 +	if(aIsDir)
   1.950 +		return(TheFs.RmDir(aName));
   1.951 +	else
   1.952 +		return(TheFs.Delete(aName));
   1.953 +	}
   1.954 +
   1.955 +LOCAL_C TInt CreateAlternateEntry(const TDesC& aName,TBool aIsDir,TInt aSize)
   1.956 +//
   1.957 +// Creates entry with aName where cluster chain grows forward but not contiguously.
   1.958 +// Assumes that no holes in fat clusters.
   1.959 +//
   1.960 +	{
   1.961 +	TInt r=DeleteAlternateEntry(aName,aIsDir);
   1.962 +	test(r==KErrNone||r==KErrNotFound);
   1.963 +	RFile file;
   1.964 +	if(aIsDir)
   1.965 +		{
   1.966 +		r=TheFs.MkDir(aName);
   1.967 +		if(r!=KErrNone)
   1.968 +			return(r);
   1.969 +		}
   1.970 +	else
   1.971 +		{
   1.972 +		r=file.Create(TheFs,aName,EFileShareAny);
   1.973 +		if(r!=KErrNone)
   1.974 +			return(r);
   1.975 +		r=file.SetSize(1); //ensure file allocated a start cluster
   1.976 +		test(r==KErrNone);
   1.977 +		}
   1.978 +	CreateAlternate(_L("\\fat\\file1"),_L("\\fat\\file2"));
   1.979 +	r=TheFs.Delete(_L("\\fat\\file1"));
   1.980 +	test(r==KErrNone);
   1.981 +	if(aIsDir)
   1.982 +		ExpandDirectory(aName,aSize);
   1.983 +	else
   1.984 +		{
   1.985 +		r=file.SetSize(aSize);
   1.986 +		test(r==KErrNone);
   1.987 +		file.Close();
   1.988 +		}
   1.989 +	return(KErrNone);
   1.990 +	}
   1.991 +
   1.992 +LOCAL_C TInt DeleteForwardEntry(const TDesC& aName,TBool aIsDir)
   1.993 +//
   1.994 +// Deletes entry with aName and corresponding entries created for EChainForward
   1.995 +//
   1.996 +	{
   1.997 +	TInt r=TheFs.Delete(_L("\\fat\\file2"));
   1.998 +	test(r==KErrNone||r==KErrNotFound);
   1.999 +	r=TheFs.Delete(_L("\\fat\\file4"));
  1.1000 +	test(r==KErrNone||r==KErrNotFound);
  1.1001 +	r=TheFs.Delete(_L("\\fat\\file5"));
  1.1002 +	test(r==KErrNone||r==KErrNotFound);
  1.1003 +	if(aIsDir)
  1.1004 +		r=TheFs.RmDir(aName);
  1.1005 +	else
  1.1006 +		r=TheFs.Delete(aName);
  1.1007 +	return r;
  1.1008 +	}
  1.1009 +	
  1.1010 +LOCAL_C TInt CreateForwardEntry(const TDesC& aName,TBool aIsDir,TInt aSize)
  1.1011 +//
  1.1012 +// Creates an entry whose cluster chain first goes forward (upto 3.5kb for fat16 file)
  1.1013 +// and then backwards
  1.1014 +//	
  1.1015 +	{
  1.1016 +	TInt r=DeleteForwardEntry(aName,aIsDir);
  1.1017 +	test(r==KErrNone||r==KErrNotFound);
  1.1018 +	RFile file1,file2,entry;
  1.1019 +	r=file1.Create(TheFs,_L("\\fat\\file1"),EFileShareAny);
  1.1020 +	test(r==KErrNone);
  1.1021 +	r=file1.SetSize(EntriesPerFatSector()*gBytesPerCluster);
  1.1022 +	test(r==KErrNone);
  1.1023 +	r=file2.Create(TheFs,_L("\\fat\\file2"),EFileShareAny);
  1.1024 +	test(r==KErrNone);
  1.1025 +	r=file2.SetSize(EntriesPerFatSector()*gBytesPerCluster);
  1.1026 +	test(r==KErrNone);
  1.1027 +	if(aIsDir)
  1.1028 +		{
  1.1029 +		r=TheFs.MkDir(aName);
  1.1030 +		if(r!=KErrNone)
  1.1031 +			return(r);
  1.1032 +		}
  1.1033 +	else
  1.1034 +		{
  1.1035 +		r=entry.Create(TheFs,aName,EFileShareAny);
  1.1036 +		if(r!=KErrNone)
  1.1037 +			return(r);
  1.1038 +		r=entry.SetSize(1);	// ensure entry has start cluster allocated
  1.1039 +		test(r==KErrNone);
  1.1040 +		}
  1.1041 +	CreateAlternate(_L("\\fat\\file3"),_L("\\fat\\file4"));
  1.1042 +	RFile file5;
  1.1043 +	r=file5.Create(TheFs,_L("\\fat\\file5"),EFileShareAny);
  1.1044 +	test(r==KErrNone);
  1.1045 +	r=file5.SetSize(EntriesPerFatSector()*gBytesPerCluster*2);
  1.1046 +	test(r==KErrNone);
  1.1047 +	file1.Close();
  1.1048 +	file2.Close();
  1.1049 +	file5.Close();
  1.1050 +	r=TheFs.Delete(_L("\\fat\\file1"));
  1.1051 +	test(r==KErrNone);
  1.1052 +	r=TheFs.Delete(_L("\\fat\\file3"));
  1.1053 +	test(r==KErrNone);
  1.1054 +	if(aIsDir)
  1.1055 +		ExpandDirectory(aName,aSize);
  1.1056 +	else
  1.1057 +		{
  1.1058 +		r=entry.SetSize(aSize);
  1.1059 +		test(r==KErrNone);
  1.1060 +		entry.Close();
  1.1061 +		}
  1.1062 +	return(KErrNone);
  1.1063 +	}
  1.1064 +
  1.1065 +LOCAL_C TInt DeleteBackwardEntry(const TDesC& aName,TBool aIsDir)
  1.1066 +//
  1.1067 +// Deletes entry with aName and corresponding entries created for EChainBackwards
  1.1068 +//
  1.1069 +	{
  1.1070 +	TInt r=TheFs.Delete(_L("\\fat\\file2"));
  1.1071 +	test(r==KErrNone||r==KErrNotFound);
  1.1072 +	r=TheFs.Delete(_L("\\fat\\file3"));
  1.1073 +	test(r==KErrNone||r==KErrNotFound);
  1.1074 +	if(aIsDir)
  1.1075 +		r=TheFs.RmDir(aName);
  1.1076 +	else
  1.1077 +		r=TheFs.Delete(aName);
  1.1078 +	return r;
  1.1079 +	}
  1.1080 +
  1.1081 +LOCAL_C TInt CreateBackwardEntry(const TDesC& aName,TBool aIsDir,TInt aSize)
  1.1082 +//
  1.1083 +// Creates an entry whose fat cluster chain first goes backwards(upto 3.5kb for fat16 file)
  1.1084 +// and then forwards
  1.1085 +//
  1.1086 +	{
  1.1087 +	TInt r=DeleteBackwardEntry(aName,aIsDir);
  1.1088 +	test(r==KErrNone||r==KErrNotFound);
  1.1089 +	CreateAlternate(_L("\\fat\\file1"),_L("\\fat\\file2"));
  1.1090 +	RFile entry;
  1.1091 +	if(aIsDir)
  1.1092 +		{
  1.1093 +		r=TheFs.MkDir(aName);
  1.1094 +		if(r!=KErrNone)
  1.1095 +			return(r);
  1.1096 +		}
  1.1097 +	else
  1.1098 +		{
  1.1099 +		r=entry.Create(TheFs,aName,EFileShareAny);
  1.1100 +		if(r!=KErrNone)
  1.1101 +			return(r);
  1.1102 +		r=entry.SetSize(1);
  1.1103 +		test(r==KErrNone);
  1.1104 +		}
  1.1105 +	RFile file3;
  1.1106 +	r=file3.Create(TheFs,_L("\\fat\\file3"),EFileShareAny);
  1.1107 +	test(r==KErrNone);
  1.1108 +	r=file3.SetSize(EntriesPerFatSector()*gBytesPerCluster);
  1.1109 +	test(r==KErrNone);
  1.1110 +	r=TheFs.Delete(_L("\\fat\\file1"));
  1.1111 +	test(r==KErrNone);
  1.1112 +	file3.Close();
  1.1113 +	if(aIsDir)
  1.1114 +		ExpandDirectory(aName,aSize);
  1.1115 +	else
  1.1116 +		{
  1.1117 +		r=entry.SetSize(aSize);
  1.1118 +		test(r==KErrNone);
  1.1119 +		entry.Close();
  1.1120 +		}
  1.1121 +	return(KErrNone);	
  1.1122 +	}
  1.1123 +
  1.1124 +LOCAL_C TInt DeleteStdEntry(const TDesC& aName,TBool aIsDir)
  1.1125 +//
  1.1126 +// Deletes entry with aName
  1.1127 +//
  1.1128 +	{
  1.1129 +	if(aIsDir)
  1.1130 +		return(TheFs.RmDir(aName));
  1.1131 +	else
  1.1132 +		return(TheFs.Delete(aName));
  1.1133 +	}
  1.1134 +
  1.1135 +LOCAL_C TInt CreateStdEntry(const TDesC& aName,TBool aIsDir,TInt aSize)
  1.1136 +//
  1.1137 +// Creates entry with aName where the cluster chain grows contiguously
  1.1138 +//
  1.1139 +	{
  1.1140 +	TInt r=DeleteStdEntry(aName,aIsDir);
  1.1141 +	test(r==KErrNone||r==KErrNotFound);
  1.1142 +	if(aIsDir)
  1.1143 +		{
  1.1144 +		r=TheFs.MkDir(aName);
  1.1145 +		if(r==KErrNone)
  1.1146 +			ExpandDirectory(aName,aSize);
  1.1147 +		return(r);
  1.1148 +		}
  1.1149 +	else
  1.1150 +		{
  1.1151 +		RFile file;
  1.1152 +		r=file.Create(TheFs,aName,EFileShareAny);
  1.1153 +		if(r==KErrNone)
  1.1154 +			{
  1.1155 +			r=file.SetSize(aSize);
  1.1156 +			test(r==KErrNone);
  1.1157 +			}
  1.1158 +		else if(r==KErrAlreadyExists)
  1.1159 +			{
  1.1160 +			TInt res =file.Open(TheFs,aName,EFileShareAny);
  1.1161 +			test(res==KErrNone);
  1.1162 +			}
  1.1163 +		else
  1.1164 +			return(r);
  1.1165 +		file.Close();
  1.1166 +		return(r);
  1.1167 +		}
  1.1168 +	}
  1.1169 +
  1.1170 +LOCAL_C TInt CreateEntry(const TDesC& aName,TBool aIsDir,TFatChain aChain,TInt aSize)
  1.1171 +//
  1.1172 +// Creates entry with aName whose fat cluster chain characteristics determined by aChain
  1.1173 +//
  1.1174 +	{
  1.1175 +	switch(aChain)
  1.1176 +		{
  1.1177 +		case(EChainStd):return(CreateStdEntry(aName,aIsDir,aSize));
  1.1178 +		case(EChainAlternate):return(CreateAlternateEntry(aName,aIsDir,aSize));
  1.1179 +		case(EChainBackwards):return(CreateBackwardEntry(aName,aIsDir,aSize));
  1.1180 +		case(EChainForwards):return(CreateForwardEntry(aName,aIsDir,aSize));
  1.1181 +		default:return(KErrGeneral);
  1.1182 +		}
  1.1183 +	}
  1.1184 +
  1.1185 +LOCAL_C TInt DeleteEntry(const TDesC& aName,TBool aIsDir,TFatChain aChain)
  1.1186 +//
  1.1187 +// Delete entry with aName
  1.1188 +//
  1.1189 +	{
  1.1190 +	switch(aChain)
  1.1191 +		{
  1.1192 +		case(EChainStd):return(DeleteStdEntry(aName,aIsDir));
  1.1193 +		case(EChainAlternate):return(DeleteAlternateEntry(aName,aIsDir));
  1.1194 +		case(EChainBackwards):return(DeleteBackwardEntry(aName,aIsDir));
  1.1195 +		case(EChainForwards):return(DeleteForwardEntry(aName,aIsDir));
  1.1196 +		default:return(KErrGeneral);
  1.1197 +		}
  1.1198 +	}
  1.1199 +
  1.1200 +LOCAL_C void TestRFsDelete(const TDesC& aName,TFatChain aChain,TInt aFileSize)
  1.1201 +//
  1.1202 +// test RFs::Delete
  1.1203 +//
  1.1204 +	{
  1.1205 +	TInt failCount=TheFailCount;
  1.1206 +	TInt r;
  1.1207 +	test.Start(_L("TestRFsDelete"));
  1.1208 +	FOREVER
  1.1209 +		{
  1.1210 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1211 +		r=CreateEntry(aName,EFalse,aChain,aFileSize);
  1.1212 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1213 +		if(IsReset)
  1.1214 +			{
  1.1215 +			++TheFailCount;
  1.1216 +			WriteLogFile();
  1.1217 +			}
  1.1218 +		r=SetWriteFailOn(failCount);
  1.1219 +		test(r==KErrNone);
  1.1220 +		r=TheFs.Delete(aName);
  1.1221 +		if(r==KErrNone)
  1.1222 +			break;
  1.1223 +		test(r==WriteFailValue);
  1.1224 +		r=TheFs.ScanDrive(gSessionPath);
  1.1225 +		test(r==KErrNone);
  1.1226 +		r=TheFs.CheckDisk(gSessionPath);
  1.1227 +		test(r==KErrNone);
  1.1228 +		++failCount;
  1.1229 +		}
  1.1230 +	r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1231 +	test(r==KErrNone);
  1.1232 +	r=TheFs.CheckDisk(gSessionPath);
  1.1233 +	test(r==KErrNone);
  1.1234 +	test(!EntryExists(aName));
  1.1235 +	++TheOpNumber;
  1.1236 +	TheFailCount=0;
  1.1237 +	}
  1.1238 +
  1.1239 +LOCAL_C void TestRFsRmDir(const TDesC& aName,TFatChain aChain,TInt aDirSize)
  1.1240 +//
  1.1241 +// test RFs::RmDir
  1.1242 +//
  1.1243 +	{
  1.1244 +	TInt failCount=TheFailCount;
  1.1245 +	TInt r;
  1.1246 +	test.Next(_L("TestRFsRmDir"));
  1.1247 +	switch (aChain)
  1.1248 +		{
  1.1249 +		case EChainStd:
  1.1250 +			RDebug::Print(_L("Chain Std %S size %d"), &aName, aDirSize);
  1.1251 +			break;
  1.1252 +		case EChainAlternate:
  1.1253 +			RDebug::Print(_L("Chain Alternate %S size %d"), &aName, aDirSize);
  1.1254 +			break;
  1.1255 +		case EChainBackwards:
  1.1256 +			RDebug::Print(_L("Chain Backwards %S size %d"), &aName, aDirSize);
  1.1257 +			break;
  1.1258 +		case EChainForwards:
  1.1259 +			RDebug::Print(_L("Chain Forwards %S size %d"), &aName, aDirSize);
  1.1260 +			break;
  1.1261 +		default:
  1.1262 +			break;
  1.1263 +		}
  1.1264 +	FOREVER
  1.1265 +		{
  1.1266 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1267 +		r=CreateEntry(aName,ETrue,aChain,aDirSize);
  1.1268 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1269 +		if(IsReset)
  1.1270 +			{
  1.1271 +			++TheFailCount;
  1.1272 +			WriteLogFile();
  1.1273 +			}
  1.1274 +		r=SetWriteFailOn(failCount);
  1.1275 +		test(r==KErrNone);
  1.1276 +		r=TheFs.RmDir(aName);
  1.1277 +		if(r==KErrNone)
  1.1278 +			break;
  1.1279 +		test(r==WriteFailValue);
  1.1280 +		r=TheFs.ScanDrive(gSessionPath);
  1.1281 +		RDebug::Print(_L("%6d: ScanDrive = %d"), __LINE__, r);
  1.1282 +		if (r != KErrNone)
  1.1283 +		{
  1.1284 +			RDebug::Print(_L("ScanDrive fail %d"), r);
  1.1285 +			DumpFat();
  1.1286 +			DumpData(NULL, 0, 200);
  1.1287 +		}
  1.1288 +		test(r==KErrNone);
  1.1289 +		r=TheFs.CheckDisk(gSessionPath);
  1.1290 +		RDebug::Print(_L("%6d: CheckDisk = %d"), __LINE__, r);
  1.1291 +		test(r==KErrNone);
  1.1292 +		++failCount;
  1.1293 +		}
  1.1294 +	r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1295 +	test(r==KErrNone);
  1.1296 +	r=TheFs.CheckDisk(gSessionPath);
  1.1297 +	test(r==KErrNone);
  1.1298 +	test(!EntryExists(aName));
  1.1299 +	++TheOpNumber;
  1.1300 +	TheFailCount=0;
  1.1301 +	}
  1.1302 +
  1.1303 +LOCAL_C void TestRFsMkDir(const TDesC& aName)
  1.1304 +//
  1.1305 +// test RFs::MkDir
  1.1306 +//
  1.1307 +	{
  1.1308 +	TInt failCount=TheFailCount;
  1.1309 +	TInt r;
  1.1310 +	test.Next(_L("TestRFsMkDir"));
  1.1311 +	FOREVER
  1.1312 +		{
  1.1313 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1314 +		r=DeleteEntry(aName,ETrue,EChainStd);
  1.1315 +		test(r==KErrNone||r==KErrNotFound);
  1.1316 +		if(IsReset)
  1.1317 +			{
  1.1318 +			++TheFailCount;
  1.1319 +			WriteLogFile();
  1.1320 +			}
  1.1321 +		r=SetWriteFailOn(failCount);
  1.1322 +		test(r==KErrNone);
  1.1323 +		r=TheFs.MkDir(aName);
  1.1324 +		if(r==KErrNone)
  1.1325 +			break;
  1.1326 +		test(r==WriteFailValue);
  1.1327 +		r=TheFs.ScanDrive(gSessionPath);
  1.1328 +		test(r==KErrNone);
  1.1329 +		r=TheFs.CheckDisk(gSessionPath);
  1.1330 +		test(r==KErrNone);
  1.1331 +		++failCount;
  1.1332 +		}
  1.1333 +	r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1334 +	test(r==KErrNone);
  1.1335 +	r=TheFs.CheckDisk(gSessionPath);
  1.1336 +	test(r==KErrNone);
  1.1337 +	test(EntryExists(aName));
  1.1338 +	r=DeleteEntry(aName,ETrue,EChainStd);
  1.1339 +	test(r==KErrNone);
  1.1340 +	++TheOpNumber;
  1.1341 +	TheFailCount=0;
  1.1342 +	}
  1.1343 +
  1.1344 +LOCAL_C void TestRFsRename(const TDesC& aOldName,const TDesC& aNewName,TBool aIsDir,TFatChain aChain,TInt aSize)
  1.1345 +//
  1.1346 +// test RFs::Rename
  1.1347 +//
  1.1348 +	{
  1.1349 +	test.Next(_L("TestRFsRename"));
  1.1350 +	TInt failCount=TheFailCount;
  1.1351 +	TInt r;
  1.1352 +	TEntry oldEntryInfo,newEntryInfo;
  1.1353 +	FOREVER
  1.1354 +		{
  1.1355 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1356 +		r=CreateEntry(aOldName,aIsDir,aChain,aSize);
  1.1357 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1358 +		r=DeleteEntry(aNewName,aIsDir,aChain);
  1.1359 +		test(r==KErrNone||r==KErrNotFound);
  1.1360 +		GetEntryDetails(aOldName,oldEntryInfo);
  1.1361 +		if(IsReset)
  1.1362 +			{
  1.1363 +			++TheFailCount;
  1.1364 +			WriteLogFile();
  1.1365 +			}
  1.1366 +		r=SetWriteFailOn(failCount);
  1.1367 +		test(r==KErrNone);
  1.1368 +		r=TheFs.Rename(aOldName,aNewName);
  1.1369 +		if(r==KErrNone)
  1.1370 +			break;
  1.1371 +		if(r!=WriteFailValue)
  1.1372 +			{
  1.1373 +			test.Printf(_L("r=%d\n"),r);
  1.1374 +			test(EFalse);
  1.1375 +			}
  1.1376 +		test(r==WriteFailValue);
  1.1377 +		r=TheFs.ScanDrive(gSessionPath);
  1.1378 +		test(r==KErrNone);
  1.1379 +		r=TheFs.CheckDisk(gSessionPath);
  1.1380 +		test(r==KErrNone);
  1.1381 +		// no start cluster if aSize==0
  1.1382 +		if(aSize!=0)
  1.1383 +			test(OneEntryExists(aOldName,aNewName));
  1.1384 +		++failCount;
  1.1385 +		}
  1.1386 +	r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1387 +	test(r==KErrNone);
  1.1388 +	r=TheFs.CheckDisk(gSessionPath);
  1.1389 +	test(r==KErrNone);
  1.1390 +	test(EntryExists(aNewName) && !EntryExists(aOldName));
  1.1391 +	GetEntryDetails(aNewName,newEntryInfo);
  1.1392 +	test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
  1.1393 +	r=DeleteEntry(aNewName,aIsDir,aChain);
  1.1394 +	test(r==KErrNone);
  1.1395 +	++TheOpNumber;
  1.1396 +	TheFailCount=0;
  1.1397 +	}
  1.1398 +
  1.1399 +LOCAL_C void TestRFsReplace(const TDesC& aOldName, const TDesC& aNewName,TBool aBothExist,TFatChain aChain,TInt aFileSize)
  1.1400 +//
  1.1401 +// test RFs::Replace
  1.1402 +//
  1.1403 +	{
  1.1404 +	
  1.1405 +	TInt failCount=TheFailCount;
  1.1406 +	TInt r;
  1.1407 +	if(aBothExist)
  1.1408 +		test.Next(_L("TestRFsReplace with new name existing"));
  1.1409 +	else
  1.1410 +		test.Next(_L("TestRFsReplace with new name not existing"));
  1.1411 +	TEntry oldEntryInfo,newEntryInfo;
  1.1412 +	FOREVER
  1.1413 +		{
  1.1414 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1415 +		r=CreateEntry(aOldName,EFalse,aChain,aFileSize);
  1.1416 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1417 +		if(aBothExist)
  1.1418 +			{
  1.1419 +			r=CreateEntry(aNewName,EFalse,aChain,aFileSize);
  1.1420 +			test(r==KErrNone||r==KErrAlreadyExists);
  1.1421 +			}
  1.1422 +		else
  1.1423 +			{
  1.1424 +			r=DeleteEntry(aNewName,EFalse,aChain);
  1.1425 +			test(r==KErrNone||r==KErrNotFound);
  1.1426 +			}
  1.1427 +		GetEntryDetails(aOldName,oldEntryInfo);
  1.1428 +		if(IsReset)
  1.1429 +			{
  1.1430 +			++TheFailCount;
  1.1431 +			WriteLogFile();
  1.1432 +			}
  1.1433 +		r=SetWriteFailOn(failCount);
  1.1434 +		test(r==KErrNone);
  1.1435 +		r=TheFs.Replace(aOldName,aNewName);
  1.1436 +		if(r==KErrNone)
  1.1437 +			break;
  1.1438 +		test(r==WriteFailValue);
  1.1439 +		r=TheFs.ScanDrive(gSessionPath);
  1.1440 +		test(r==KErrNone);
  1.1441 +		r=TheFs.CheckDisk(gSessionPath);
  1.1442 +		test(r==KErrNone);
  1.1443 +		if(!aBothExist && aFileSize!=0)
  1.1444 +			test(OneEntryExists(aOldName,aNewName));
  1.1445 +		else if(aBothExist)
  1.1446 +			test(EntryExists(aOldName)||EntryExists(aNewName));
  1.1447 +		++failCount;
  1.1448 +		}
  1.1449 +	r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1450 +	test(r==KErrNone);
  1.1451 +	r=TheFs.CheckDisk(gSessionPath);
  1.1452 +	test(r==KErrNone);
  1.1453 +	test(EntryExists(aNewName) && !EntryExists(aOldName));
  1.1454 +	GetEntryDetails(aNewName,newEntryInfo);
  1.1455 +	test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
  1.1456 +	r=DeleteEntry(aNewName,EFalse,aChain);
  1.1457 +	test(r==KErrNone);
  1.1458 +	++TheOpNumber;
  1.1459 +	TheFailCount=0;
  1.1460 +	}
  1.1461 +
  1.1462 +LOCAL_C void TestRFileCreate(const TDesC& aName)
  1.1463 +//
  1.1464 +// test RFile::Create
  1.1465 +//
  1.1466 +	{
  1.1467 +	TInt failCount=TheFailCount;
  1.1468 +	TInt r;
  1.1469 +	test.Next(_L("TestRFileCreate"));
  1.1470 +	FOREVER
  1.1471 +		{
  1.1472 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1473 +		r=DeleteEntry(aName,EFalse,EChainStd);
  1.1474 +		test(r==KErrNone||r==KErrNotFound);
  1.1475 +		if(IsReset)
  1.1476 +			{
  1.1477 +			++TheFailCount;
  1.1478 +			WriteLogFile();
  1.1479 +			}
  1.1480 +		r=SetWriteFailOn(failCount);
  1.1481 +		test(r==KErrNone);
  1.1482 +		RFile file;
  1.1483 +		r=file.Create(TheFs,aName,EFileShareAny);
  1.1484 +		if(r==KErrNone)
  1.1485 +			{
  1.1486 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1487 +			test(r==KErrNone);
  1.1488 +			file.Close();
  1.1489 +			break;
  1.1490 +			}
  1.1491 +		test(r==WriteFailValue);
  1.1492 +		r=TheFs.ScanDrive(gSessionPath);
  1.1493 +		test(r==KErrNone);
  1.1494 +		r=TheFs.CheckDisk(gSessionPath);
  1.1495 +		test(r==KErrNone);
  1.1496 +		++failCount;
  1.1497 +		}
  1.1498 +	r=TheFs.CheckDisk(gSessionPath);
  1.1499 +	test(r==KErrNone);
  1.1500 +	test(EntryExists(aName));
  1.1501 +	r=DeleteEntry(aName,EFalse,EChainStd);
  1.1502 +	test(r==KErrNone);
  1.1503 +	++TheOpNumber;
  1.1504 +	TheFailCount=0;
  1.1505 +	}
  1.1506 +
  1.1507 +LOCAL_C void TestRFileTemp(const TDesC& aPath)
  1.1508 +//
  1.1509 +// test RFile::Temp
  1.1510 +//
  1.1511 +	{
  1.1512 +	TInt failCount=TheFailCount;
  1.1513 +	TInt r;
  1.1514 +	test.Next(_L("TestRFileTemp"));
  1.1515 +	TFileName temp;
  1.1516 +	FOREVER
  1.1517 +		{
  1.1518 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1519 +		if(IsReset)
  1.1520 +			{
  1.1521 +			++TheFailCount;
  1.1522 +			WriteLogFile();
  1.1523 +			}
  1.1524 +		r=SetWriteFailOn(failCount);
  1.1525 +		test(r==KErrNone);
  1.1526 +		RFile file;
  1.1527 + 		r=file.Temp(TheFs,aPath,temp,EFileShareAny);
  1.1528 +		if(r==KErrNone)
  1.1529 +			{
  1.1530 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1531 +			test(r==KErrNone);
  1.1532 +			file.Close();
  1.1533 +			break;
  1.1534 +			}
  1.1535 +		test(r==WriteFailValue);
  1.1536 +		r=TheFs.ScanDrive(gSessionPath);
  1.1537 +		test(r==KErrNone);
  1.1538 +		r=TheFs.CheckDisk(gSessionPath);
  1.1539 +		test(r==KErrNone);
  1.1540 +		++failCount;
  1.1541 +		}
  1.1542 +	r=TheFs.CheckDisk(gSessionPath);
  1.1543 +	test(r==KErrNone);
  1.1544 +	test(EntryExists(temp));
  1.1545 +	r=DeleteEntry(temp,EFalse,EChainStd);
  1.1546 +	test(r==KErrNone);
  1.1547 +	++TheOpNumber;
  1.1548 +	TheFailCount=0;
  1.1549 +	}
  1.1550 +
  1.1551 +LOCAL_C void TestRFileRename(const TDesC& aOldName, const TDesC& aNewName,TFatChain aChain,TInt aFileSize)
  1.1552 +//
  1.1553 +// test RFile::Rename
  1.1554 +//
  1.1555 +	{
  1.1556 +	TInt failCount=TheFailCount;
  1.1557 +	TInt r;
  1.1558 +	test.Next(_L("TestRFileRename"));
  1.1559 +	TEntry oldEntryInfo,newEntryInfo;
  1.1560 +	FOREVER
  1.1561 +		{
  1.1562 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1563 +		r=CreateEntry(aOldName,EFalse,aChain,aFileSize);
  1.1564 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1565 +		r=DeleteEntry(aNewName,EFalse,aChain);
  1.1566 +		test(r==KErrNone||r==KErrNotFound);
  1.1567 +		GetEntryDetails(aOldName,oldEntryInfo);
  1.1568 +		if(IsReset)
  1.1569 +			{
  1.1570 +			++TheFailCount;
  1.1571 +			WriteLogFile();
  1.1572 +			}
  1.1573 +		RFile file;
  1.1574 +		r=file.Open(TheFs,aOldName,EFileShareExclusive|EFileWrite);
  1.1575 +		test(r==KErrNone);
  1.1576 +		r=SetWriteFailOn(failCount);
  1.1577 +		test(r==KErrNone);
  1.1578 +		r=file.Rename(aNewName);
  1.1579 +		if(r==KErrNone)
  1.1580 +			{
  1.1581 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1582 +			test(r==KErrNone);
  1.1583 +			file.Close();
  1.1584 +			break;
  1.1585 +			}
  1.1586 +		test(r==WriteFailValue);
  1.1587 +		file.Close();
  1.1588 +		r=TheFs.ScanDrive(gSessionPath);
  1.1589 +		test(r==KErrNone);
  1.1590 +		r=TheFs.CheckDisk(gSessionPath);
  1.1591 +		test(r==KErrNone);
  1.1592 +		if(aFileSize)
  1.1593 +			test(OneEntryExists(aOldName,aNewName));
  1.1594 +		++failCount;
  1.1595 +		}
  1.1596 +	r=TheFs.CheckDisk(gSessionPath);
  1.1597 +	test(r==KErrNone);
  1.1598 +	test(EntryExists(aNewName) && !EntryExists(aOldName));
  1.1599 +	GetEntryDetails(aNewName,newEntryInfo);
  1.1600 +	test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
  1.1601 +	r=DeleteEntry(aNewName,EFalse,aChain);
  1.1602 +	test(r==KErrNone);
  1.1603 +	++TheOpNumber;
  1.1604 +	TheFailCount=0;
  1.1605 +	}
  1.1606 +
  1.1607 +LOCAL_C void TestRFileReplace(const TDesC& aName,TBool aAlreadyExists,TFatChain aChain,TInt aFileSize)
  1.1608 +//
  1.1609 +// test RFile::Replace
  1.1610 +//
  1.1611 +	{
  1.1612 +	TInt failCount=TheFailCount;
  1.1613 +	TInt r;
  1.1614 +	test.Next(_L("TestRFileReplace"));
  1.1615 +	FOREVER
  1.1616 +		{
  1.1617 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1618 +		if(aAlreadyExists)
  1.1619 +			{
  1.1620 +			r=CreateEntry(aName,EFalse,aChain,aFileSize);
  1.1621 +			test(r==KErrNone||r==KErrAlreadyExists);
  1.1622 +			}
  1.1623 +		else
  1.1624 +			{
  1.1625 +			r=DeleteEntry(aName,EFalse,aChain);
  1.1626 +			test(r==KErrNone||r==KErrNotFound);
  1.1627 +			}
  1.1628 +		if(IsReset)
  1.1629 +			{
  1.1630 +			++TheFailCount;
  1.1631 +			WriteLogFile();
  1.1632 +			}
  1.1633 +		r=SetWriteFailOn(failCount);
  1.1634 +		test(r==KErrNone);
  1.1635 +		RFile file;
  1.1636 +		r=file.Replace(TheFs,aName,EFileShareAny);
  1.1637 +		if(r==KErrNone)
  1.1638 +			{
  1.1639 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1640 +			test(r==KErrNone);
  1.1641 +			file.Close();
  1.1642 +			break;
  1.1643 +			}
  1.1644 +		test(r==WriteFailValue);
  1.1645 +		r=TheFs.ScanDrive(gSessionPath);
  1.1646 +		test(r==KErrNone);
  1.1647 +		r=TheFs.CheckDisk(gSessionPath);
  1.1648 +		test(r==KErrNone);
  1.1649 +		++failCount;
  1.1650 +		}
  1.1651 +	r=TheFs.CheckDisk(gSessionPath);
  1.1652 +	test(r==KErrNone);
  1.1653 +	test(EntryExists(aName));
  1.1654 +	r=DeleteEntry(aName,EFalse,aChain);
  1.1655 +	test(r==KErrNone);
  1.1656 +	if(!aAlreadyExists)
  1.1657 +		{
  1.1658 +		++TheOpNumber;
  1.1659 +		TheFailCount=0;
  1.1660 +		}
  1.1661 +	else
  1.1662 +		{
  1.1663 +		++TheFunctionNumber;
  1.1664 +		TheOpNumber=TheFailCount=0;
  1.1665 +		}
  1.1666 +	}
  1.1667 +
  1.1668 +LOCAL_C void TestRFileSetSize(const TDesC& aName,TFatChain aChain,TInt aOldFileSize,TInt aNewFileSize)
  1.1669 +//
  1.1670 +// test RFile::SetSize
  1.1671 +//
  1.1672 +	{
  1.1673 +	TInt failCount=TheFailCount;
  1.1674 +	TInt r;
  1.1675 +	test.Next(_L("TestRFileSetSize"));
  1.1676 +	test.Printf(_L("old size=%d new size=%d\n"),aOldFileSize,aNewFileSize);
  1.1677 +	FOREVER
  1.1678 +		{
  1.1679 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1680 +		r=CreateEntry(aName,EFalse,aChain,aOldFileSize);
  1.1681 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1682 +		if(IsReset)
  1.1683 +			{
  1.1684 +			++TheFailCount;
  1.1685 +			WriteLogFile();
  1.1686 +			}
  1.1687 +		r=SetWriteFailOn(failCount);
  1.1688 +		test(r==KErrNone);
  1.1689 +		RFile file;
  1.1690 +		r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
  1.1691 +		test(r==KErrNone);
  1.1692 +		r=file.SetSize(aNewFileSize);
  1.1693 +		// close the file before testing the return value!
  1.1694 +		file.Close();
  1.1695 +		if(r==KErrNone)
  1.1696 +			{
  1.1697 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1698 +			test(r==KErrNone);
  1.1699 +			file.Close();
  1.1700 +			break;
  1.1701 +			}
  1.1702 +		file.Close();
  1.1703 +		test(r==WriteFailValue);
  1.1704 +		r=TheFs.ScanDrive(gSessionPath);
  1.1705 +		test(r==KErrNone);
  1.1706 +		r=TheFs.CheckDisk(gSessionPath);
  1.1707 +		test(r==KErrNone);
  1.1708 +		r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
  1.1709 +		test(r==KErrNone);
  1.1710 +		TInt size;
  1.1711 +		r=file.Size(size);
  1.1712 +		test(r==KErrNone);
  1.1713 +		test(size==aNewFileSize||size==aOldFileSize);
  1.1714 +		file.Close();
  1.1715 +		++failCount;
  1.1716 +		}
  1.1717 +	r=TheFs.CheckDisk(gSessionPath);
  1.1718 +	test(r==KErrNone);
  1.1719 +	RFile file;
  1.1720 +	r=file.Open(TheFs,aName,EFileShareAny);
  1.1721 +	test(r==KErrNone);
  1.1722 +	TInt fileSize;
  1.1723 +	r=file.Size(fileSize);
  1.1724 +	test(r==KErrNone);
  1.1725 +	test(aNewFileSize==fileSize);
  1.1726 +	file.Close();
  1.1727 +	r=DeleteEntry(aName,EFalse,aChain);
  1.1728 +	test(r==KErrNone);
  1.1729 +	++TheFunctionNumber;
  1.1730 +	TheFailCount=0;
  1.1731 +	}
  1.1732 +
  1.1733 +LOCAL_C void TestRFileWrite(const TDesC& aName,TFatChain aChain,TInt aFileSize,TInt aPos,TInt aLength)
  1.1734 +//
  1.1735 +// test RFile::Write
  1.1736 +//
  1.1737 +	{
  1.1738 +	TInt failCount=TheFailCount;
  1.1739 +	TInt r;
  1.1740 +	test.Next(_L("TestRFileWrite"));
  1.1741 +	test.Printf(_L("aFileSize=%d,aPos=%d,aLength=%d\n"),aFileSize,aPos,aLength);
  1.1742 +	TInt newSize=(aFileSize>=aPos+aLength)?aFileSize:aPos+aLength;
  1.1743 +	HBufC8* desPtr;
  1.1744 +	desPtr=HBufC8::New(aLength);
  1.1745 +	test(desPtr!=NULL);
  1.1746 +	TPtr8 des=desPtr->Des();
  1.1747 +	des.SetLength(aLength);
  1.1748 +	InitialiseWriteBuffer(des);
  1.1749 +	FOREVER
  1.1750 +		{
  1.1751 +		test.Printf(_L("failCount=%d\n"),failCount);
  1.1752 +		r=CreateEntry(aName,EFalse,aChain,aFileSize);
  1.1753 +		test(r==KErrNone||r==KErrAlreadyExists);
  1.1754 +		if(IsReset)
  1.1755 +			{
  1.1756 +			++TheFailCount;
  1.1757 +			WriteLogFile();
  1.1758 +			}
  1.1759 +		r=SetWriteFailOn(failCount);
  1.1760 +		test(r==KErrNone);
  1.1761 +		RFile file;
  1.1762 +		r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
  1.1763 +		test(r==KErrNone);
  1.1764 +		r=file.Write(aPos,des,aLength);
  1.1765 +		if(r==KErrNone)
  1.1766 +			{
  1.1767 +			r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
  1.1768 +			test(r==KErrNone);
  1.1769 +			file.Close();
  1.1770 +			break;
  1.1771 +			}
  1.1772 +		test(r==WriteFailValue);
  1.1773 +		file.Close();
  1.1774 +		r=TheFs.ScanDrive(gSessionPath);
  1.1775 +		test(r==KErrNone);
  1.1776 +		r=TheFs.CheckDisk(gSessionPath);
  1.1777 +		test(r==KErrNone);
  1.1778 +		file.Open(TheFs,aName,EFileShareAny);
  1.1779 +		test(r==KErrNone);
  1.1780 +		TInt fileSize;
  1.1781 +		r=file.Size(fileSize);
  1.1782 +		// with fair scheduling enabled it's possible for the file 
  1.1783 +		// size to grow even if the write appears to have failed...
  1.1784 +//		test(fileSize==aFileSize||fileSize==newSize);
  1.1785 +		test(fileSize>=aFileSize && fileSize <= newSize);
  1.1786 +
  1.1787 +		file.Close();
  1.1788 +		++failCount;
  1.1789 +		}
  1.1790 +	r=TheFs.CheckDisk(gSessionPath);
  1.1791 +	test(r==KErrNone);
  1.1792 +	RFile file;
  1.1793 +	r=file.Open(TheFs,aName,EFileShareAny);
  1.1794 +	test(r==KErrNone);
  1.1795 +	TInt fileSize;
  1.1796 +	r=file.Size(fileSize);
  1.1797 +	test(r==KErrNone);
  1.1798 +	test(newSize==fileSize);
  1.1799 +	HBufC8* desPtr2;
  1.1800 +	desPtr2=HBufC8::New(aLength);
  1.1801 +	test(desPtr2!=NULL);
  1.1802 +	TPtr8 des2=desPtr2->Des();
  1.1803 +	des2.SetLength(aLength);
  1.1804 +	r=file.Read(aPos,des2,des2.Length());
  1.1805 +	test(r==KErrNone);
  1.1806 +	r=des2.Compare(des);
  1.1807 +	test(r==0);
  1.1808 +	file.Close();
  1.1809 +	r=DeleteEntry(aName,EFalse,aChain);
  1.1810 +	test(r==KErrNone);
  1.1811 +	delete desPtr;
  1.1812 +	delete desPtr2;
  1.1813 +	++TheFunctionNumber;
  1.1814 +	TheFailCount=0;
  1.1815 +	}
  1.1816 +
  1.1817 +
  1.1818 +LOCAL_C void TestOperations(const TDesC& aOldName,const TDesC& aNewName,TFatChain aChain,TInt aFileSize, TInt aDirClusters)
  1.1819 +//
  1.1820 +// Tests the specified operations
  1.1821 +//
  1.1822 +	{
  1.1823 +	TFileName oldDirName=aOldName;
  1.1824 +	TFileName newDirName=aNewName;
  1.1825 +	// create directory for directory operations
  1.1826 +	oldDirName+=_L("\\");
  1.1827 +	newDirName+=_L("\\");
  1.1828 +	// locate path for RFile::Temp
  1.1829 +	TInt pathPos=aOldName.LocateReverse('\\')+1;
  1.1830 +	TFileName tempPath=aOldName.Left(pathPos);
  1.1831 +	test.Printf(_L("aOldName=%S\n"),&aOldName);
  1.1832 +	test.Printf(_L("aNewName=%S\n"),&aNewName);
  1.1833 +	test.Printf(_L("tempPath=%S\n"),&tempPath);
  1.1834 +	switch(TheOpNumber)
  1.1835 +		{
  1.1836 +		case(0):TestRFsDelete(aOldName,aChain,aFileSize);
  1.1837 +		case(1):TestRFsRmDir(oldDirName,aChain,aDirClusters);
  1.1838 +		case(2):TestRFsMkDir(oldDirName);
  1.1839 +		case(3):TestRFsRename(aOldName,aNewName,EFalse,aChain,aFileSize);
  1.1840 +		case(4):TestRFsRename(oldDirName,newDirName,ETrue,aChain,aDirClusters);
  1.1841 +		case(5):TestRFsReplace(aOldName,aNewName,EFalse,aChain,aFileSize);
  1.1842 +		case(6):TestRFsReplace(aOldName,aNewName,ETrue,aChain,aFileSize);
  1.1843 +		case(7):TestRFileCreate(aOldName);
  1.1844 +		case(8):TestRFileTemp(tempPath);
  1.1845 +		case(9):TestRFileRename(aOldName,aNewName,aChain,aFileSize);
  1.1846 +		case(10):TestRFileReplace(aOldName,EFalse,aChain,aFileSize);
  1.1847 +		case(11):TestRFileReplace(aOldName,ETrue,aChain,aFileSize);break;
  1.1848 +		default:test(EFalse);
  1.1849 +		}
  1.1850 +	test.End();
  1.1851 +	}
  1.1852 +
  1.1853 +LOCAL_C void TestOperation0()
  1.1854 +//
  1.1855 +//
  1.1856 +//
  1.1857 +	{
  1.1858 +	// tests entries in root directory
  1.1859 +	test.Next(_L("TestOperation0"));
  1.1860 +	TestOperations(_L("\\entryWithTwoVfats"),_L("\\anotherEntryWithTwo"),EChainStd,0,0);
  1.1861 +	}
  1.1862 +	
  1.1863 +LOCAL_C void TestOperation1()
  1.1864 +//
  1.1865 +//
  1.1866 +//
  1.1867 +	{
  1.1868 +	// tests entries in a full root directory
  1.1869 +	test.Next(_L("TestOperation1"));
  1.1870 +	if(TheFailCount==0)
  1.1871 +		FillUpRootDir(4);
  1.1872 +	TestOperations(_L("\\entryOne"),_L("\\entryTwo"),EChainStd,512,0);
  1.1873 +	UnFillUpRootDir(4);
  1.1874 +	}
  1.1875 +
  1.1876 +LOCAL_C void TestOperation2()
  1.1877 +//
  1.1878 +//
  1.1879 +//
  1.1880 +	{
  1.1881 +	// tests entries in same subdir
  1.1882 +	test.Next(_L("TestOperation2"));
  1.1883 +	TestOperations(_L("\\test\\subdir1\\NameWithFourVFatEntriesWaffle"),_L("\\test\\subdir1\\aEntry"),EChainAlternate,5120,1);
  1.1884 +	}
  1.1885 +
  1.1886 +
  1.1887 +LOCAL_C void TestOperation3()
  1.1888 +//
  1.1889 +//
  1.1890 +//
  1.1891 +	{
  1.1892 +	// tests entries in different subdir
  1.1893 +	test.Next(_L("TestOperation3"));
  1.1894 +	TestOperations(_L("\\test\\subdir1\\NameWithThreeEntries"),_L("\\ANother\\aEntrytwo"),EChainAlternate,15000,10);
  1.1895 +	}
  1.1896 +
  1.1897 +
  1.1898 +LOCAL_C void TestOperation4()
  1.1899 +//
  1.1900 +//
  1.1901 +//
  1.1902 +	{
  1.1903 +	// tests entries with cluster chain of EChainForwards
  1.1904 +	test.Next(_L("TestOperation4"));
  1.1905 +	TestOperations(_L("\\test\\subdir1\\aEntry"),_L("\\aEntry"),EChainForwards,12799,25);
  1.1906 +	}
  1.1907 +
  1.1908 +
  1.1909 +LOCAL_C void TestOperation5()
  1.1910 +//
  1.1911 +//
  1.1912 +//
  1.1913 +	{
  1.1914 +	// tests entries with cluster chain of EChainBackwards
  1.1915 +	test.Next(_L("TestOperation5"));
  1.1916 +	TestOperations(_L("\\test\\subdir1\\aEntry"),_L("\\ANother\\EntrywithThree"),EChainBackwards,51199,10);
  1.1917 +	}
  1.1918 +
  1.1919 +LOCAL_C void TestOperation6()
  1.1920 +//
  1.1921 +//
  1.1922 +//
  1.1923 +	{
  1.1924 +	// tests entries where old name has a very long name
  1.1925 +	test.Next(_L("TestOperation6"));
  1.1926 +	TFileName longName=_L("\\test\\subdir1\\");
  1.1927 +	MakeVeryLongName(longName);
  1.1928 +	TestOperations(longName,_L("\\ANother\\e1"),EChainAlternate,5100,0);
  1.1929 +	}
  1.1930 +
  1.1931 +LOCAL_C void TestOperation7()
  1.1932 +//
  1.1933 +//
  1.1934 +//
  1.1935 +	{
  1.1936 +	// tests entries where new name fills up subdir cluster
  1.1937 +	test.Next(_L("TestOperation7"));
  1.1938 +	TFileName name=_L("\\test\\subdir2\\");
  1.1939 +	// add entry with 7 vfat entries
  1.1940 +	MakeEntryName(name,80);
  1.1941 +	if(TheFailCount==0)
  1.1942 +		CreateEntry(name,EFalse,EChainStd,1);
  1.1943 +	TestOperations(_L("\\test\\subdir2\\EntryWithThree"),_L("\\test\\subdir2\\EntryWithThree-"),EChainStd,512,0);
  1.1944 +	DeleteEntry(name,EFalse,EChainStd);
  1.1945 +	}
  1.1946 +
  1.1947 +LOCAL_C void TestOperation8()
  1.1948 +//
  1.1949 +//
  1.1950 +//
  1.1951 +	{
  1.1952 +	// tests entries where new name is first entry in new subdir cluster
  1.1953 +	test.Next(_L("TestOperation8"));
  1.1954 +	TFileName name=_L("\\test\\subdir2\\");
  1.1955 +	// add entry with 10 vfat entries
  1.1956 +	MakeEntryName(name,125);
  1.1957 +	if(TheFailCount==0)
  1.1958 +		CreateEntry(name,EFalse,EChainStd,175000);
  1.1959 +	TestOperations(_L("\\test\\subdir2\\Entrywith3three"),_L("\\test\\subdir2\\entrywiththree-"),EChainStd,512,1);
  1.1960 +	DeleteEntry(name,EFalse,EChainStd);
  1.1961 +	}
  1.1962 +
  1.1963 +GLDEF_C void DoTests()
  1.1964 +	{
  1.1965 +	TInt r;
  1.1966 +	if(!IsReset && IsInternalRam())
  1.1967 +		{
  1.1968 +		test.Printf(_L("Error: Internal ram drive not tested\n"));
  1.1969 +		return;
  1.1970 +		}
  1.1971 +	if(!IsReset)
  1.1972 +		QuickFormat();
  1.1973 +
  1.1974 +	DoReadBootSector();
  1.1975 +	DumpBootSector();
  1.1976 +	ClearDiskData();
  1.1977 +
  1.1978 +	r=TheFs.SetSessionPath(gSessionPath);
  1.1979 +	test(r==KErrNone);
  1.1980 +
  1.1981 +	switch(TheFunctionNumber)
  1.1982 +		{
  1.1983 +		case(0):TestOperation0();
  1.1984 +		case(1):{
  1.1985 +				TestOperation1();
  1.1986 +				r=TheFs.MkDir(_L("\\fat\\"));
  1.1987 +				test(r==KErrNone);
  1.1988 +				r=TheFs.MkDir(_L("\\test\\"));
  1.1989 +				test(r==KErrNone);
  1.1990 +				r=TheFs.MkDir(_L("\\ANother\\"));
  1.1991 +				test(r==KErrNone);
  1.1992 +				r=TheFs.MkDir(_L("\\test\\subdir1\\"));
  1.1993 +				test(r==KErrNone);
  1.1994 +				r=TheFs.MkDir(_L("\\test\\subdir2\\"));
  1.1995 +				test(r==KErrNone);}
  1.1996 +		case(2):{
  1.1997 +				TestOperation2();
  1.1998 +				// add some filler files
  1.1999 +				CreateEntry(_L("\\test\\subdir1\\FillerOne"),EFalse,EChainStd,512);
  1.2000 +				CreateEntry(_L("\\test\\subdir1\\FillerTwo"),EFalse,EChainStd,1024);}
  1.2001 +		case(3):TestOperation3();
  1.2002 +		case(4):{
  1.2003 +				TestOperation4();
  1.2004 +				// add some filler files
  1.2005 +				CreateEntry(_L("\\ANother\\FillerThree"),EFalse,EChainStd,1536);
  1.2006 +				CreateEntry(_L("\\test\\subdir1\\FillerFour"),EFalse,EChainStd,2048);}
  1.2007 +		case(5):TestOperation5();
  1.2008 +		case(6):TestOperation6();
  1.2009 +		case(7):TestOperation7();
  1.2010 +		case(8):TestOperation8();
  1.2011 +		// increase size of file
  1.2012 +		case(9):TestRFileSetSize(_L("\\entry1"),EChainStd,0,512);
  1.2013 +		case(10):TestRFileSetSize(_L("\\entry1"),EChainAlternate,0,1025);
  1.2014 +		case(11):TestRFileSetSize(_L("\\entry1"),EChainStd,1,512);
  1.2015 +		// seek index (of CFatFileCB) resized
  1.2016 +		case(12):TestRFileSetSize(_L("\\entry1"),EChainForwards,512,66666);
  1.2017 +		// seek index resized
  1.2018 +		case(13):TestRFileSetSize(_L("\\entry1"),EChainBackwards,32779,131074);
  1.2019 +		// decrease size of file
  1.2020 +		// seek index resized
  1.2021 +		case(14):TestRFileSetSize(_L("\\entry1"),EChainForwards,133000,32768);
  1.2022 +		// seek index resized
  1.2023 +		case(15):TestRFileSetSize(_L("\\entry1"),EChainBackwards,65536,1);
  1.2024 +		// seek index resized
  1.2025 +		case(16):TestRFileSetSize(_L("\\entry1"),EChainAlternate,66554,0);
  1.2026 +		case(17):TestRFileSetSize(_L("\\entry1"),EChainStd,1024,1);
  1.2027 +		case(18):TestRFileSetSize(_L("\\entry1"),EChainAlternate,512,0);
  1.2028 +		case(19):TestRFileWrite(_L("\\entry2"),EChainStd,0,0,512);
  1.2029 +		case(20):TestRFileWrite(_L("\\entry2"),EChainAlternate,5120,512,1024);
  1.2030 +		case(21):TestRFileWrite(_L("\\entry2"),EChainForwards,3584,3584,5000);
  1.2031 +		case(22):TestRFileWrite(_L("\\entry2"),EChainBackwards,3000,2999,2000);
  1.2032 +		// seek index resized
  1.2033 +		case(23):TestRFileWrite(_L("\\entry2"),EChainBackwards,64000,64000,3000);
  1.2034 +		// seek index resized
  1.2035 +		case(24):TestRFileWrite(_L("\\entry2"),EChainForwards,131072,2,4000);break;
  1.2036 +		default:test(EFalse);
  1.2037 +		}
  1.2038 +	DeleteEntry(_L("\\test\\subdir1\\FillerFour"),EFalse,EChainStd);
  1.2039 +	DeleteEntry(_L("\\ANother\\FillerThree"),EFalse,EChainStd);
  1.2040 +	DeleteEntry(_L("\\test\\subdir1\\FillerTwo"),EFalse,EChainStd);
  1.2041 +	DeleteEntry(_L("\\test\\subdir1\\FillerOne"),EFalse,EChainStd);
  1.2042 +	r=TheFs.RmDir(_L("\\test\\subdir2\\"));
  1.2043 +	test(r==KErrNone);
  1.2044 +	r=TheFs.RmDir(_L("\\test\\subdir1\\"));
  1.2045 +	test(r==KErrNone);
  1.2046 +	r=TheFs.RmDir(_L("\\ANother\\"));
  1.2047 +	test(r==KErrNone);
  1.2048 +	r=TheFs.RmDir(_L("\\test\\"));
  1.2049 +	test(r==KErrNone);
  1.2050 +	r=TheFs.RmDir(_L("\\fat\\"));
  1.2051 +	test(r==KErrNone);
  1.2052 +	if (gFatBuf)
  1.2053 +		{
  1.2054 +		delete gFatBuf;
  1.2055 +		gFatBuf = NULL;
  1.2056 +		}
  1.2057 +	}
  1.2058 +#endif