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