diff -r a179b74831c9 -r c1f20ce4abcf kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp --- a/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp Thu Aug 19 11:14:22 2010 +0300 +++ b/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp Tue Aug 31 16:34:26 2010 +0300 @@ -11,9 +11,11 @@ // Contributors: // // Description: -// f32test\scndrv\t_scn32dr1.cpp +// f32test\filesystem\fat\t_scn32dr1.cpp +// Tests that ScanDrive fixes known errors to a Rugged FAT drive // -// + +#define __E32TEST_EXTENSION__ #include #include @@ -262,10 +264,10 @@ { pos += BootSector.ReservedSectors() * BootSector.BytesPerSector(); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TPtr8 buf(&data[0], 4); r=TheRawDisk.Read(pos, buf); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); } @@ -290,7 +292,7 @@ return val; } -LOCAL_C void WriteFat(TInt aFatIndex,TInt aValue,const TUint8* aFat) +LOCAL_C void WriteToFatBuf(TInt aFatIndex,TInt aValue,const TUint8* aFat) // // Write a value to both fats starting at aFat // @@ -344,7 +346,7 @@ { TInt nRes = ReadBootSector(TheFs, CurrentDrive(), KBootSectorNum<Des(); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); r=TheRawDisk.Read(gRootDirStart, ptr); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); DumpRootDir(buf->Ptr()); delete(buf); @@ -724,12 +726,12 @@ if (GetFatEntry(cluster, aFat) != 0) { HBufC8* buf=HBufC8::New(gBytesPerCluster); - test(buf!=NULL); + test_NotNull(buf); TPtr8 ptr=buf->Des(); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); r=TheRawDisk.Read(ClusterToByte(cluster), ptr); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); RDebug::Print(_L("Cluster %d @ 0x%08X:"), cluster, ClusterToByte(cluster)); DumpDirCluster(ptr.Ptr()); @@ -798,12 +800,12 @@ // { HBufC8* buf=HBufC8::New(gBytesPerCluster*2); - test(buf!=NULL); + test_NotNull(buf); TPtr8 ptr=buf->Des(); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); r=TheRawDisk.Read(ClusterToByte(aCluster), ptr); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); RDebug::Print(_L("Cluster %d @ 0x%08X:"), aCluster, ClusterToByte(aCluster)); TFatDirEntry* d = (TFatDirEntry*)ptr.Ptr() + aEntry; @@ -841,7 +843,7 @@ nRes = FormatFatDrive(TheFs, CurrentDrive(), ETrue); #endif - test(nRes == KErrNone); + test_KErrNone(nRes); } @@ -859,7 +861,7 @@ num[0] = TText(aDepth % 26 + 'A'); aDir+=num; r=TheFs.MkDir(aDir); - test(r==KErrNone); + test_KErrNone(r); } } @@ -872,7 +874,7 @@ while(aDepth--) { r=TheFs.RmDir(aDir); - test(r==KErrNone); + test_KErrNone(r); aDir.SetLength(aDir.Length()-2); } } @@ -889,7 +891,7 @@ aDir2=aDir1; aDir2+=_L("a\\"); TInt r=TheFs.MkDir(aDir2); - test(r==KErrNone); + test_KErrNone(r); // create dir with depth of 126 directories - one short of max depth CreateDeepDir(aDir1,101); // create dir with depth of 90 @@ -903,7 +905,7 @@ { DeleteDeepDir(aDir2,64); TInt r=TheFs.RmDir(aDir2); - test(r==KErrNone); + test_KErrNone(r); aDir2.SetLength(aDir2.Length()-2); DeleteDeepDir(aDir1,102); DeleteDeepDir(aDir1,24); @@ -937,7 +939,7 @@ aLong[len+1] = TText(count%26 + 'A'); count++; TInt r=temp.Create(TheFs,aLong,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); } } @@ -956,7 +958,7 @@ aLong[len+1] = TText(count%26 + 'A'); count++; TInt r=TheFs.Delete(aLong); - test(r==KErrNone || r==KErrNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound); } } @@ -978,7 +980,7 @@ name[2]=(TUint16)(count/26%26+'a'); name[3]=(TUint16)(count%26+'a'); r=TheFs.Delete(name); - test(r==KErrNone || r==KErrNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound); ++count; } } @@ -1002,7 +1004,7 @@ name[2]=(TUint16)(count/26%26+'a'); name[3]=(TUint16)(count%26+'a'); r=f.Create(TheFs, name, EFileWrite); - test(r==KErrNone); + test_KErrNone(r); f.Close(); ++count; } @@ -1024,7 +1026,7 @@ dir[1]=(TUint16)(count/26+'a'); dir[2]=(TUint16)(count%26+'a'); r=TheFs.MkDir(dir); - test(r==KErrNone); + test_KErrNone(r); entriesSoFar+=2; ++count; } @@ -1044,7 +1046,7 @@ dir[1]=TUint16(count/26+'a'); dir[2]=TUint16(count%26+'a'); r=TheFs.RmDir(dir); - test(r==KErrNone); + test_KErrNone(r); entriesSoFar-=2; ++count; } @@ -1057,27 +1059,27 @@ { test.Next(_L("Delete Directory Structure")); TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\almostfull\\")); - test(r==KErrNone); + test_KErrNone(r); TInt entriesNeeded=(gEntriesPerCluster-2) / 2; //7*2entries + . + .. = full sector for (TInt i = 0; i < entriesNeeded; i++) { TFileName file=_L("\\scndrv\\dir2\\full\\__a"); file.AppendNum(i); r=TheFs.Delete(file); - test(r==KErrNone||r==KErrNotFound); + test_Value(r, r==KErrNone||r==KErrNotFound); } r=TheFs.RmDir(_L("\\scndrv\\dir2\\full\\")); - test(r==KErrNone); + test_KErrNone(r); r=TheFs.RmDir(_L("\\scndrv\\dir2\\")); - test(r==KErrNone); + test_KErrNone(r); TFileName veryLongName=(_L("\\scndrv\\dir1\\")); MakeVeryLongName(veryLongName); r=TheFs.Delete(veryLongName); - test(r==KErrNone); + test_KErrNone(r); r=TheFs.RmDir(_L("\\scndrv\\dir1\\")); - test(r==KErrNone); + test_KErrNone(r); r=TheFs.RmDir(_L("\\scndrv\\")); - test(r==KErrNone); + test_KErrNone(r); } LOCAL_C void CreateDirectoryStructure() @@ -1088,34 +1090,34 @@ test.Next(_L("Create Directory Structure")); // cluster 3 (root dir is cluster 2) TInt r=TheFs.MkDir(_L("\\scndrv\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 4 r=TheFs.MkDir(_L("\\scndrv\\dir1\\")); - test(r==KErrNone); + test_KErrNone(r); TFileName veryLongName=(_L("\\scndrv\\dir1\\")); MakeVeryLongName(veryLongName); RFile f; // cluster 5 r=f.Create(TheFs,veryLongName,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); r=f.SetSize(512); - test(r==KErrNone); + test_KErrNone(r); f.Close(); // cluster 6 r=TheFs.MkDir(_L("\\scndrv\\dir2\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 7 r=TheFs.MkDir(_L("\\scndrv\\dir2\\full\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 8 r=TheFs.MkDir(_L("\\scndrv\\dir2\\somedirwith3entries\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 9 r=TheFs.MkDir(_L("\\scndrv\\dir2\\somedir2with3entries\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 10 r=TheFs.MkDir(_L("\\scndrv\\dir2\\almostfull\\")); - test(r==KErrNone); + test_KErrNone(r); // cluster 11-17 TInt entriesNeeded=(gEntriesPerCluster-2) / 2; //7*2entries + . + .. = full sector for (TInt i = 0; i < entriesNeeded; i++) @@ -1124,11 +1126,11 @@ file.AppendNum(i); LastInFull = file; r=f.Create(TheFs,file,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); if (i < 7) { r=f.SetSize(512); - test(r==KErrNone); + test_KErrNone(r); } f.Close(); } @@ -1144,14 +1146,14 @@ file1.AppendNum(1); file2.AppendNum(2); r=f.Create(TheFs,file1,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); r=f.SetSize(512); - test(r==KErrNone); + test_KErrNone(r); f.Close(); r=f.Create(TheFs,file2,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); r=f.SetSize(512); - test(r==KErrNone); + test_KErrNone(r); f.Close(); } @@ -1177,16 +1179,16 @@ // contains aOffset ExtBufLen = 2 * gBytesPerCluster; ExtBufPtr = HBufC8::New(ExtBufLen); - test(ExtBufPtr != NULL); + test_NotNull(ExtBufPtr); // read the clusters in ExtBufAdd = aOffset - aOffset % gBytesPerCluster; TInt clust = (ExtBufAdd - (gDataStartBytes - gRootDirStart)) /gBytesPerCluster + 2; RDebug::Print(_L("Extension buffer for cluster %d allocated"), clust); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TPtr8 des(ExtBufPtr->Des()); r=TheRawDisk.Read(gRootDirStart + ExtBufAdd, des); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); } // convert to offset in the extension buffer @@ -1221,10 +1223,10 @@ // reads directory section of disk into buffer // { - test(aCluster != 1); + test_Value(aCluster, aCluster != 1); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); if (aCluster == -1) // all clusters ? { @@ -1245,7 +1247,7 @@ r=TheRawDisk.Read(gRootDirStart + pos, dirPtr); } - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); } @@ -1255,21 +1257,21 @@ // { TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); r=TheRawDisk.Read(gFatStartBytes, aFatBuf); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); } -LOCAL_C void WriteDirDisk(TDes8& aDirBuf, TInt aCluster = -1) +LOCAL_C void WriteDirEntryToDisk(TDes8& aDirBuf, TInt aCluster = -1) // -// writes dir buffer to disk +// writes dir entry buffer to disk // { - test(aCluster != 1); + test_Value(aCluster, aCluster != 1); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); if (aCluster == -1) { @@ -1290,29 +1292,29 @@ r=TheRawDisk.Write(gRootDirStart + pos, dirPtr); } - test(r==KErrNone); + test_KErrNone(r); if (ExtBufPtr) { TPtr8 des(ExtBufPtr->Des()); r=TheRawDisk.Write(gRootDirStart + ExtBufAdd, des); - test(r==KErrNone); + test_KErrNone(r); } TheRawDisk.Close(); } -LOCAL_C void WriteFatDisk(TDes8& aFatBuf, TInt aStart=0) +LOCAL_C void WriteFatToDisk(TDes8& aFatBuf, TInt aStart=0) // // writes fat buffer to disk // { TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TInt fatCount=BootSector.NumberOfFats() - aStart; TInt pos = gFatStartBytes + aStart * gFatSizeSectors*BootSector.BytesPerSector(); while(fatCount--) { r=TheRawDisk.Write(pos, aFatBuf); - test(r==KErrNone); + test_KErrNone(r); pos += gFatSizeSectors*BootSector.BytesPerSector(); } TheRawDisk.Close(); @@ -1369,15 +1371,15 @@ gFatTestEntries = KMaxFatSize; gFatTestSize = PosInBytes(gFatTestEntries); FatBufPtr=HBufC8::New(gFatTestSize); - test(FatBufPtr!=NULL); + test_NotNull(FatBufPtr); DirBufPtr=HBufC8::New(DirBufferSize()); - test(DirBufPtr!=NULL); + test_NotNull(DirBufPtr); // Buffers for reading from disk FatDiskPtr=HBufC8::New(gFatTestSize); - test(FatDiskPtr!=NULL); + test_NotNull(FatDiskPtr); DirDiskPtr=HBufC8::New(DirBufferSize()); - test(DirDiskPtr!=NULL); + test_NotNull(DirDiskPtr); } LOCAL_C TBool IsSameAsDrive(const TDes8& aFatBuf,const TDes8& aDirBuf) @@ -1464,12 +1466,12 @@ else if (ExtBufPtr) { HBufC8* extPtr = HBufC8::New(ExtBufLen); - test(extPtr != NULL); + test_NotNull(extPtr); TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TPtr8 des(extPtr->Des()); r=TheRawDisk.Read(ExtBufAdd+gRootDirStart, des); - test(r==KErrNone); + test_KErrNone(r); TheRawDisk.Close(); TInt i = FindUnMatch(ExtBufPtr->Ptr(), extPtr->Ptr(), ExtBufLen); if (i >= 0) @@ -1518,7 +1520,7 @@ if(aAddEOfDir) WriteEndOfDir(aTrg.iBytePos+aTrg.iLength*KSizeOfFatDirEntry); TPtr8 dirBuf=DirBufPtr->Des(); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); } LOCAL_C TBool TestPartialEntry(TEntryInfo aEntry) @@ -1528,7 +1530,7 @@ { test.Next(_L("TestPartialEntry")); TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); WriteDelete(aEntry.iBytePos,aEntry.iLength); TPtr8 fatBuf=FatBufPtr->Des(); @@ -1551,7 +1553,7 @@ if(aAddEOfDir) WriteEndOfDir(aTrg.iBytePos+aTrg.iLength*KSizeOfFatDirEntry); TPtr8 dirBuf=DirBufPtr->Des(); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); } LOCAL_C TBool TestMatchingEntry(TEntryInfo aToDelete) @@ -1562,7 +1564,7 @@ test.Next(_L("TestMatchingEntries")); WriteDelete(aToDelete.iBytePos,aToDelete.iLength); TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TPtr8 fatBuf=FatBufPtr->Des(); TPtr8 dirBuf=DirBufPtr->Des(); @@ -1586,8 +1588,8 @@ CDir* dirs; // check no entries in the root directory TInt r=TheFs.GetDir(KRoot,KEntryAttMaskSupported,ESortNone,dirs); - test(r==KErrNone); - test(dirs->Count()==0); + test_KErrNone(r); + test_Equal(0,dirs->Count()); delete(dirs); dirs=NULL; @@ -1605,13 +1607,13 @@ RFile file; r=file.Replace(TheFs,TestFileName,EFileShareExclusive); - test(r==KErrNone); + test_KErrNone(r); file.Close(); // get short name TFileName shortName; r=TheFs.GetShortName(TestFileName,shortName); - test(r==KErrNone); + test_KErrNone(r); test(shortName==KOrigShortName); // must be first entry in root, modify to read like @@ -1620,26 +1622,26 @@ TInt bytePos=ClusterEntryToBytes(0,1); RRawDisk raw; r=raw.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TBuf8<1> buf(1); //-- change 2nd character in the short name (Fat DOS entry) buf[0]=(TUint8)'\xC4'; r=raw.Write(gRootDirStart+bytePos+1,buf); - test(r==KErrNone); + test_KErrNone(r); //-- fix the fiddled short name checksum in the corresponding VFat entry bytePos=ClusterEntryToBytes(0,0); buf[0]=(TUint8)0x2f; r=raw.Write(gRootDirStart+bytePos+13,buf); - test(r==KErrNone); + test_KErrNone(r); // retrieve short name from media. // Note: do not use RFs::GetShortName() as its behaviours are code page dependent. bytePos=ClusterEntryToBytes(0,1); TBuf8<11> shortNameBuf8; r=raw.Read(gRootDirStart+bytePos,shortNameBuf8); - test(r==KErrNone); + test_KErrNone(r); shortNameBuf8 = DosNameFromStdFormat(shortNameBuf8); shortName.Copy(shortNameBuf8); raw.Close(); @@ -1650,15 +1652,15 @@ //TheFs.SetDebugRegister(KFSYS); r=TheFs.ScanDrive(gSessionPath); TheFs.SetDebugRegister(0); - test(r==KErrNone); + test_KErrNone(r); DumpData(NULL, 0, 20); // retrieve short name from media. r=raw.Open(TheFs,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); bytePos=ClusterEntryToBytes(0,1); r=raw.Read(gRootDirStart+bytePos,shortNameBuf8); - test(r==KErrNone); + test_KErrNone(r); shortNameBuf8 = DosNameFromStdFormat(shortNameBuf8); shortName.Copy(shortNameBuf8); raw.Close(); @@ -1667,7 +1669,7 @@ // delete file r=TheFs.Delete(TestFileName); - test(r==KErrNone); + test_KErrNone(r); } LOCAL_C void TestMountAndScan() @@ -1680,46 +1682,47 @@ test.Next(_L("TestMountAndScan")); HBufC8* newFat=HBufC8::New(gFatTestSize); - test(newFat!=NULL); + test_NotNull(newFat); TPtr8 fat=newFat->Des(); TPtr8 origFat=FatBufPtr->Des(); TPtr8 origDir=DirBufPtr->Des(); // set cluster of \scndrv\dir1\ to a hanging cluster ReadFatDisk(fat); - WriteFat(gClusterDir1ext,35,fat.Ptr()); - WriteFat(35,36,fat.Ptr()); - WriteFatDisk(fat); + WriteToFatBuf(gClusterDir1ext,35,fat.Ptr()); + WriteToFatBuf(35,36,fat.Ptr()); + WriteFatToDisk(fat); // set the default path to something other than the current drive TFileName fsName; TInt r=TheFs.FileSystemName(fsName,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); TFileName origDefPath, newDefPath; r=TheFs.SessionPath(origDefPath); - test(r==KErrNone); + test_KErrNone(r); newDefPath=origDefPath; newDefPath[0]=(TText)'z'; r=TheFs.SetSessionPath(newDefPath); - test(r==KErrNone); + test_KErrNone(r); r = TheFs.ExtensionName(extName,gSessionPath[0]-'A',0); if (r == KErrNone) { primaryExtensionExists = ETrue; } r=TheFs.DismountFileSystem(fsName,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); // mount file system and check scandrive corrects error TBool isMount; if (primaryExtensionExists) r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount); else r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount); - test(isMount && r==KErrNone); + test(isMount); + test_KErrNone(r); TBool res=IsSameAsDrive(origFat,origDir); test(res); r=TheFs.SetSessionPath(origDefPath); - test(r==KErrNone); + test_KErrNone(r); delete newFat; } @@ -1733,14 +1736,14 @@ TBool primaryExtensionExists = EFalse; TFileName fsName; TInt r=TheFs.FileSystemName(fsName,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); r = TheFs.ExtensionName(extName,gSessionPath[0]-'A',0); if (r == KErrNone) { primaryExtensionExists = ETrue; } r=TheFs.DismountFileSystem(fsName,gSessionPath[0]-'A'); - test(r==KErrNone); + test_KErrNone(r); // RFs::MountFileSystemAndScan twice consecutively // first time @@ -1749,15 +1752,37 @@ r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount); else r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount); - test(isMount && r==KErrNone); + test(isMount); + test_KErrNone(r); // and a second time if (primaryExtensionExists) r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount); else r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount); - test(!isMount && r==KErrAccessDenied); + test(!isMount); + test_Equal(KErrAccessDenied,r); } + +static void CreateContiguousClusterChain(TUint32 aStartIndex, TUint32 aEndIndex, const TUint8* aFatPtr, TBool aMarkEoc) +/* + * Creates a contiguous cluster chain in the FAT buffer. + * + * @param aStartIndex The first cluster index of the chain + * aEndIndex The last cluster index of the chain + * aFatPtr FAT table buffer pointer + * aMarkEoc If ETrue, aEndIndex will be marked as EOC, else it will be a hanging cluster chain + */ + { + // Write cluster chain + for(TUint i=aStartIndex; iDes(); TPtr8 origFat=FatBufPtr->Des(); TPtr8 origDir=DirBufPtr->Des(); - // set cluster of \scndrv\dir1\ to a hanging cluster + // Set cluster of \scndrv\dir1\ to hanging cluster chain test.Start(_L("Test hanging cluster in \\scndrv\\dir1\\")); ReadFatDisk(fat); - WriteFat(gClusterDir1ext,35,fat.Ptr()); - WriteFat(35,36,fat.Ptr()); - WriteFatDisk(fat); + WriteToFatBuf(gClusterDir1ext,35,fat.Ptr()); + WriteToFatBuf(35,36,fat.Ptr()); + WriteFatToDisk(fat); // gClusterDir1ext->35->36 TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TBool res=IsSameAsDrive(origFat,origDir); test(res); - // set cluster chain of first entry of \scndrv\dir1\ to + // Set cluster chain of first entry of \scndrv\dir1\ to // larger size than file size test.Next(_L("Test hanging cluster in first entry")); ReadFatDisk(fat); - WriteFat(gClusterDir1ext,39,fat.Ptr()); - WriteFat(39,500,fat.Ptr()); - WriteFat(500,gEndOfChain,fat.Ptr()); - WriteFatDisk(fat); + WriteToFatBuf(gClusterDir1ext,39,fat.Ptr()); + WriteToFatBuf(39,500,fat.Ptr()); + CreateContiguousClusterChain(500, 505, fat.Ptr(), ETrue); + WriteFatToDisk(fat); // gClusterDir1ext->39->500->501->502->503->504->505->EOC r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(origFat,origDir); test(res); - // set cluster of \scndrv\ to a hanging cluster + // Set cluster of \scndrv\ to a hanging cluster test.Next(_L("Test hanging cluster of \\scndrv\\")); ReadFatDisk(fat); - WriteFat(gClusterScnDrv,511,fat.Ptr()); - WriteFatDisk(fat); + WriteToFatBuf(gClusterScnDrv,511,fat.Ptr()); + WriteFatToDisk(fat); // gClusterScnDrv->511 r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(origFat,origDir); test(res); @@ -1815,7 +1840,7 @@ { test.Next(_L("Check lost clusters")); HBufC8* newFat=HBufC8::New(gFatTestSize); - test(newFat!=NULL); + test_NotNull(newFat); TPtr8 fat=newFat->Des(); TPtr8 origFat=FatBufPtr->Des(); TPtr8 origDir=DirBufPtr->Des(); @@ -1825,12 +1850,10 @@ // write cluster chain test.Start(_L("Test removal of lost cluster chain")); ReadFatDisk(fat); - for(TInt i=25;i<35;++i) - WriteFat(i,i+1,fat.Ptr()); - WriteFat(35,gEndOfChain,fat.Ptr()); - WriteFatDisk(fat); + CreateContiguousClusterChain(25, 35, fat.Ptr(), ETrue); + WriteFatToDisk(fat); // 25->26->27->28->29->30->31->32->33->34->35->EOC TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TBool res=IsSameAsDrive(origFat,origDir); test(res); @@ -1841,17 +1864,17 @@ TInt off = j*BootSector.BytesPerSector()+j*7%512; fat[off]=1; } - WriteFatDisk(fat); + WriteFatToDisk(fat); r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(origFat,origDir); test(res); // write semi-random changes to second fat test.Next(_L("Test semi-random changes to second fat")); - WriteFatDisk(fat, 1); + WriteFatToDisk(fat, 1); r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(origFat,origDir); test(res); @@ -1859,6 +1882,74 @@ test.End(); } + +static void DoHangingAndLostClusters() +/* + * Tests that ScanDrive fixes MULTIPLE hanging clusters and removes lost clusters. + * It creates multiple hanging and lost cluster chains in the FAT table and + * expects ScanDrive to fix them all. + */ + { + test.Start(_L("Check multiple hanging and lost cluster chains")); + HBufC8* newFat = HBufC8::New(gFatTestSize); + test_NotNull(newFat); + TPtr8 fat = newFat->Des(); + TPtr8 origFat = FatBufPtr->Des(); + TPtr8 origDir = DirBufPtr->Des(); + ReadFatDisk(origFat); + ReadDirDisk(origDir); + + test.Printf(_L("Create multiple hanging cluster chains\n")); + ReadFatDisk(fat); + // Set hanging cluster for the file in \scndrv\dir1 + // gClusterDir1ext+1->25->26->27->28->29->30->31->32->33->34->35 + WriteToFatBuf(gClusterDir1ext+1, 25, fat.Ptr()); + CreateContiguousClusterChain(25, 35, fat.Ptr(), EFalse); + // Set hanging cluster for the first file in \scndrv\dir2 + // gClusterDir2_AFull+1->249->250->53->54->55->EOC + WriteToFatBuf(gClusterDir2_AFull+1, 249, fat.Ptr()); + WriteToFatBuf(249, 250, fat.Ptr()); + WriteToFatBuf(250, 53, fat.Ptr()); + CreateContiguousClusterChain(53, 55, fat.Ptr(), ETrue); + // Set hanging cluster for the fourth file in \scndrv\dir2 + // gClusterDir2_AFull+4->59->60->61->62->63 + WriteToFatBuf(gClusterDir2_AFull+4, 59, fat.Ptr()); + CreateContiguousClusterChain(59, 63, fat.Ptr(), EFalse); + // Set hanging cluster for the second file in \scndrv\dir2 + // gClusterDir2_AFull+2->67->68->69->EOC + WriteToFatBuf(gClusterDir2_AFull+2, 67, fat.Ptr()); + CreateContiguousClusterChain(67, 69, fat.Ptr(), ETrue); + + test.Printf(_L("Create multiple lost clusters\n")); + // Create 1st lost cluster chain (clusters 36-45) + CreateContiguousClusterChain(36, 45, fat.Ptr(), ETrue); + // Create 2nd lost cluster chain (clusters 246-248,56-58) + CreateContiguousClusterChain(246, 248, fat.Ptr(), EFalse); + WriteToFatBuf(248, 56, fat.Ptr()); + CreateContiguousClusterChain(56, 58, fat.Ptr(), ETrue); + // Create 3rd lost cluster chain (clusters 251-253,564-566, with hanging end) + CreateContiguousClusterChain(251, 253, fat.Ptr(), EFalse); + WriteToFatBuf(253, 564, fat.Ptr()); + CreateContiguousClusterChain(564, 566, fat.Ptr(), EFalse); + + // Flush all FAT changes to the media + WriteFatToDisk(fat); + + test.Next(_L("Test ScanDrive fixes multiple hanging and lost cluster chains")); + TInt r = TheFs.CheckDisk(gSessionPath); // CheckDisk should detect an error + test_Value(r, r != KErrNone); + r = TheFs.ScanDrive(gSessionPath); // ScanDrive should find the errors and fix them + test_KErrNone(r); + r = TheFs.CheckDisk(gSessionPath); + test_KErrNone(r); + TBool res = IsSameAsDrive(origFat, origDir); + test(res); + + delete newFat; + test.End(); + } + + LOCAL_C void DoPartEntries() // // Tests that scandrive detects/corrects partial entries @@ -1872,9 +1963,9 @@ TPtr8 dirBuf=DirBufPtr->Des(); TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedirwith3entries\\")); - test(r==KErrNone || r==KErrNotFound || KErrPathNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound || r==KErrPathNotFound); r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedir2with3entries\\")); - test(r==KErrNone || r==KErrNotFound || KErrPathNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound || r==KErrPathNotFound); if (BootSector.RootDirEntries() != 0) { @@ -1883,7 +1974,7 @@ test.Next(_L("Partial entry at end of rootdir")); FillUpRootDir(2); r=temp.Create(TheFs,_L("\\temp"),EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); ReadDirDisk(dirBuf); ReadFatDisk(fatBuf); @@ -1903,7 +1994,7 @@ CreatePartialEntry(partial2,3,EFalse); // entry has been allocated a cluster which scandrive should delete along with partial entry if (last > 0) - WriteFat(last,0,fatBuf.Ptr()); + WriteToFatBuf(last,0,fatBuf.Ptr()); res=TestPartialEntry(partial2); test(res); @@ -1911,26 +2002,26 @@ test.Next(_L("Test directory reclaim")); last = GetStartCluster(gClusterDir2_Full,gEntriesPerCluster-2); WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2)); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); TInt entry = GetFatEntry(gClusterDir2_Full, fatBuf.Ptr()); - WriteFat(gClusterDir2_Full,gEndOfChain,fatBuf.Ptr()); + WriteToFatBuf(gClusterDir2_Full,gEndOfChain,fatBuf.Ptr()); while (entry && (entry & gEndOfChain) != gEndOfChain) { TInt next = GetFatEntry(entry, fatBuf.Ptr()); - WriteFat(entry,0,fatBuf.Ptr()); + WriteToFatBuf(entry,0,fatBuf.Ptr()); entry = next; } if (last > 0) - WriteFat(last,0,fatBuf.Ptr()); + WriteToFatBuf(last,0,fatBuf.Ptr()); r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(fatBuf,dirBuf); test(res); // use last entry of first cluster in \scndrv\dir2\full\ test.Next(_L("Partial entry at end of subdir")); r=temp.Create(TheFs,_L("\\scndrv\\dir2\\full\\temp"),EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); ReadDirDisk(dirBuf); ReadFatDisk(fatBuf); @@ -1943,12 +2034,12 @@ test.Next(_L("Partial entry preceeding end-of-dir marker")); last = GetStartCluster(gClusterDir2_AFull,14); if (last > 0) - WriteFat(last,0,fatBuf.Ptr()); + WriteToFatBuf(last,0,fatBuf.Ptr()); last = GetStartCluster(gClusterDir2_AFull,8); if (last > 0) - WriteFat(last,0,fatBuf.Ptr()); + WriteToFatBuf(last,0,fatBuf.Ptr()); WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_AFull,14)); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); TEntryInfo partial4(ClusterEntryToBytes(gClusterDir2_AFull,8),6); CreatePartialEntry(partial4,4,EFalse); res=TestPartialEntry(partial4); @@ -1964,14 +2055,14 @@ // create entry in \scndrv\dir2\almostfull\ // test.Next(_L("Partial entry with invalid dos name")); // r=temp.Create(TheFs,_L("\\scndrv\\dir2\\almostfull\\Dodgy file name"),EFileShareAny); -// test(r==KErrNone); +// test_KErrNone(r); // temp.Close(); // ReadDirDisk(dirBuf); // TInt dosStart=ClusterEntryToBytes(gClusterDir2_AFull,4); // dirBuf[dosStart+4]=0x1; // WriteDirDisk(dirBuf); // r=TheFs.ScanDrive(gSessionPath); -// test(r==KErrNone); +// test_KErrNone(r); // WriteDelete(dosStart-2*32,3); // res=IsSameAsDrive(fatBuf,dirBuf); // test(res); @@ -1983,26 +2074,26 @@ last = GetStartCluster(gClusterDir2_Full,gEntriesPerCluster-1); WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2)); WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-1)); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); TFileName longFile=_L("\\scndrv\\dir2\\full\\"); MakeVeryLongName(longFile); r=temp.Create(TheFs,longFile,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); ReadDirDisk(dirBuf); - WriteFat(gClusterDir2_Full,gClusterDir2_SD3E,fatBuf.Ptr()); - WriteFat(gClusterDir2_SD3E,gClusterDir2_SD23E,fatBuf.Ptr()); - WriteFat(gClusterDir2_SD23E,gEndOfChain,fatBuf.Ptr()); + WriteToFatBuf(gClusterDir2_Full,gClusterDir2_SD3E,fatBuf.Ptr()); + WriteToFatBuf(gClusterDir2_SD3E,gClusterDir2_SD23E,fatBuf.Ptr()); + WriteToFatBuf(gClusterDir2_SD23E,gEndOfChain,fatBuf.Ptr()); if (last > 0) - WriteFat(last,0,fatBuf.Ptr()); + WriteToFatBuf(last,0,fatBuf.Ptr()); TEntryInfo partial5(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2),19); CreatePartialEntry(partial5,7,EFalse); res=TestPartialEntry(partial5); test(res); r=TheFs.Delete(longFile); - test(r==KErrNone || r==KErrNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound); r=TheFs.Delete(_L("\\temp")); - test(r==KErrNone || r==KErrNotFound); + test_Value(r, r==KErrNone || r==KErrNotFound); } ReadDirDisk(dirBuf); @@ -2052,16 +2143,16 @@ test.Next(_L("matching entries in same subdir")); // delete entries to allow contiguous clusters in \scndrv\dir2\full directory TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedirwith3entries\\")); - test(r==KErrNone); + test_KErrNone(r); r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedir2with3entries\\")); - test(r==KErrNone); + test_KErrNone(r); // ensure directory is expanded RFile temp; r=temp.Create(TheFs,_L("\\scndrv\\dir2\\full\\temp"),EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); r=TheFs.Delete(_L("\\scndrv\\dir2\\full\\temp")); - test(r==KErrNone); + test_KErrNone(r); ReadDirDisk(dirBuf); ReadFatDisk(fatBuf); TEntryInfo from4(ClusterEntryToBytes(gClusterDir2_Full,4),2); @@ -2074,14 +2165,14 @@ test.Next(_L("matching entries in diff dirs + new cluster")); // delete last entry in directory r=TheFs.Delete(LastInFull); - test(r==KErrNone); + test_KErrNone(r); TFileName veryLongName=_L("\\scndrv\\dir2\\full\\"); MakeVeryLongName(veryLongName); r=temp.Create(TheFs,veryLongName,EFileShareAny); - test(r==KErrNone); + test_KErrNone(r); temp.Close(); r=TheFs.Delete(veryLongName); - test(r==KErrNone); + test_KErrNone(r); ReadDirDisk(dirBuf); ReadFatDisk(fatBuf); TEntryInfo from5(ClusterEntryToBytes(gClusterDir1,2),19); @@ -2111,7 +2202,7 @@ ReadFatDisk(fatBuf); // run scandisk and compare TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TBool res=IsSameAsDrive(fatBuf,dirBuf); test(res); // Create a entry with matching start cluster and check fixed up @@ -2138,7 +2229,7 @@ ReadFatDisk(fatBuf); TInt r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TBool res=IsSameAsDrive(fatBuf,dirBuf); test(res); @@ -2231,9 +2322,9 @@ name.AppendNumFixedWidth(i+totalFilesCreated, EHex, 3); RFile f; r = f.Create(TheFs, name, EFileShareAny); - test(r == KErrNone); + test_KErrNone(r); r = f.Write(buf); - test(r == KErrNone); + test_KErrNone(r); f.Close(); } @@ -2266,7 +2357,7 @@ } - WriteDirDisk(dirBuf, cluster); + WriteDirEntryToDisk(dirBuf, cluster); totalFilesCreated += filesThisTime; test.Printf(_L(" created %d entries\n"), totalFilesCreated); } @@ -2278,7 +2369,7 @@ test.Printf(_L("Running ScanDrive\n"), filesThisTime); r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); TBool res=IsSameAsDrive(fatBuf,dirBuf); test(res); @@ -2290,17 +2381,17 @@ name.Append(_L("tempfile.")); name.AppendNumFixedWidth(i, EHex, 3); r = TheFs.Delete(name); - test(r == KErrNone); + test_KErrNone(r); } ReadDirDisk(dirBuf); ReadFatDisk(fatBuf); WriteEndOfDir(ClusterEntryToBytes(cluster, startEntry)); - WriteDirDisk(dirBuf); + WriteDirEntryToDisk(dirBuf); test.Printf(_L("Running ScanDrive\n"), filesThisTime); r=TheFs.ScanDrive(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); res=IsSameAsDrive(fatBuf,dirBuf); test(res); } @@ -2341,6 +2432,7 @@ DoPartEntries(); DoLostClusters(); DoHangingClusters(); + DoHangingAndLostClusters(); TestMountAndScan(); TestConsecutiveMountAndScans(); DeleteDirectoryStructure(); @@ -2362,7 +2454,7 @@ { TInt r; r = TheFs.CharToDrive(gSessionPath[0], gDriveNumber); - test( KErrNone == r ); + test_KErrNone(r); //-- set up console output @@ -2380,7 +2472,7 @@ // check this is not the internal ram drive TVolumeInfo v; r=TheFs.Volume(v); - test(r==KErrNone); + test_KErrNone(r); if(v.iDrive.iMediaAtt&KMediaAttVariableSize) { test.Printf(_L("Error: Internal ram drive not tested\n")); @@ -2388,7 +2480,7 @@ } r=TheFs.SetSessionPath(gSessionPath); - test(r==KErrNone); + test_KErrNone(r); DoTests();