userlibandfileserver/fileserver/sfat32/sl_scan32.cpp
changeset 109 b3a1d9898418
parent 102 ef2a444a7410
equal deleted inserted replaced
102:ef2a444a7410 109:b3a1d9898418
    70 void CScanDrive::ConstructL(CFatMountCB* aMount)
    70 void CScanDrive::ConstructL(CFatMountCB* aMount)
    71     {
    71     {
    72     ASSERT(aMount);
    72     ASSERT(aMount);
    73 
    73 
    74     //--- setting up 
    74     //--- setting up 
    75     iMount=aMount;
    75 	iMount			 = aMount;
    76     iGenericError = ENoErrors;
    76 	iGenericError	 = ENoErrors;
    77     iDirError     = ENoDirError;  
    77 	iDirError		 = ENoDirError;
    78     iMaxClusters  = iMount->UsableClusters()+KFatFirstSearchCluster; //-- UsableClusters() doesn't count first 2 unused clusers
    78 	iHangingClusters = 0;
       
    79 	iMaxClusters	 = iMount->UsableClusters()+KFatFirstSearchCluster; //-- UsableClusters() doesn't count first 2 unused clusers
    79     //------------------------------
    80     //------------------------------
    80 	
    81 	
    81     //-- create bit vectors that will represent FAT on media and reconstructed by ScanDrive. Each bit in the vector represents 1 FAT cluster.
    82     //-- create bit vectors that will represent FAT on media and reconstructed by ScanDrive. Each bit in the vector represents 1 FAT cluster.
    82     const TUint32 KClustersNum = MaxClusters();
    83     const TUint32 KClustersNum = MaxClusters();
    83 
    84 
   107     for(TInt i=KFatFirstSearchCluster; i<KMaxClusters; ++i)
   108     for(TInt i=KFatFirstSearchCluster; i<KMaxClusters; ++i)
   108 	    {
   109 	    {
   109         const TUint32 nFatEntry = ReadFatL(i);
   110         const TUint32 nFatEntry = ReadFatL(i);
   110        
   111        
   111         //-- each '1' bit represents a used cluster 
   112         //-- each '1' bit represents a used cluster 
   112         if(nFatEntry != KSpareCluster) 
   113         if(nFatEntry != KSpareCluster)
   113             iMediaFatBits.SetBit(i);
   114             iMediaFatBits.SetBit(i);
   114 	    }
   115 	    }
   115     }
   116     }
   116 
   117 
   117 //----------------------------------------------------------------------------------------------------
   118 //----------------------------------------------------------------------------------------------------
   123 void CScanDrive::DoParseFat32Buf(const TPtrC8& aBuf, TUint32& aCurrFatEntry)
   124 void CScanDrive::DoParseFat32Buf(const TPtrC8& aBuf, TUint32& aCurrFatEntry)
   124     {
   125     {
   125     ASSERT((aBuf.Size() & (sizeof(TFat32Entry)-1)) == 0);
   126     ASSERT((aBuf.Size() & (sizeof(TFat32Entry)-1)) == 0);
   126     
   127     
   127     const TInt KNumEntries = aBuf.Size() >> KFat32EntrySzLog2;
   128     const TInt KNumEntries = aBuf.Size() >> KFat32EntrySzLog2;
   128     const TFat32Entry* const pFatEntry = (const TFat32Entry*)(aBuf.Ptr()); 
   129     const TFat32Entry* const pFatEntry = (const TFat32Entry*)(aBuf.Ptr());
   129 
   130 
   130     for(TInt i=0; i<KNumEntries; ++i)
   131     for(TInt i=0; i<KNumEntries; ++i)
   131         {
   132         {
   132         if(aCurrFatEntry >= KFatFirstSearchCluster)
   133         if(aCurrFatEntry >= KFatFirstSearchCluster)
   133             {
   134             {
   159 
   160 
   160     const TUint32 KFatBufSz = 32*K1KiloByte; //-- buffer size for FAT reading. 32K seems to be optimal size
   161     const TUint32 KFatBufSz = 32*K1KiloByte; //-- buffer size for FAT reading. 32K seems to be optimal size
   161 
   162 
   162     iMediaFatBits.Fill(0);
   163     iMediaFatBits.Fill(0);
   163 
   164 
   164     RBuf8 buf;
   165     RBuf8 fatParseBuf;
   165     CleanupClosePushL(buf);
   166     CleanupClosePushL(fatParseBuf);
   166 
   167 
   167     //-- allocate memory for FAT parse buffer
   168     //-- allocate memory for FAT parse buffer
   168     buf.CreateMaxL(KFatBufSz);
   169     fatParseBuf.CreateMaxL(KFatBufSz);
   169 
   170 
   170     //-- read FAT directly from the media into the large buffer and parse it
   171     //-- read FAT directly from the media into the large buffer and parse it
   171     TUint32 rem = KFatSize;
   172     TUint32 rem = KFatSize;
   172     TUint32 mediaPos = KFat1StartPos;   
   173     TUint32 mediaPos = KFat1StartPos;   
   173     TUint32 currFatEntry = 0;
   174     TUint32 currFatEntry = 0;
   174 
   175 
   175     while(rem)
   176     while(rem)
   176         {
   177         {
   177         const TUint32 bytesToRead=Min(rem, KFatBufSz);
   178         const TUint32 bytesToRead=Min(rem, KFatBufSz);
   178         TPtrC8 ptrData(buf.Ptr(), bytesToRead);
   179         TPtrC8 ptrData(fatParseBuf.Ptr(), bytesToRead);
   179 
   180 
   180         //-- read portion of the FAT into buffer
   181         //-- read portion of the FAT into buffer
   181         User::LeaveIfError(iMount->LocalDrive()->Read(mediaPos, bytesToRead, buf)); 
   182         User::LeaveIfError(iMount->LocalDrive()->Read(mediaPos, bytesToRead, fatParseBuf)); 
   182 
   183 
   183         //-- parse the buffer and populate bit vector
   184         //-- parse the buffer and populate bit vector
   184         DoParseFat32Buf(ptrData, currFatEntry);
   185         DoParseFat32Buf(ptrData, currFatEntry);
   185         
   186         
   186         mediaPos += bytesToRead;
   187         mediaPos += bytesToRead;
   187         rem -= bytesToRead;
   188         rem -= bytesToRead;
   188         }
   189         }
   189 
   190 
   190     buf.Close();
   191     fatParseBuf.Close();
   191     CleanupStack::PopAndDestroy(&buf); 
   192     CleanupStack::PopAndDestroy(&fatParseBuf); 
   192     }
   193     }
   193 
   194 
   194 
   195 
   195 
   196 
   196 //----------------------------------------------------------------------------------------------------
   197 //----------------------------------------------------------------------------------------------------
   239     else
   240     else
   240         return iGenericError;
   241         return iGenericError;
   241 }
   242 }
   242 
   243 
   243 /**
   244 /**
   244     Sets the flag indicating than there are errors in filesystem structure
   245     Sets the flag indicating that there are errors in filesystem structure
   245     See ProblemsDiscovered()
   246     See ProblemsDiscovered()
   246 
   247 
   247     @param  aError a code describing the error
   248     @param  aError a code describing the error
   248 */
   249 */
   249 void CScanDrive::IndicateErrorsFound(TGenericError aError)
   250 void CScanDrive::IndicateErrorsFound(TGenericError aError)
   297 
   298 
   298 	    CompareAndFixFatsL();
   299 	    CompareAndFixFatsL();
   299         }
   300         }
   300 
   301 
   301 	PrintErrors();
   302 	PrintErrors();
   302 
       
   303 
   303 
   304     timeEnd.UniversalTime(); //-- take end time
   304     timeEnd.UniversalTime(); //-- take end time
   305     const TInt elapsedTime = (TInt)( (timeEnd.MicroSecondsFrom(timeStart)).Int64() / K1mSec);
   305     const TInt elapsedTime = (TInt)( (timeEnd.MicroSecondsFrom(timeStart)).Int64() / K1mSec);
   306     (void)elapsedTime;
   306     (void)elapsedTime;
   307 
   307 
   476 */
   476 */
   477 void CScanDrive::CheckDirStructureL()
   477 void CScanDrive::CheckDirStructureL()
   478 	{
   478 	{
   479 	CheckDirL(iMount->RootIndicator());
   479 	CheckDirL(iMount->RootIndicator());
   480 	// Due to recursive nature of CheckDirL when a depth of
   480 	// Due to recursive nature of CheckDirL when a depth of
   481 	// KMaxScanDepth is reached clusters are stored in a list
   481 	// KMaxScanDepth is reached, clusters are stored in a list
   482 	// and passed into CheckDirL afresh
   482 	// and passed into CheckDirL afresh
   483 
   483 
   484 	for(TUint i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
   484 	for(TUint i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
   485 		{
   485 		{
   486 		RArray<TInt>* clusterList=iClusterListArray[i];
   486 		RArray<TInt>* clusterList=iClusterListArray[i];
   516 
   516 
   517 	++iDirsChecked;
   517 	++iDirsChecked;
   518 
   518 
   519 	TEntryPos entryPos(aCluster,0);
   519 	TEntryPos entryPos(aCluster,0);
   520 	TInt dirEntries=0;
   520 	TInt dirEntries=0;
   521 	FOREVER
   521 	for(;;)
   522 		{
   522 		{
   523 		TFatDirEntry entry;
   523 		TFatDirEntry entry;
   524 		ReadDirEntryL(entryPos,entry);
   524 		ReadDirEntryL(entryPos,entry);
   525 		if(!iMount->IsEndOfClusterCh(entryPos.iCluster))
   525 		if(!iMount->IsEndOfClusterCh(entryPos.iCluster))
   526 			++dirEntries;
   526 			++dirEntries;
   658 	
   658 	
   659 	while(clusterCount)
   659 	while(clusterCount)
   660 		{
   660 		{
   661         if(IsClusterUsedL(aCluster))
   661         if(IsClusterUsedL(aCluster))
   662 			{//-- this cluster already seems to belong to some other object; crosslinked cluster chain. Can't fix it.
   662 			{//-- this cluster already seems to belong to some other object; crosslinked cluster chain. Can't fix it.
   663                 __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); 
   663             __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); 
   664             
   664             
   665             if(CheckDiskMode())
   665             if(CheckDiskMode())
   666                 {//-- in check disk mode this is a FS error; Indicate error and abort furter scanning
   666                 {//-- in check disk mode this is an FS error; Indicate error and abort further scanning
   667                 __PRINT(_L("CScanDrive::RecordClusterChainL #1.1")); 
   667                 __PRINT(_L("CScanDrive::RecordClusterChainL #1.1"));
   668                 IndicateErrorsFound(EClusterAlreadyInUse);
   668                 IndicateErrorsFound(EClusterAlreadyInUse);
   669                 User::Leave(KErrCorrupt);
   669                 User::Leave(KErrCorrupt);
   670                 }
   670                 }
   671             
   671             
   672             
   672             
   685 
   685 
   686 		
   686 		
   687         if(clusterCount==1)
   687         if(clusterCount==1)
   688 			{//-- we have reached the end of the cluster chain
   688 			{//-- we have reached the end of the cluster chain
   689 			if(!iMount->IsEndOfClusterCh(ReadFatL(aCluster)))
   689 			if(!iMount->IsEndOfClusterCh(ReadFatL(aCluster)))
   690 				{//-- seems to be a rugged FAT artefact; File truncation/extension had failed before and now file length is less than
   690 				{
   691                  //-- the corresponding cluster chain shall be. It will be truncated to the size recorded in file DOS entry.
   691 				// According to the directory entry, we have reached the end of the cluster chain,
   692 				iTruncationCluster = aCluster;								
   692 				// whereas in the media FAT, it is not.
       
   693 				// This is a rugged FAT artefact; hanging cluster chain:
       
   694 				// 	A cluster chain which is longer in the FAT table than is recorded in the corresponding directory entry 
       
   695 				// 	or not terminated by an EOC entry in FAT.
       
   696 				// This is caused by:
       
   697 				//  - File truncation failing.
       
   698 				//	- OR file expanding failing during flushing to the media FAT.
   693                 
   699                 
   694                 if(CheckDiskMode())
   700                 if(CheckDiskMode())
   695                     {//-- in check disk mode this is a FS error; Indicate error and abort furter scanning
   701                     {//-- in check disk mode this is an FS error; Indicate error and abort further scanning
   696                     __PRINT1(_L("CScanDrive::RecordClusterChainL #2 %d"),aCluster); 
   702                     __PRINT1(_L("CScanDrive::RecordClusterChainL #2 Hanging cluster=%d"),aCluster);
   697                     IndicateErrorsFound(EInvalidEntrySize);
   703                     IndicateErrorsFound(EInvalidEntrySize);
   698                     User::Leave(KErrCorrupt);
   704                     User::Leave(KErrCorrupt);
   699                     }
   705                     }
       
   706 				
       
   707 				// The chain will be truncated to the size recorded in the file's DOS entry and
       
   708 				// the remaining lost cluster chain will be fixed later in CompareAndFixFatsL().
       
   709 				FixHangingClusterChainL(aCluster);
   700                 }
   710                 }
   701 
   711 
   702             //__PRINT1(_L("#--: %d -> EOC"), aCluster); 
   712             //__PRINT1(_L("#--: %d -> EOC"), aCluster); 
   703             MarkClusterUsedL(aCluster);
   713             MarkClusterUsedL(aCluster);
   704 			return;
   714 			return;
   761 			break;
   771 			break;
   762 		
   772 		
   763         if(!IsValidVFatEntry(aEntry,toFollow))
   773         if(!IsValidVFatEntry(aEntry,toFollow))
   764 			return(EFalse);
   774 			return(EFalse);
   765 		}
   775 		}
   766 	
   776 	// A sequence of VFat entries must end with a Dos entry to be valid.
   767     return(IsDosEntry(aEntry));
   777 	return(IsDosEntry(aEntry));
   768 	}
   778 	}
   769 
   779 
   770 //----------------------------------------------------------------------------------------------------
   780 //----------------------------------------------------------------------------------------------------
   771 /**
   781 /**
   772     Check if an entry is valid VFat
   782     Check if an entry is valid VFat
   843 	}
   853 	}
   844 
   854 
   845 
   855 
   846 //----------------------------------------------------------------------------------------------------
   856 //----------------------------------------------------------------------------------------------------
   847 /**
   857 /**
   848     Scan for differnces in the new and old FAT table writing them to media if discovered
   858     Scan for differences in the new and old FAT table writing them to media if discovered
   849     It is supposed to be called in 'ScanDrive' mode only
   859     It is supposed to be called in 'ScanDrive' mode only
   850 
   860 
   851     @leave System wide error codes
   861     @leave System wide error codes
   852 */
   862 */
   853 void CScanDrive::CompareAndFixFatsL()
   863 void CScanDrive::CompareAndFixFatsL()
   883                     {
   893                     {
   884                     ++nBadClusters;
   894                     ++nBadClusters;
   885                     continue;
   895                     continue;
   886                     }
   896                     }
   887          
   897          
   888                 //-- here we found a lost cluster. Its FAT entry will be replaced with KSpareCluster. In the case of multiple lost clusters FAT table will
   898                 //-- Here we found a lost cluster. Its FAT entry will be replaced with KSpareCluster.
   889                 //-- be flushed on media sector basis. It is much faster than flushing FAT after every write and will
   899                 //-- In the case of multiple lost clusters FAT table will be flushed on media sector basis.
   890                 //-- guarantee that FAT won't be corrupted if the media driver provides atomic sector write. 
   900                 //-- It is much faster than flushing FAT after every write and will guarantee
       
   901                 //-- that FAT won't be corrupted if the media driver provides atomic sector write. 
   891                 if(nClustersFixed == 0)
   902                 if(nClustersFixed == 0)
   892                     {//-- this is the first lost cluster entry we found
   903                     {//-- this is the first lost cluster entry we found
   893                     
   904                     
   894                     //-- relative FAT media sector for the 'i' entry. The real value doesn't matter, 
   905                     //-- relative FAT media sector for the 'i' entry. The real value doesn't matter, 
   895                     //-- we will just be flushing FAT before writing to the different FAT media sector.
   906                     //-- we will just be flushing FAT before writing to the different FAT media sector.
   900                 else
   911                 else
   901                     {
   912                     {
   902                     const TUint32 fatSec = iMount->FAT().PosInBytes(i) >> KSectorSzLog2; 
   913                     const TUint32 fatSec = iMount->FAT().PosInBytes(i) >> KSectorSzLog2; 
   903 
   914 
   904                     if(fatSec != dirtyFatSector)
   915                     if(fatSec != dirtyFatSector)
   905                         {//-- we are going to write to a differrent media sector
   916                         {//-- we are going to write to a different media sector
   906                         iMount->FAT().FlushL();
   917                         iMount->FAT().FlushL();
   907                         iMount->FAT().WriteL(i, KSpareCluster); //-- fix lost cluster
   918                         iMount->FAT().WriteL(i, KSpareCluster); //-- fix lost cluster
   908                         dirtyFatSector = fatSec;
   919                         dirtyFatSector = fatSec;
   909                         }
   920                         }
   910                     else
   921                     else
   926     if(nClustersFixed)
   937     if(nClustersFixed)
   927         iMount->FAT().FlushL();
   938         iMount->FAT().FlushL();
   928     
   939     
   929     //------
   940     //------
   930 
   941 
   931     if(iTruncationCluster != 0)
   942 	
   932         {
   943 	// Add the number of hanging clusters fixed by ScanDrive
   933 	    iMount->FAT().WriteFatEntryEofL(iTruncationCluster); 
   944 	nClustersFixed += iHangingClusters;
   934 		iMount->FAT().FlushL();
   945     
   935 		
   946     __PRINT3(_L("CScanDrive::WriteNewFatsL() fixed clusters=%d,hanging clusters=%d,bad clusters=%d"),nClustersFixed,iHangingClusters,nBadClusters);
   936         //-- indicate that there are some problems in FAT. and we probably wrote something there.
       
   937         IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors
       
   938 
       
   939         ++nClustersFixed;
       
   940         }
       
   941     
       
   942     __PRINT2(_L("CScanDrive::WriteNewFatsL() fixed:%d, bad:%d"), nClustersFixed, nBadClusters);
       
   943     }
   947     }
   944 
   948 
   945 //----------------------------------------------------------------------------------------------------
   949 //----------------------------------------------------------------------------------------------------
   946 /**
   950 /**
   947     Read the "Rugged FAT" ID, stored in reserved2 in the Dos entry or associated with the Dos entry of the 
   951     Read the "Rugged FAT" ID, stored in reserved2 in the Dos entry or associated with the Dos entry of the 
  1010 
  1014 
  1011 	iMount->EraseDirEntryL(iMatching.iEntries[num],entry);
  1015 	iMount->EraseDirEntryL(iMatching.iEntries[num],entry);
  1012     
  1016     
  1013     IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors
  1017     IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors
  1014 	}
  1018 	}
       
  1019 
       
  1020 //----------------------------------------------------------------------------------------------------
       
  1021 /**
       
  1022 	Fix a hanging cluster chain.
       
  1023 	Writes EOF to the corresponding FAT entry, making this cluster chain length correspond to the 
       
  1024 	real file size recorded in the directory entry.
       
  1025 	The remainder of the chain will be cleaned up later in CompareAndFixFatsL().
       
  1026 	
       
  1027 	@leave	System wide error code
       
  1028 */
       
  1029 void CScanDrive::FixHangingClusterChainL(TUint32 aFatEofIndex)
       
  1030 	{
       
  1031 	__PRINT1(_L("CScanDrive::FixHangingClusterL() Hanging cluster=%d"), aFatEofIndex);
       
  1032 	
       
  1033 	iMount->FAT().WriteFatEntryEofL(aFatEofIndex);
       
  1034 	iMount->FAT().FlushL();
       
  1035 	iHangingClusters++;
       
  1036 	
       
  1037 	// Indicate that we have found an error
       
  1038 	IndicateErrorsFound(EScanDriveDirError);
       
  1039 	}
       
  1040 
  1015 
  1041 
  1016 //----------------------------------------------------------------------------------------------------
  1042 //----------------------------------------------------------------------------------------------------
  1017 /**
  1043 /**
  1018     Move past specified number of entries
  1044     Move past specified number of entries
  1019 
  1045 
  1085         const TBool bNewFatEntry  = iScanFatBits[i];
  1111         const TBool bNewFatEntry  = iScanFatBits[i];
  1086 
  1112 
  1087 		if(BoolXOR(bRealFatEntry, bNewFatEntry))
  1113 		if(BoolXOR(bRealFatEntry, bNewFatEntry))
  1088 		    {//-- mismatch between FAT on the media and the FAT bitmap restored by walking directory structure
  1114 		    {//-- mismatch between FAT on the media and the FAT bitmap restored by walking directory structure
  1089 
  1115 
  1090 			    if(bRealFatEntry)
  1116 			if(bRealFatEntry)
  1091                 {//-- FAT[i] on the media is marked as occupied, but retored FAT bitmap shows that it is free
  1117 				{//-- FAT[i] on the media is marked as occupied, but restored FAT bitmap shows that it is free
  1092                     if(iMount->IsBadCluster(ReadFatL(i)))
  1118 				if(iMount->IsBadCluster(ReadFatL(i)))
  1093                         continue; //-- this is a BAD cluster it can't be occupied by the FS object, OK.
  1119 					continue; //-- this is a BAD cluster it can't be occupied by the FS object, OK.
  1094 
  1120 
  1095                     __PRINT2(_L("FAT[%d] = %d\n"), i, ReadFatL(i));        
  1121 				__PRINT2(_L("FAT[%d] = %d\n"), i, ReadFatL(i));
  1096                     __PRINT1(_L("iTruncationCluster = %d\n"), iTruncationCluster);        
  1122 				
  1097                     
  1123 				//-- this is a Rugged FAT artefact; a lost cluster
  1098                     //-- this is a lost cluster
  1124 				__PRINT1(_L("Lost cluster=%d\n"),i);
  1099                     if(!IsEofF(ReadFatL(i)) && (i==iTruncationCluster))
  1125 				
  1100                         {//-- seems to be a Rugged FAT ertefact
  1126 				IndicateErrorsFound(EBadClusterValue);
  1101                         __PRINT1(_L("Hanging cluster = %d\n"),i);        
  1127 				}
  1102                         }
  1128 			else
  1103                     else
  1129 				{//-- FAT[i] on the media is marked as free, but restored FAT bitmap shows that it is occupied by some object
  1104                         {
  1130 				IndicateErrorsFound(EClusterAlreadyInUse);
  1105                         __PRINT1(_L("Lost cluster=%d\n"),i);
  1131 				__PRINT1(_L("Unflushed cluster = %d\n"),i);
  1106                         }
  1132 				}
  1107                     
  1133 
  1108                     
  1134 		 if(aStopOnFirstErrorFound)
  1109                     IndicateErrorsFound(EBadClusterValue);
  1135 			 break; //-- not asked to check for errors further
  1110                 }
       
  1111                 else
       
  1112                 {//-- FAT[i] on the media is marked as free, but retored FAT bitmap shows that it is occupied by some object
       
  1113                     IndicateErrorsFound(EClusterAlreadyInUse);
       
  1114                     __PRINT1(_L("Unflushed cluster = %d\n"),i);
       
  1115                 }
       
  1116 
       
  1117              if(aStopOnFirstErrorFound)
       
  1118                  break; //-- not asked to check for errors further
       
  1119 
  1136 
  1120             }
  1137             }
  1121 		
  1138 		
  1122         if(bRealFatEntry)
  1139         if(bRealFatEntry)
  1123 			mediausedcnt++;
  1140 			mediausedcnt++;
  1185 	//__PRINT(_L("CScanDrive::MoveToNextEntryL"));
  1202 	//__PRINT(_L("CScanDrive::MoveToNextEntryL"));
  1186 	iMount->MoveToNextEntryL(aPos);
  1203 	iMount->MoveToNextEntryL(aPos);
  1187 	}	
  1204 	}	
  1188 
  1205 
  1189 /**
  1206 /**
  1190     Read a cluster from the Media Fat if scan run in a seperate thread read from scan fat table
  1207     Read a cluster from the Media Fat if scan run in a separate thread read from scan Fat table
  1191     otherwise read from mount owned Fat table
  1208     otherwise read from mount owned Fat table
  1192 
  1209 
  1193     @param aClusterNum Cluster to read
  1210     @param aClusterNum Cluster to read
  1194     @return Value of cluster read from Fat
  1211     @return Value of cluster read from Fat
  1195 */
  1212 */
  1196 TUint32 CScanDrive::ReadFatL(TUint aClusterNum) 
  1213 TUint32 CScanDrive::ReadFatL(TUint aClusterNum)
  1197 	{
  1214 	{
  1198 	if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters())
  1215 	if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters())
  1199         {
  1216         {
  1200         __PRINT1(_L("CScanDrive::ReadFatL() bad cluster:%d\n"),aClusterNum);
  1217         __PRINT1(_L("CScanDrive::ReadFatL() bad cluster:%d\n"),aClusterNum);
  1201         IndicateErrorsFound(EBadClusterNumber);
  1218         IndicateErrorsFound(EBadClusterNumber);