userlibandfileserver/fileserver/sfat32/sl_scan32.cpp
changeset 90 947f0dc9f7a8
parent 36 538db54a451d
child 102 ef2a444a7410
child 149 d9f1e5bfe28c
--- 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,User::Leave(KErrCorrupt));
+	
+    if(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<TInt>(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);
         }