diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,187 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// f32\sfat\inc\sl_scandrv.h +// +// + +/** + @file + @internalTechnology +*/ + +#ifndef SL_SCANDRV_H +#define SL_SCANDRV_H + +#include "sl_std.h" + +//--------------------------------------------------------------------------------------------------------------------------------- + +const TUint KMaxMatchingEntries = 2; ///< Maximum number of matching directory entries scan drive can fix. Any more indicates a fault in the file system +const TUint KMaxArrayDepth = 6; ///< Maximum array depth for cluster storage when KMaxScanDepth is reached + +/** Data structure used to store the location of a partial VFat entry */ +struct TPartVFatEntry + { + TEntryPos iEntryPos; ///< The position of the partial VFat entry + TFatDirEntry iEntry; ///< The Dos entry The VFat entries belong with + }; + + +/** Data structure used to store the locations of entries with matching start cluster numbers. */ +struct TMatchingStartCluster + { + TEntryPos iEntries[KMaxMatchingEntries]; ///< The positions of the matching entries + TUint iCount; ///< Count of matching entries + TUint iStartCluster; ///< The matching cluster number found in more than one entry + }; + + +//--------------------------------------------------------------------------------------------------------------------------------- +/** + This class is used for checking volume for FS errors and fixing a limited set of FS artefacts introduced by Rugged FAT on write failures. + It can operate in 2 modes: + + 1. "ScanDrive" mode, scan whole volume for possible Rugged FAT artefacts and fix them if possible. + 1.1 If there was no problem at all, then StartL() finishes normally and ProblemsDiscovered() returns ENoErrors. + 1.2 If there was Rugged FAT artefact and it had been successfully fixed, StartL() finishes normally and ProblemsDiscovered() returns EScanDriveDirError. + In this case the client may perform volum remounting, because FAT is very likely to have been changed. + 1.3 If there was a fatal error, like media failure or unfixable FS problem, StartL() will leave with some generic error code. + + 2. "CheckDisk" mode. check file system for known artefacts and return an error if _any_ problem discovered. + In this case StartL() _may_ leave with something like KErrCorrupt if there was a media failure or scan has stumbled across unknown FS error, + ProblemsDiscovered() _may_ return some code describing the problem. If StartL() did not leave, but ProblemsDiscovered() returns a code different + from ENoErrors, this means that there is FS corruption. +*/ +class CScanDrive : public CBase + { + +public: + + ~CScanDrive(); + static CScanDrive* NewL(CFatMountCB* aMount); + void ConstructL(CFatMountCB* aMount); + +public: + + /** description of known problems that this scanned can deal with. Mostly used in "CheckDisk " mode */ + enum TGenericError + { + ENoErrors = 0, ///< 0 no errors discovered + EBadClusterNumber, ///< 1 cluster number that doesn't correspond to the max. amount of clusters on the volume + EClusterAlreadyInUse, ///< 2 cross-linked cluster chain + EBadClusterValue, ///< 3 also means "lost cluster" + EInvalidEntrySize, ///< 4 size of file/directory does not correspond to the cluster chain length + + EUnknownError = 95, ///< unknown error + + EScanDriveDirError=100 ///< 100 ScanDrive error + }; + + TGenericError ProblemsDiscovered() const; + + /** CScanDrive mode of operation */ + enum TScanDriveMode + { + EScanAndFix, ///< "ScanDrive" mode, scan whole volume for possible Rugged FAT artefacts and fix them + ECheckDisk, ///< "CheckDisk" mode. check file system for known artefacts and return an error if _any_ problem discovered + }; + + void StartL(TScanDriveMode aMode); + +private: + void PrintErrors(); + void CompareFatsL(TBool aStopOnFirstErrorFound) ; + void CompareAndFixFatsL(); + + void FixupDirErrorL(); + + void ReadMediaFatL(); + void DoParseFatL(); + void DoParseFat32L(); + void DoParseFat32Buf(const TPtrC8& aBuf, TUint32& aCurrFatEntry); + + TBool IsClusterUsedL(TUint aCluster); + void MarkClusterUsedL(TUint aCluster); + + TUint32 ReadFatL(TUint aClusterNum) ; + void FindSameStartClusterL(); + TInt FindStartClusterL(TInt aDirCluster); + void CheckDirStructureL(); + void CheckDirL(TUint32 aCluster); + void ProcessEntryL(const TFatDirEntry& aEntry); + TInt CheckEntryClusterL(const TFatDirEntry& aEntry, const TEntryPos& aEntryPos); + void RecordClusterChainL(TInt aCluster,TUint aSizeInBytes); + TBool MoveToVFatEndL(TEntryPos& aPos,TFatDirEntry& aEntry,TInt& aDirLength); + TBool IsValidVFatEntry(const TFatDirEntry& aEntry,TInt prevNum)const; + TBool IsDosEntry(const TFatDirEntry& aEntry)const; + void AddPartialVFatL(const TEntryPos& aStartPos, const TFatDirEntry& aEntry); + TBool AddMatchingEntryL(const TEntryPos& aEntryPos); + TInt GetReservedidL(const TEntryPos aVFatPos); + + void FixPartEntryL(); + void FixMatchingEntryL(); + void MovePastEntriesL(TEntryPos& aEntryPos,TFatDirEntry& aEntry,TInt aToMove,TInt& aDirEntries); + void AddToClusterListL(TInt aCluster); + inline TBool AlreadyExistsL(TInt aCluster)const; + inline TBool IsEndOfRootDir(const TEntryPos& aPos)const; + inline TBool IsEofF(TInt aVal)const; + inline TBool IsDirError()const; + void MoveToNextEntryL(TEntryPos& aPos); + void ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry); + + inline void IndicateErrorsFound(TGenericError aError); + inline TUint32 MaxClusters() const; + inline TBool CheckDiskMode() const; + +protected: + + /** + Internal ScanDrive mode specific errors. In Rugged FAT mode (current implementatio) any type of error of this kind can occur only once and it will be fixed. + Othersise the FS is considered to be corrupted + */ + enum TDirError + { + ENoDirError= 0, ///< no errors found + EScanMatchingEntry=1, ///< Two entries pointing to the same cluster chain; Rugged FAT rename/replace artefact + EScanPartEntry, ///< Deleted DOS entry and orphaned VFAT ones from the same entryset; Rugged FAT 'file/dir delete' artefact + }; + + +private: + CFatMountCB* iMount; ///< The owning Fat mount + + TPartVFatEntry iPartEntry; ///< Storage for a partial VFat entry set error, see EScanPartEntry + TMatchingStartCluster iMatching; ///< Storage for Matching start cluster error, see EScanMatchingEntry + + TDirError iDirError; ///< Indicates the error tpye found also used to indicate if an error has occured + TInt iDirsChecked; ///< Count of the number of directories checked + TInt iRecursiveDepth; ///< Depth of recursion the scan has reached + RArray* iClusterListArray[KMaxArrayDepth]; ///< Size in bytes of the bit packed Fat Cluster list array used when maximum depth has been reached so that directory may be re-visited. Avoid stack overflow + + TUint iListArrayIndex; ///< Current position into cluster list array + TUint32 iTruncationCluster; ///< Cluster at which cluster chain truncation should take place, used for truncation errors + TUint32 iMaxClusters; ///< Max. amount of clusters on the volume + + RBitVector iMediaFatBits; ///< Storage for bit packed Fat read from media + RBitVector iScanFatBits; ///< Storage for bit packed Fat built up by the scan + + TGenericError iGenericError; ///< FS error that is discovered by scanning in any mode + TScanDriveMode iScanDriveMode; ///< mode of operation + }; + + + +#endif //SL_SCANDRV_H + +