diff -r 2d65c2f76d7b -r 947f0dc9f7a8 userlibandfileserver/fileserver/sfat32/sl_scan32.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_scan32.cpp Tue Feb 02 01:24:03 2010 +0200 +++ b/userlibandfileserver/fileserver/sfat32/sl_scan32.cpp Fri Apr 16 16:24:37 2010 +0300 @@ -277,7 +277,7 @@ CheckDirStructureL(); - //-- uncomments a line below if you need to compare real and restored FAT tables and print out all differences + //-- uncomment a line below if you need to compare real and restored FAT tables and print out all differences //CompareFatsL(EFalse); //timeEnd.UniversalTime(); //-- take end time @@ -363,7 +363,11 @@ } } - __ASSERT_ALWAYS(err==KErrNone,User::Leave(KErrNotFound)); + if(err != KErrNone) + { + __PRINT1(_L("CScanDrive::FindSameStartClusterL() #1 %d"), err); + User::Leave(KErrNotFound); + } } //---------------------------------------------------------------------------------------------------- @@ -374,21 +378,32 @@ @return System wide error value @leave */ -TInt CScanDrive::FindStartClusterL(TInt aDirCluster) +TInt CScanDrive::FindStartClusterL(TUint32 aDirCluster) { __PRINT1(_L("CScanDrive::FindStartCluster dirCluster=%d"),aDirCluster); - __ASSERT_ALWAYS(aDirCluster>=iMount->RootIndicator(),User::Leave(KErrCorrupt)); + + if(aDirCluster < (TUint)iMount->RootIndicator() || aDirCluster >= MaxClusters()) + { + __PRINT(_L("CScanDrive::FindStartCluster() #!\n")); + IndicateErrorsFound(EBadClusterNumber); + User::Leave(KErrCorrupt); + } + + if(++iRecursiveDepth==KMaxScanDepth) { --iRecursiveDepth; return(KErrNotFound); } + TEntryPos entryPos(aDirCluster,0); TInt dirEntries=0; - FOREVER + + for(;;) { TFatDirEntry entry; ReadDirEntryL(entryPos,entry); + if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased()) { if(IsEndOfRootDir(entryPos)) @@ -396,12 +411,20 @@ MoveToNextEntryL(entryPos); continue; } + if(entry.IsEndOfDirectory()) break; - TBool isComplete; + TEntryPos vfatPos=entryPos; - isComplete=MoveToVFatEndL(entryPos,entry,dirEntries); - __ASSERT_ALWAYS(isComplete,User::Leave(KErrBadName)); + const TBool isComplete = MoveToVFatEndL(entryPos,entry,dirEntries); + + if(!isComplete) + { + __PRINT(_L("CScanDrive::FindStartCluster() #2\n")); + IndicateErrorsFound(EEntrySetIncomplete); + User::Leave(KErrBadName); + } + TInt err=CheckEntryClusterL(entry,vfatPos); if(err==KErrNone) @@ -440,7 +463,7 @@ else if(aEntry.Attributes()&KEntryAttDir) return(FindStartClusterL(iMount->StartCluster(aEntry))); - return(KErrNotFound); + return KErrNotFound; } //---------------------------------------------------------------------------------------------------- @@ -526,6 +549,7 @@ if(!isComplete && CheckDiskMode()) {//-- broken VFAT entryset; in CheckDisk mode this is the FS error, abort further activity + __PRINT(_L("CScanDrive::CheckDirL() #1")); IndicateErrorsFound(EInvalidEntrySize); User::Leave(KErrCorrupt); } @@ -577,13 +601,18 @@ void CScanDrive::ProcessEntryL(const TFatDirEntry& aEntry) { __PRINT(_L("CScanDrive::ProcessEntryL")); - TInt entryAtt=aEntry.Attributes(); + const TUint entryAtt=aEntry.Attributes(); - __ASSERT_ALWAYS(!(entryAtt&~KEntryAttMaskSupported)&&!aEntry.IsErased(),User::Leave(KErrCorrupt)); + if((entryAtt & ~KEntryAttMaskSupported) || aEntry.IsErased()) + { + __PRINT1(_L("CScanDrive::ProcessEntryL() wrong entry att: 0x%x"), entryAtt); + IndicateErrorsFound(EEntryBadAtt); + User::Leave(KErrCorrupt); + } if(!(entryAtt&(KEntryAttDir|KEntryAttVolume)) && iMount->StartCluster(aEntry)>0) {//-- this is a file with length >0. Check that its cluster chain corresponds to its size - RecordClusterChainL(iMount->StartCluster(aEntry),(TUint) aEntry.Size()); + RecordClusterChainL(iMount->StartCluster(aEntry), aEntry.Size()); } else if(entryAtt&KEntryAttDir) {//-- this is the directory, walk into it @@ -601,34 +630,52 @@ @param aSizeInBytes Size of the file or directory in bytes @leave System wide error values */ -void CScanDrive::RecordClusterChainL(TInt aCluster, TUint aSizeInBytes) +void CScanDrive::RecordClusterChainL(TUint32 aCluster, TUint aSizeInBytes) { __PRINT2(_L("CScanDrive::RecordClusterChainL() cl:%d, sz:%d") ,aCluster, aSizeInBytes); - __ASSERT_ALWAYS(aCluster>0, User::Leave(KErrCorrupt)); + + if(aCluster < KFatFirstSearchCluster || aCluster >= MaxClusters()) + { + __PRINT(_L("CScanDrive::RecordClusterChainL() #0")); + IndicateErrorsFound(EBadClusterNumber); + User::Leave(KErrCorrupt); + } TUint clusterCount; if(aSizeInBytes==0) + { clusterCount=1; + } else { const TUint64 tmp = aSizeInBytes + Pow2_64(iMount->ClusterSizeLog2()) - 1; clusterCount = (TUint) (tmp >> iMount->ClusterSizeLog2()); } - TInt startCluster=aCluster; + TUint startCluster=aCluster; + while(clusterCount) { if(IsClusterUsedL(aCluster)) {//-- this cluster already seems to belong to some other object; crosslinked cluster chain. Can't fix it. - if(CheckDiskMode()) + __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); + + if(CheckDiskMode()) {//-- in check disk mode this is a FS error; Indicate error and abort furter scanning - __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); + __PRINT(_L("CScanDrive::RecordClusterChainL #1.1")); IndicateErrorsFound(EClusterAlreadyInUse); User::Leave(KErrCorrupt); } - __ASSERT_ALWAYS(!IsDirError() && iMatching.iStartCluster==0 && aCluster==startCluster,User::Leave(KErrCorrupt)); + + if(IsDirError() || iMatching.iStartCluster > 0 || aCluster != startCluster) + {//-- secondary entry into this state + __PRINT(_L("CScanDrive::RecordClusterChainL #1.2")); + IndicateErrorsFound(EClusterAlreadyInUse); + User::Leave(KErrCorrupt); + } + iMatching.iStartCluster=aCluster; iDirError=EScanMatchingEntry; //ERROR POINT IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors @@ -637,10 +684,10 @@ if(clusterCount==1) - { + {//-- we have reached the end of the cluster chain if(!iMount->IsEndOfClusterCh(ReadFatL(aCluster))) - {//-- seems to be a rugged FAT artefact; File truncation had failed before and now file length is less than - //-- the corresponding cluster chain shall be. It will be truncated. + {//-- seems to be a rugged FAT artefact; File truncation/extension had failed before and now file length is less than + //-- the corresponding cluster chain shall be. It will be truncated to the size recorded in file DOS entry. iTruncationCluster = aCluster; if(CheckDiskMode()) @@ -660,8 +707,14 @@ const TUint clusterVal=ReadFatL(aCluster); //__PRINT2(_L("#--: %d -> %d"), aCluster, clusterVal); - - __ASSERT_ALWAYS(!IsEofF(clusterVal) && clusterVal !=KSpareCluster, User::Leave(KErrCorrupt)); + if(IsEofF(clusterVal) || clusterVal == KSpareCluster ) + {//-- unexpected end of the cluster chain (it is shorter than recorded in file dir. entry) + __PRINT1(_L("CScanDrive::RecordClusterChainL #3 %d"),clusterVal); + IndicateErrorsFound(EBadClusterValue); + User::Leave(KErrCorrupt); + } + + MarkClusterUsedL(aCluster); aCluster=clusterVal; --clusterCount; @@ -688,9 +741,16 @@ return IsDosEntry(aEntry); TInt toFollow=aEntry.NumFollowing(); - __ASSERT_ALWAYS(toFollow>0 && !aEntry.IsErased(), User::Leave(KErrCorrupt)); - FOREVER + if(toFollow <=0 || aEntry.IsErased()) + { + __PRINT1(_L("CScanDrive::MoveToVFatEndL #1 %d"),toFollow); + IndicateErrorsFound(EEntrySetIncomplete); + User::Leave(KErrCorrupt); + } + + + for(;;) { MoveToNextEntryL(aPos); ReadDirEntryL(aPos,aEntry); @@ -731,7 +791,7 @@ */ TBool CScanDrive::IsDosEntry(const TFatDirEntry& aEntry)const { - TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory(); + const TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory(); return res; } @@ -746,7 +806,13 @@ void CScanDrive::AddPartialVFatL(const TEntryPos& aStartPos, const TFatDirEntry& aEntry) { __PRINT2(_L("CScanDrive::AddPartialVFatL cluster=%d pos=%d"),aStartPos.iCluster,aStartPos.iPos); - __ASSERT_ALWAYS(!IsDirError(),User::Leave(KErrCorrupt)); + + if(IsDirError()) + { + __PRINT(_L("CScanDrive::AddPartialVFatL #1")); + User::Leave(KErrCorrupt); + } + iPartEntry.iEntryPos=aStartPos; iPartEntry.iEntry=aEntry; iDirError=EScanPartEntry; @@ -763,7 +829,14 @@ TBool CScanDrive::AddMatchingEntryL(const TEntryPos& aEntryPos) { __PRINT2(_L("CScanDrive::AddMatchingEntryL cluster=%d pos=%d"),aEntryPos.iCluster,aEntryPos.iPos); - __ASSERT_ALWAYS(iMatching.iStartCluster>0 && iMatching.iCount= KMaxMatchingEntries) + { + __PRINT(_L("CScanDrive::AddMatchingEntryL #1")); + User::Leave(KErrCorrupt); + } + + iMatching.iEntries[iMatching.iCount++]=aEntryPos; return iMatching.iCount==KMaxMatchingEntries; } @@ -886,10 +959,13 @@ if(!IsDosEntry(entry)) { TInt toMove=entry.NumFollowing(); + while(toMove--) MoveToNextEntryL(aVFatPos); + ReadDirEntryL(aVFatPos,entry); } + return(entry.RuggedFatEntryId()); } @@ -916,15 +992,24 @@ { __PRINT1(_L("CScanDrive::FixMatchingEntryL() start cluster=%d"),iMatching.iStartCluster); - __ASSERT_ALWAYS(iMatching.iCount==KMaxMatchingEntries,User::Leave(KErrCorrupt)); + + if(iMatching.iCount != KMaxMatchingEntries) + { + __PRINT1(_L("CScanDrive::FixMatchingEntryL() #1 %d"), iMatching.iCount); + User::Leave(KErrCorrupt); + } + ASSERT(!CheckDiskMode()); - TInt idOne=GetReservedidL(iMatching.iEntries[0]); - TInt idTwo=GetReservedidL(iMatching.iEntries[1]); + const TInt idOne=GetReservedidL(iMatching.iEntries[0]); + const TInt idTwo=GetReservedidL(iMatching.iEntries[1]); TFatDirEntry entry; - TInt num=idOne>idTwo?0:1; + + const TInt num = idOne>idTwo ? 0:1; ReadDirEntryL(iMatching.iEntries[num],entry); + iMount->EraseDirEntryL(iMatching.iEntries[num],entry); + IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors } @@ -964,6 +1049,7 @@ if(iClusterListArray[iListArrayIndex]==NULL) iClusterListArray[iListArrayIndex]=new(ELeave) RArray(KClusterListGranularity); + iClusterListArray[iListArrayIndex]->Append(aCluster); } @@ -1111,6 +1197,7 @@ { if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters()) { + __PRINT1(_L("CScanDrive::ReadFatL() bad cluster:%d\n"),aClusterNum); IndicateErrorsFound(EBadClusterNumber); User::Leave(KErrCorrupt); } @@ -1129,6 +1216,7 @@ { if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters()) { + __PRINT1(_L("CScanDrive::MarkClusterUsedL() bad cluster:%d\n"),aClusterNum); IndicateErrorsFound(EBadClusterNumber); User::Leave(KErrCorrupt); } @@ -1145,6 +1233,7 @@ { if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters()) { + __PRINT1(_L("CScanDrive::IsClusterUsedL() bad cluster:%d\n"),aClusterNum); IndicateErrorsFound(EBadClusterNumber); User::Leave(KErrCorrupt); }