--- a/userlibandfileserver/fileserver/sfat/sl_scan.cpp Mon Oct 19 15:55:17 2009 +0100
+++ b/userlibandfileserver/fileserver/sfat/sl_scan.cpp Mon Dec 21 16:14:42 2009 +0000
@@ -21,15 +21,23 @@
@internalTechnology
*/
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!
+//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
+//!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
//#define DEBUG_SCANDRIVE
#include "sl_std.h"
#include "sl_scandrv.h"
-const TInt KEndOfDirectory = 0xFFFF; ///< End of directory marker
-const TInt KMaxScanDepth = 20; ///< Maximum scan depth of to avoid stack over flow
-const TInt KClusterListGranularity = 8; ///< Granularity of cluster list used for storage of clusters when KMaxScanDepth is reached
+const TInt KEndOfDirectory = 0xFFFF; ///< End of directory marker
+const TInt KMaxScanDepth = 20; ///< Maximum scan depth of to avoid stack over flow
+const TInt KClusterListGranularity = 8; ///< Granularity of cluster list used for storage of clusters when KMaxScanDepth is reached
/**
Creates a CScanDrive
@@ -37,83 +45,83 @@
@param aMount The owning mount
*/
CScanDrive* CScanDrive::NewL(CFatMountCB* aMount)
- {
- if(aMount==NULL)
- User::Leave(KErrArgument);
- CScanDrive* self=new (ELeave) CScanDrive();
- CleanupStack::PushL(self);
- self->ConstructL(aMount);
- CleanupStack::Pop();
- return self;
- }
+ {
+ if(aMount==NULL)
+ User::Leave(KErrArgument);
+ CScanDrive* self=new (ELeave) CScanDrive();
+ CleanupStack::PushL(self);
+ self->ConstructL(aMount);
+ CleanupStack::Pop();
+ return self;
+ }
CScanDrive::CScanDrive()
//
// Constructor
//
- {
- }
+ {
+ }
CScanDrive::~CScanDrive()
//
// Destructor
//
- {
- delete iNewFat;
- for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
- {
- iClusterListArray[i]->Close();
- delete iClusterListArray[i];
- }
- }
+ {
+ delete iNewFat;
+ for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
+ {
+ iClusterListArray[i]->Close();
+ delete iClusterListArray[i];
+ }
+ }
void CScanDrive::ConstructL(CFatMountCB* aMount)
//
// Create the new fat and initalise
//
- {
- iMount=aMount;
- iNewFat=CCheckFatTable::NewL(aMount);
- iNewFat->InitializeL();
- }
+ {
+ iMount=aMount;
+ iNewFat=CCheckFatTable::NewL(aMount);
+ iNewFat->InitializeL();
+ }
TBool CScanDrive::AlreadyExistsL(TInt aCluster)const
//
-// Return ETrue if aCluster in the new fat contains a non-zero entry
+// Return ETrue if aCluster in the new fat contains a non-zero entry
//
- {
- return(iNewFat->ReadL(aCluster)!=0);
- }
+ {
+ return(iNewFat->ReadL(aCluster)!=0);
+ }
TBool CScanDrive::IsEndOfRootDir(const TEntryPos& aPos)const
//
// Return ETrue if aPos is the last entry in the root directory
//
- {
- return(iMount->IsRootDir(aPos)&&(iMount->StartOfRootDirInBytes()+aPos.iPos==(iMount->RootDirEnd()-KSizeOfFatDirEntry)));
- }
+ {
+ return(iMount->IsRootDir(aPos)&&(iMount->StartOfRootDirInBytes()+aPos.iPos==(iMount->RootDirEnd()-KSizeOfFatDirEntry)));
+ }
/**
@param aVal Value of the cluster to be tested
@return ETrue if aVal is the end of cluster marker
*/
TBool CScanDrive::IsEofF(TInt aVal)const
- {
+ {
return iMount->IsEndOfClusterCh(aVal);
- }
+ }
/**
@return True if a directory error has been found
*/
TBool CScanDrive::IsDirError()const
- {
- return(iDirError!=0);
- }
+ {
+ return(iDirError!=0);
+ }
@@ -146,23 +154,23 @@
@leave
*/
TInt CScanDrive::StartL()
- {
- __PRINT(_L("CScanDrive::StartL"));
- // check directory structure
- CheckDirStructureL();
+ {
+ __PRINT(_L("CScanDrive::StartL"));
+ // check directory structure
+ CheckDirStructureL();
#if defined(DEBUG_SCANDRIVE)
- CompareFatsL();
+ CompareFatsL();
#endif
- // fix error in directory structure
- if(IsDirError())
- FixupDirErrorL();
- // flush new fat
- WriteNewFatsL();
+ // fix error in directory structure
+ if(IsDirError())
+ FixupDirErrorL();
+ // flush new fat
+ WriteNewFatsL();
#if defined(DEBUG_SCANDRIVE)
- PrintErrors();
+ PrintErrors();
#endif
- return KErrNone;
- }
+ return KErrNone;
+ }
/**
Fix errors detected by the drive scan
@@ -170,21 +178,21 @@
@leave System wide error code
*/
void CScanDrive::FixupDirErrorL()
- {
- if(!IsDirError())
- return;
- if(iDirError==EScanMatchingEntry)
- {
- FindSameStartClusterL();
- FixMatchingEntryL();
- }
- else
- {
+ {
+ if(!IsDirError())
+ return;
+ if(iDirError==EScanMatchingEntry)
+ {
+ FindSameStartClusterL();
+ FixMatchingEntryL();
+ }
+ else
+ {
FixPartEntryL();
}
IndicateErrorsFound(); //-- indicate that we have found errors
- }
+ }
/**
Find positions of entries with same start cluster for error correction, searches
@@ -193,23 +201,23 @@
@leave System wide error code
*/
void CScanDrive::FindSameStartClusterL()
- {
- TInt err=FindStartClusterL(0);
- if(err==KErrNone)
- return;
- for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
- {
- RArray<TInt>* clusterList=iClusterListArray[i];
- for(TInt j=0;j<clusterList->Count();++j)
- {
- iRecursiveDepth=0;
- err=FindStartClusterL((*clusterList)[j]);
- if(err==KErrNone)
- return;
- }
- }
- __ASSERT_ALWAYS(err==KErrNone,User::Leave(KErrNotFound));
- }
+ {
+ TInt err=FindStartClusterL(0);
+ if(err==KErrNone)
+ return;
+ for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
+ {
+ RArray<TInt>* clusterList=iClusterListArray[i];
+ for(TInt j=0;j<clusterList->Count();++j)
+ {
+ iRecursiveDepth=0;
+ err=FindStartClusterL((*clusterList)[j]);
+ if(err==KErrNone)
+ return;
+ }
+ }
+ __ASSERT_ALWAYS(err==KErrNone,User::Leave(KErrNotFound));
+ }
/**
Scan through directory structure looking for start cluster found in iMatching
@@ -218,46 +226,46 @@
@leave
*/
TInt CScanDrive::FindStartClusterL(TInt aDirCluster)
- {
- __PRINT1(_L("CScanDrive::FindStartCluster dirCluster=%d"),aDirCluster);
- __ASSERT_ALWAYS(aDirCluster>=0,User::Leave(KErrCorrupt));
- if(++iRecursiveDepth==KMaxScanDepth)
- {
- --iRecursiveDepth;
- return(KErrNotFound);
- }
- TEntryPos entryPos(aDirCluster,0);
- TInt dirEntries=0;
- FOREVER
- {
- TFatDirEntry entry;
- iMount->ReadDirEntryL(entryPos,entry);
- if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased())
- {
- if(IsEndOfRootDir(entryPos))
- break;
- iMount->MoveToNextEntryL(entryPos);
- continue;
- }
- if(entry.IsEndOfDirectory())
- break;
- TBool isComplete;
- TEntryPos vfatPos=entryPos;
- isComplete=MoveToVFatEndL(entryPos,entry,dirEntries);
- __ASSERT_ALWAYS(isComplete,User::Leave(KErrBadName));
- TInt err=CheckEntryClusterL(entry,vfatPos);
- if(err==KErrNone)
- {
- --iRecursiveDepth;
- return(err);
- }
- if(IsEndOfRootDir(entryPos))
- break;
- iMount->MoveToNextEntryL(entryPos);
- }
- --iRecursiveDepth;
- return(KErrNotFound);
- }
+ {
+ __PRINT1(_L("CScanDrive::FindStartCluster dirCluster=%d"),aDirCluster);
+ __ASSERT_ALWAYS(aDirCluster>=0,User::Leave(KErrCorrupt));
+ if(++iRecursiveDepth==KMaxScanDepth)
+ {
+ --iRecursiveDepth;
+ return(KErrNotFound);
+ }
+ TEntryPos entryPos(aDirCluster,0);
+ TInt dirEntries=0;
+ FOREVER
+ {
+ TFatDirEntry entry;
+ iMount->ReadDirEntryL(entryPos,entry);
+ if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased())
+ {
+ if(IsEndOfRootDir(entryPos))
+ break;
+ iMount->MoveToNextEntryL(entryPos);
+ continue;
+ }
+ if(entry.IsEndOfDirectory())
+ break;
+ TBool isComplete;
+ TEntryPos vfatPos=entryPos;
+ isComplete=MoveToVFatEndL(entryPos,entry,dirEntries);
+ __ASSERT_ALWAYS(isComplete,User::Leave(KErrBadName));
+ TInt err=CheckEntryClusterL(entry,vfatPos);
+ if(err==KErrNone)
+ {
+ --iRecursiveDepth;
+ return(err);
+ }
+ if(IsEndOfRootDir(entryPos))
+ break;
+ iMount->MoveToNextEntryL(entryPos);
+ }
+ --iRecursiveDepth;
+ return(KErrNotFound);
+ }
/**
Procces aEntry to find matching start cluster
@@ -268,18 +276,18 @@
@leave
*/
TInt CScanDrive::CheckEntryClusterL(const TFatDirEntry& aEntry, const TEntryPos& aEntryPos)
- {
- __PRINT(_L("CScanDrive::CheckEntryClusterL"));
- if(iMount->StartCluster(aEntry)==iMatching.iStartCluster)
- {
- TBool complete=AddMatchingEntryL(aEntryPos);
- if(complete)
- return(KErrNone);
- }
- else if(aEntry.Attributes()&KEntryAttDir)
- return(FindStartClusterL(iMount->StartCluster(aEntry)));
- return(KErrNotFound);
- }
+ {
+ __PRINT(_L("CScanDrive::CheckEntryClusterL"));
+ if(iMount->StartCluster(aEntry)==iMatching.iStartCluster)
+ {
+ TBool complete=AddMatchingEntryL(aEntryPos);
+ if(complete)
+ return(KErrNone);
+ }
+ else if(aEntry.Attributes()&KEntryAttDir)
+ return(FindStartClusterL(iMount->StartCluster(aEntry)));
+ return(KErrNotFound);
+ }
/**
Checks directory strucutre for errors, can be considered the start point of the scan.
@@ -288,22 +296,22 @@
@leave System wide error code
*/
void CScanDrive::CheckDirStructureL()
- {
- CheckDirL(iMount->RootIndicator());
- // Due to recursive nature of CheckDirL when a depth of
- // KMaxScanDepth is reached clusters are stored in a list
- // and passed into CheckDirL afresh
- for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
- {
- RArray<TInt>* clusterList=iClusterListArray[i];
- ++iListArrayIndex;
- for(TInt j=0;j<clusterList->Count();++j)
- {
- iRecursiveDepth=0;
- CheckDirL((*clusterList)[j]);
- }
- }
- }
+ {
+ CheckDirL(iMount->RootIndicator());
+ // Due to recursive nature of CheckDirL when a depth of
+ // KMaxScanDepth is reached clusters are stored in a list
+ // and passed into CheckDirL afresh
+ for(TInt i=0;i<KMaxArrayDepth && iClusterListArray[i]!=NULL;++i)
+ {
+ RArray<TInt>* clusterList=iClusterListArray[i];
+ ++iListArrayIndex;
+ for(TInt j=0;j<clusterList->Count();++j)
+ {
+ iRecursiveDepth=0;
+ CheckDirL((*clusterList)[j]);
+ }
+ }
+ }
/**
Function is called recursively with Process entry untill the whole volume has been scanned.
Each directory entry is scanned for errors, these are recorded for later fixing.
@@ -312,72 +320,72 @@
@leave System wide error codes
*/
void CScanDrive::CheckDirL(TInt aCluster)
- {
- __PRINT1(_L("CScanDrive::CheckDirL aCluster=%d"),aCluster);
- __ASSERT_ALWAYS(aCluster>=0,User::Leave(KErrCorrupt));
- // check depth of recursion
- if(++iRecursiveDepth==KMaxScanDepth)
- {
- AddToClusterListL(aCluster);
- --iRecursiveDepth;
- return;
- }
+ {
+ __PRINT1(_L("CScanDrive::CheckDirL aCluster=%d"),aCluster);
+ __ASSERT_ALWAYS(aCluster>=0,User::Leave(KErrCorrupt));
+ // check depth of recursion
+ if(++iRecursiveDepth==KMaxScanDepth)
+ {
+ AddToClusterListL(aCluster);
+ --iRecursiveDepth;
+ return;
+ }
#if defined(DEBUG_SCANDRIVE)
- ++iDirsChecked;
+ ++iDirsChecked;
#endif
- TEntryPos entryPos(aCluster,0);
- TInt dirEntries=0;
- FOREVER
- {
- TFatDirEntry entry;
- iMount->ReadDirEntryL(entryPos,entry);
- if(!iMount->IsEndOfClusterCh(entryPos.iCluster))
- ++dirEntries;
- if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased())
- {
- if(IsEndOfRootDir(entryPos))
- break;
- iMount->MoveToNextEntryL(entryPos);
- continue;
- }
- if(entry.IsEndOfDirectory())
- {
- if(aCluster)
- WriteClusterChainL(aCluster,dirEntries<<KSizeOfFatDirEntryLog2);
- break;
- }
- TEntryPos origPos=entryPos;
- TFatDirEntry origEntry=entry;
- TInt origDirEntries=dirEntries;
- TBool isComplete;
- isComplete=MoveToVFatEndL(entryPos,entry,dirEntries);
- // Only assume that this is a corrupted VFAT entry if the VFAT attributes are set;
- // assuming a non-VFAT corrupted entry is a VFAT entry is dangerous as we then assume that the
- // first byte is a count of entries to skip, thus completely invalidating the next <n> directories.
- if (!isComplete && origEntry.IsVFatEntry())
- {
- AddPartialVFatL(origPos,origEntry);
- if(entryPos.iCluster!=KEndOfDirectory)
- {
- TInt toMove=origEntry.NumFollowing()-(dirEntries-origDirEntries);
- if(toMove)
- MovePastEntriesL(entryPos,entry,toMove,dirEntries);
- }
- else
- {
- // we fell off the end of the directory file, so just strip this
- // incomplete long file name entry
- dirEntries = origDirEntries;
- }
- }
- else
- ProcessEntryL(entry);
- if(IsEndOfRootDir(entryPos))
- break;
- iMount->MoveToNextEntryL(entryPos);
- }
- --iRecursiveDepth;
- }
+ TEntryPos entryPos(aCluster,0);
+ TInt dirEntries=0;
+ FOREVER
+ {
+ TFatDirEntry entry;
+ iMount->ReadDirEntryL(entryPos,entry);
+ if(!iMount->IsEndOfClusterCh(entryPos.iCluster))
+ ++dirEntries;
+ if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased())
+ {
+ if(IsEndOfRootDir(entryPos))
+ break;
+ iMount->MoveToNextEntryL(entryPos);
+ continue;
+ }
+ if(entry.IsEndOfDirectory())
+ {
+ if(aCluster)
+ WriteClusterChainL(aCluster,dirEntries<<KSizeOfFatDirEntryLog2);
+ break;
+ }
+ TEntryPos origPos=entryPos;
+ TFatDirEntry origEntry=entry;
+ TInt origDirEntries=dirEntries;
+ TBool isComplete;
+ isComplete=MoveToVFatEndL(entryPos,entry,dirEntries);
+ // Only assume that this is a corrupted VFAT entry if the VFAT attributes are set;
+ // assuming a non-VFAT corrupted entry is a VFAT entry is dangerous as we then assume that the
+ // first byte is a count of entries to skip, thus completely invalidating the next <n> directories.
+ if (!isComplete && origEntry.IsVFatEntry())
+ {
+ AddPartialVFatL(origPos,origEntry);
+ if(entryPos.iCluster!=KEndOfDirectory)
+ {
+ TInt toMove=origEntry.NumFollowing()-(dirEntries-origDirEntries);
+ if(toMove)
+ MovePastEntriesL(entryPos,entry,toMove,dirEntries);
+ }
+ else
+ {
+ // we fell off the end of the directory file, so just strip this
+ // incomplete long file name entry
+ dirEntries = origDirEntries;
+ }
+ }
+ else
+ ProcessEntryL(entry);
+ if(IsEndOfRootDir(entryPos))
+ break;
+ iMount->MoveToNextEntryL(entryPos);
+ }
+ --iRecursiveDepth;
+ }
/**
Process non trivial entries, such as files, if they are correct by filling out their
@@ -388,15 +396,15 @@
@leave System wide error code
*/
void CScanDrive::ProcessEntryL(const TFatDirEntry& aEntry)
- {
- __PRINT(_L("CScanDrive::ProcessEntryL"));
- TInt entryAtt=aEntry.Attributes();
- __ASSERT_ALWAYS(!(entryAtt&~KEntryAttMaskSupported)&&!aEntry.IsErased(),User::Leave(KErrCorrupt));
- if(!(entryAtt&(KEntryAttDir|KEntryAttVolume)) && iMount->StartCluster(aEntry)>0)
- WriteClusterChainL(iMount->StartCluster(aEntry),aEntry.Size());
- else if(entryAtt&KEntryAttDir)
- CheckDirL(iMount->StartCluster(aEntry));
- }
+ {
+ __PRINT(_L("CScanDrive::ProcessEntryL"));
+ TInt entryAtt=aEntry.Attributes();
+ __ASSERT_ALWAYS(!(entryAtt&~KEntryAttMaskSupported)&&!aEntry.IsErased(),User::Leave(KErrCorrupt));
+ if(!(entryAtt&(KEntryAttDir|KEntryAttVolume)) && iMount->StartCluster(aEntry)>0)
+ WriteClusterChainL(iMount->StartCluster(aEntry),aEntry.Size());
+ else if(entryAtt&KEntryAttDir)
+ CheckDirL(iMount->StartCluster(aEntry));
+ }
/**
Writes out the cluster chain for a correct file or directory, checks that the cluster
@@ -411,43 +419,43 @@
//
// Mark off in the new fat the clusters used by entry with start cluster of aCluster
//
- {
+ {
IndicateErrorsFound(); //-- indicate that we have found errors
- __PRINT1(_L("CScanDrive::WriteClusterChainL starting at %d"),aCluster);
- __ASSERT_ALWAYS(aCluster>0 && aSizeInBytes>=0,User::Leave(KErrCorrupt));
- TInt clusterCount;
- if(aSizeInBytes==0)
- clusterCount=1;
- else
- clusterCount=(aSizeInBytes+(1<<iMount->ClusterSizeLog2())-1)>>iMount->ClusterSizeLog2();
- TInt startCluster=aCluster;
- while(clusterCount)
- {
- if(AlreadyExistsL(aCluster))
- {
- __ASSERT_ALWAYS(!IsDirError()&&iMatching.iStartCluster==0&&aCluster==startCluster,User::Leave(KErrCorrupt));
- iMatching.iStartCluster=aCluster;
- iDirError=EScanMatchingEntry;
- return;
- }
- if(clusterCount==1)
- {
- iNewFat->WriteFatEntryEofFL(aCluster);
- return;
- }
- else
- {
- TInt clusterVal;
- clusterVal=iMount->FAT().ReadL(aCluster);
- __ASSERT_ALWAYS(!IsEofF(clusterVal) && clusterVal!=0,User::Leave(KErrCorrupt));
- iNewFat->WriteL(aCluster,clusterVal);
- aCluster=clusterVal;
- --clusterCount;
- }
- }
- }
+ __PRINT1(_L("CScanDrive::WriteClusterChainL starting at %d"),aCluster);
+ __ASSERT_ALWAYS(aCluster>0 && aSizeInBytes>=0,User::Leave(KErrCorrupt));
+ TInt clusterCount;
+ if(aSizeInBytes==0)
+ clusterCount=1;
+ else
+ clusterCount=(aSizeInBytes+(1<<iMount->ClusterSizeLog2())-1)>>iMount->ClusterSizeLog2();
+ TInt startCluster=aCluster;
+ while(clusterCount)
+ {
+ if(AlreadyExistsL(aCluster))
+ {
+ __ASSERT_ALWAYS(!IsDirError()&&iMatching.iStartCluster==0&&aCluster==startCluster,User::Leave(KErrCorrupt));
+ iMatching.iStartCluster=aCluster;
+ iDirError=EScanMatchingEntry;
+ return;
+ }
+ if(clusterCount==1)
+ {
+ iNewFat->WriteFatEntryEofFL(aCluster);
+ return;
+ }
+ else
+ {
+ TInt clusterVal;
+ clusterVal=iMount->FAT().ReadL(aCluster);
+ __ASSERT_ALWAYS(!IsEofF(clusterVal) && clusterVal!=0,User::Leave(KErrCorrupt));
+ iNewFat->WriteL(aCluster,clusterVal);
+ aCluster=clusterVal;
+ --clusterCount;
+ }
+ }
+ }
/**
Move to dos entry, checking all vfat entry ID numbers are in sequence.
@@ -460,25 +468,25 @@
@return EFalse if not valid vfat entries or dos entry, else returns ETrue
*/
TBool CScanDrive::MoveToVFatEndL(TEntryPos& aPos,TFatDirEntry& aEntry,TInt& aDirLength)
- {
- __PRINT2(_L("CScanDrive::MoveToVFatEndL cluster=%d,pos=%d"),aPos.iCluster,aPos.iPos);
- if(!aEntry.IsVFatEntry())
- return IsDosEntry(aEntry);
- TInt toFollow=aEntry.NumFollowing();
- __ASSERT_ALWAYS(toFollow>0&&!aEntry.IsErased(),User::Leave(KErrCorrupt));
- FOREVER
- {
- iMount->MoveToNextEntryL(aPos);
- iMount->ReadDirEntryL(aPos,aEntry);
- ++aDirLength;
- --toFollow;
- if(!toFollow)
- break;
- if(!IsValidVFatEntry(aEntry,toFollow))
- return(EFalse);
- }
- return(IsDosEntry(aEntry));
- }
+ {
+ __PRINT2(_L("CScanDrive::MoveToVFatEndL cluster=%d,pos=%d"),aPos.iCluster,aPos.iPos);
+ if(!aEntry.IsVFatEntry())
+ return IsDosEntry(aEntry);
+ TInt toFollow=aEntry.NumFollowing();
+ __ASSERT_ALWAYS(toFollow>0&&!aEntry.IsErased(),User::Leave(KErrCorrupt));
+ FOREVER
+ {
+ iMount->MoveToNextEntryL(aPos);
+ iMount->ReadDirEntryL(aPos,aEntry);
+ ++aDirLength;
+ --toFollow;
+ if(!toFollow)
+ break;
+ if(!IsValidVFatEntry(aEntry,toFollow))
+ return(EFalse);
+ }
+ return(IsDosEntry(aEntry));
+ }
/**
Check if an entry is valid VFat
@@ -488,11 +496,11 @@
@return ETrue if aEntry is a valid vfat entry
*/
TBool CScanDrive::IsValidVFatEntry(const TFatDirEntry& aEntry, TInt aPrevNum)const
- {
- if(aEntry.IsErased()||!aEntry.IsVFatEntry())
- return(EFalse);
- return(aEntry.NumFollowing()==aPrevNum);
- }
+ {
+ if(aEntry.IsErased()||!aEntry.IsVFatEntry())
+ return(EFalse);
+ return(aEntry.NumFollowing()==aPrevNum);
+ }
/**
Check if an entry is a Dos entry
@@ -501,10 +509,10 @@
@return ETrue if aEntry is a dos entry
*/
TBool CScanDrive::IsDosEntry(const TFatDirEntry& aEntry)const
- {
- TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory();
- return res;
- }
+ {
+ TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory();
+ return res;
+ }
/**
Add partial entry to iPartEntry under the error condition of not all Vfat entries
@@ -515,13 +523,13 @@
@leave KErrCorrupt Occurs if the entry is not valid
*/
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));
- iPartEntry.iEntryPos=aStartPos;
- iPartEntry.iEntry=aEntry;
- iDirError=EScanPartEntry;
- }
+ {
+ __PRINT2(_L("CScanDrive::AddPartialVFatL cluster=%d pos=%d"),aStartPos.iCluster,aStartPos.iPos);
+ __ASSERT_ALWAYS(!IsDirError(),User::Leave(KErrCorrupt));
+ iPartEntry.iEntryPos=aStartPos;
+ iPartEntry.iEntry=aEntry;
+ iDirError=EScanPartEntry;
+ }
/**
Add entry position to iMatching
@@ -531,12 +539,12 @@
@return
*/
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));
- iMatching.iEntries[iMatching.iCount++]=aEntryPos;
- return iMatching.iCount==KMaxMatchingEntries;
- }
+ {
+ __PRINT2(_L("CScanDrive::AddMatchingEntryL cluster=%d pos=%d"),aEntryPos.iCluster,aEntryPos.iPos);
+ __ASSERT_ALWAYS(iMatching.iStartCluster>0 && iMatching.iCount<KMaxMatchingEntries,User::Leave(KErrCorrupt));
+ iMatching.iEntries[iMatching.iCount++]=aEntryPos;
+ return iMatching.iCount==KMaxMatchingEntries;
+ }
/**
@@ -548,28 +556,28 @@
//
// Write the new fat table to disk
//
- {
- if(iNewFat->FlushL())
+ {
+ if(iNewFat->FlushL())
IndicateErrorsFound(); //-- indicate that we have found errors
- }
+ }
TInt CScanDrive::GetReservedidL(TEntryPos aVFatPos)
//
// Return the id found in reserved2 field of dos entry
//
- {
- __PRINT(_L("CScanDrive::GetReservedidL"));
- TFatDirEntry entry;
- iMount->ReadDirEntryL(aVFatPos,entry);
- if(!IsDosEntry(entry))
- {
- TInt toMove=entry.NumFollowing();
- while(toMove--)
- iMount->MoveToNextEntryL(aVFatPos);
- iMount->ReadDirEntryL(aVFatPos,entry);
- }
- return(entry.RuggedFatEntryId());
- }
+ {
+ __PRINT(_L("CScanDrive::GetReservedidL"));
+ TFatDirEntry entry;
+ iMount->ReadDirEntryL(aVFatPos,entry);
+ if(!IsDosEntry(entry))
+ {
+ TInt toMove=entry.NumFollowing();
+ while(toMove--)
+ iMount->MoveToNextEntryL(aVFatPos);
+ iMount->ReadDirEntryL(aVFatPos,entry);
+ }
+ return(entry.RuggedFatEntryId());
+ }
/**
Erase part entry found in iPartEntry
@@ -577,28 +585,28 @@
@leave System wide error code
*/
void CScanDrive::FixPartEntryL()
- {
- __PRINT2(_L("CScanDrive::FixPartEntryL cluster=%d,pos=%d"),iPartEntry.iEntryPos.iCluster,iPartEntry.iEntryPos.iPos);
- iMount->EraseDirEntryL(iPartEntry.iEntryPos,iPartEntry.iEntry);
+ {
+ __PRINT2(_L("CScanDrive::FixPartEntryL cluster=%d,pos=%d"),iPartEntry.iEntryPos.iCluster,iPartEntry.iEntryPos.iPos);
+ iMount->EraseDirEntryL(iPartEntry.iEntryPos,iPartEntry.iEntry);
IndicateErrorsFound(); //-- indicate that we have found errors
- }
-
+ }
+
/**
Delete entry with largest value in the reserved2 section(bytes 20 and 21) of dos entry
-
+
@leave System wide error code
*/
void CScanDrive::FixMatchingEntryL()
- {
- __PRINT1(_L("CScanDrive::FixMatchingEntryL() start cluster=%d"),iMatching.iStartCluster);
- __ASSERT_ALWAYS(iMatching.iCount==KMaxMatchingEntries,User::Leave(KErrCorrupt));
- TInt idOne=GetReservedidL(iMatching.iEntries[0]);
- TInt idTwo=GetReservedidL(iMatching.iEntries[1]);
- TFatDirEntry entry;
- TInt num=idOne>idTwo?0:1;
- iMount->ReadDirEntryL(iMatching.iEntries[num],entry);
- iMount->EraseDirEntryL(iMatching.iEntries[num],entry);
- IndicateErrorsFound(); //-- indicate that we have found errors
+ {
+ __PRINT1(_L("CScanDrive::FixMatchingEntryL() start cluster=%d"),iMatching.iStartCluster);
+ __ASSERT_ALWAYS(iMatching.iCount==KMaxMatchingEntries,User::Leave(KErrCorrupt));
+ TInt idOne=GetReservedidL(iMatching.iEntries[0]);
+ TInt idTwo=GetReservedidL(iMatching.iEntries[1]);
+ TFatDirEntry entry;
+ TInt num=idOne>idTwo?0:1;
+ iMount->ReadDirEntryL(iMatching.iEntries[num],entry);
+ iMount->EraseDirEntryL(iMatching.iEntries[num],entry);
+ IndicateErrorsFound(); //-- indicate that we have found errors
}
/**
Move past specified number of entries
@@ -610,14 +618,14 @@
@leave System wide error code
*/
void CScanDrive::MovePastEntriesL(TEntryPos& aEntryPos,TFatDirEntry& aEntry,TInt aToMove,TInt& aDirEntries)
- {
- while(aToMove-- && aEntryPos.iCluster!=KEndOfDirectory)
- {
- iMount->MoveToNextEntryL(aEntryPos);
- ++aDirEntries;
- }
- iMount->ReadDirEntryL(aEntryPos,aEntry);
- }
+ {
+ while(aToMove-- && aEntryPos.iCluster!=KEndOfDirectory)
+ {
+ iMount->MoveToNextEntryL(aEntryPos);
+ ++aDirEntries;
+ }
+ iMount->ReadDirEntryL(aEntryPos,aEntry);
+ }
/**
Adds aCluster to cluster list array so that it may be revisited later, avoids stack
@@ -627,41 +635,41 @@
@leave KErrNoMemory If allocation fails
*/
void CScanDrive::AddToClusterListL(TInt aCluster)
- {
- if(iListArrayIndex>=KMaxArrayDepth)
- return;
- if(iClusterListArray[iListArrayIndex]==NULL)
- iClusterListArray[iListArrayIndex]=new(ELeave) RArray<TInt>(KClusterListGranularity);
- iClusterListArray[iListArrayIndex]->Append(aCluster);
- }
+ {
+ if(iListArrayIndex>=KMaxArrayDepth)
+ return;
+ if(iClusterListArray[iListArrayIndex]==NULL)
+ iClusterListArray[iListArrayIndex]=new(ELeave) RArray<TInt>(KClusterListGranularity);
+ iClusterListArray[iListArrayIndex]->Append(aCluster);
+ }
#if defined(DEBUG_SCANDRIVE)
void CScanDrive::CompareFatsL()
//
// Compare new fat and first fat table
-//
- {
- __PRINT(_L("CScanDrive::CompareFatsL()"));
- TInt maxClusters;
- maxClusters=iMount->UsableClusters();
- for(TInt i=KFatFirstSearchCluster; i<maxClusters; ++i)
- {
- TInt realFat=iMount->FAT().ReadL(i);
- TInt newFat=iNewFat->ReadL(i);
- if(realFat!=newFat)
- {
- if(realFat!=0 && newFat==0)
- __PRINT1(_L("Lost cluster=%d\n"),i)
- else if((realFat>0 && !IsEofF(realFat)) && IsEofF(newFat))
- __PRINT1(_L("Hanging cluster = %d\n"),i)
- else if(realFat==0 && newFat>0)
- __PRINT1(_L("Unflushed cluster = %d\n"),i)
- else
- User::Leave(KErrCorrupt);
- }
- }
- }
+//
+ {
+ __PRINT(_L("CScanDrive::CompareFatsL()"));
+ TInt maxClusters;
+ maxClusters=iMount->UsableClusters();
+ for(TInt i=KFatFirstSearchCluster; i<maxClusters; ++i)
+ {
+ TInt realFat=iMount->FAT().ReadL(i);
+ TInt newFat=iNewFat->ReadL(i);
+ if(realFat!=newFat)
+ {
+ if(realFat!=0 && newFat==0)
+ __PRINT1(_L("Lost cluster=%d\n"),i)
+ else if((realFat>0 && !IsEofF(realFat)) && IsEofF(newFat))
+ __PRINT1(_L("Hanging cluster = %d\n"),i)
+ else if(realFat==0 && newFat>0)
+ __PRINT1(_L("Unflushed cluster = %d\n"),i)
+ else
+ User::Leave(KErrCorrupt);
+ }
+ }
+ }
/**
@@ -669,18 +677,18 @@
*/
void CScanDrive::PrintErrors()
- {
- __PRINT1(_L("Directories visisted = %d\n"),iDirsChecked);
- if(iDirError==EScanPartEntry)
- __PRINT2(_L("Part entry-dir cluster=%d,dir pos=%d,\n"),iPartEntry.iEntryPos.iCluster,iPartEntry.iEntryPos.iPos)
- else if(iDirError==EScanMatchingEntry)
- {
- __PRINT1(_L("Matching cluster - cluster no=%d\n"),iMatching.iStartCluster);
- __PRINT2(_L("\tcluster 1 - dir cluster=%d,dir pos=%d\n"),iMatching.iEntries[0].iCluster,iMatching.iEntries[0].iPos);
- __PRINT2(_L("\tcluster 2 - dir cluster=%d,dir pos=%d\n"),iMatching.iEntries[1].iCluster,iMatching.iEntries[1].iPos);
- }
- }
-
+ {
+ __PRINT1(_L("Directories visisted = %d\n"),iDirsChecked);
+ if(iDirError==EScanPartEntry)
+ __PRINT2(_L("Part entry-dir cluster=%d,dir pos=%d,\n"),iPartEntry.iEntryPos.iCluster,iPartEntry.iEntryPos.iPos)
+ else if(iDirError==EScanMatchingEntry)
+ {
+ __PRINT1(_L("Matching cluster - cluster no=%d\n"),iMatching.iStartCluster);
+ __PRINT2(_L("\tcluster 1 - dir cluster=%d,dir pos=%d\n"),iMatching.iEntries[0].iCluster,iMatching.iEntries[0].iPos);
+ __PRINT2(_L("\tcluster 2 - dir cluster=%d,dir pos=%d\n"),iMatching.iEntries[1].iCluster,iMatching.iEntries[1].iPos);
+ }
+ }
+
#endif