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