userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h
changeset 11 329ab0095843
parent 9 96e5fb8b040d
child 22 2f92ad2dc5db
equal deleted inserted replaced
10:36bfc973b146 11:329ab0095843
    25 
    25 
    26 #include "sl_std.h"
    26 #include "sl_std.h"
    27 
    27 
    28 //---------------------------------------------------------------------------------------------------------------------------------
    28 //---------------------------------------------------------------------------------------------------------------------------------
    29 
    29 
    30 const TInt KMaxMatchingEntries		= 2;        ///< Maximum number of matching directory entries scan drive can fix. Any more indicates a fault in the file system
    30 const TUint KMaxMatchingEntries		= 2;        ///< Maximum number of matching directory entries scan drive can fix. Any more indicates a fault in the file system
    31 const TInt KMaxArrayDepth			= 6;        ///< Maximum array depth for cluster storage when KMaxScanDepth is reached
    31 const TUint KMaxArrayDepth			= 6;        ///< Maximum array depth for cluster storage when KMaxScanDepth is reached
    32 
    32 
    33 /**
    33 /** Data structure used to store the location of a partial VFat entry */
    34 Data structure used to store the location of a partial VFat entry
       
    35 */
       
    36 struct TPartVFatEntry
    34 struct TPartVFatEntry
    37 	{
    35 	{
    38 	TEntryPos    iEntryPos; ///< The position of the partial VFat entry
    36 	TEntryPos    iEntryPos; ///< The position of the partial VFat entry
    39 	TFatDirEntry iEntry;    ///< The Dos entry The VFat entries belong with
    37 	TFatDirEntry iEntry;    ///< The Dos entry The VFat entries belong with
    40 	};
    38 	};
    41 
    39 
    42 
    40 
    43 /**
    41 /** Data structure used to store the locations of entries with matching start cluster numbers. */
    44 Data structure used to store the locations of entries with matching
       
    45 start cluster numbers. 
       
    46 */
       
    47 struct TMatchingStartCluster
    42 struct TMatchingStartCluster
    48 	{
    43 	{
    49 	TEntryPos   iEntries[KMaxMatchingEntries]; ///< The positions of the matching entries
    44 	TEntryPos   iEntries[KMaxMatchingEntries]; ///< The positions of the matching entries
    50 	TInt        iCount;         ///< Count of matching entries
    45 	TUint       iCount;         ///< Count of matching entries
    51 	TInt        iStartCluster;  ///< The matching cluster number found in more than one entry
    46 	TUint       iStartCluster;  ///< The matching cluster number found in more than one entry
    52 	};
    47 	};
    53 
    48 
       
    49 
       
    50 //---------------------------------------------------------------------------------------------------------------------------------
    54 /**
    51 /**
    55 Scan drive class performs scan drive functionality on all types
    52     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.
    56 of fat volume.
    53     It can operate in 2 modes:
       
    54     
       
    55     1. "ScanDrive" mode, scan whole volume for possible Rugged FAT artefacts and fix them if possible. 
       
    56         1.1 If there was no problem at all, then StartL() finishes normally and ProblemsDiscovered() returns ENoErrors.
       
    57         1.2 If there was Rugged FAT artefact and it had been successfully fixed, StartL() finishes normally and ProblemsDiscovered() returns EScanDriveDirError.
       
    58             In this case the client may perform volum remounting, because FAT is very likely to have been changed.
       
    59         1.3 If there was a fatal error, like media failure or unfixable FS problem, StartL() will leave with some generic error code.
       
    60 
       
    61     2.  "CheckDisk" mode. check file system for known artefacts and return an error if _any_ problem discovered.
       
    62         In this case StartL() _may_ leave with something like KErrCorrupt if there was a media failure or scan has stumbled across unknown FS error, 
       
    63         ProblemsDiscovered() _may_ return some code describing the problem. If StartL() did not leave, but ProblemsDiscovered() returns a code different 
       
    64         from ENoErrors, this means that there is FS corruption. 
    57 */
    65 */
    58 class CScanDrive : public CBase
    66 class CScanDrive : public CBase
    59 	{
    67 	{
    60 public:
       
    61 	/**
       
    62 	Error type found by scan drive, only a single error should occur in 
       
    63 	any scan of the volume
       
    64 	*/
       
    65 	enum TDirError{EScanMatchingEntry=1,EScanPartEntry, ETruncation};
       
    66 
    68 
    67 public:
    69 public:
    68 
    70 
    69 	~CScanDrive();
    71 	~CScanDrive();
    70 	static CScanDrive* NewL(CFatMountCB* aMount);
    72 	static CScanDrive* NewL(CFatMountCB* aMount);
    71 	void ConstructL(CFatMountCB* aMount);
    73 	void ConstructL(CFatMountCB* aMount);
    72 
    74 
    73 	TInt  StartL();
    75 public:
    74     TBool ProblemsDiscovered() const;  
       
    75 
    76 
       
    77     /** description of known problems that this scanned can deal with. Mostly used in "CheckDisk " mode */
       
    78     enum TGenericError
       
    79         {
       
    80         ENoErrors = 0,          ///< 0  no errors discovered
       
    81         EBadClusterNumber,      ///< 1  cluster number that doesn't correspond to the max. amount of clusters on the volume
       
    82         EClusterAlreadyInUse,   ///< 2  cross-linked cluster chain
       
    83         EBadClusterValue,       ///< 3  also means "lost cluster"
       
    84         EInvalidEntrySize,      ///< 4  size of file/directory does not correspond to the cluster chain length
       
    85         
       
    86         EUnknownError = 95,     ///< unknown error
       
    87 
       
    88         EScanDriveDirError=100  ///< 100 ScanDrive error
       
    89         };
       
    90 
       
    91     TGenericError ProblemsDiscovered() const;
       
    92 
       
    93 	/** CScanDrive mode of operation */
       
    94     enum TScanDriveMode
       
    95         {
       
    96         EScanAndFix, ///< "ScanDrive" mode, scan whole volume for possible Rugged FAT artefacts and fix them
       
    97         ECheckDisk,  ///< "CheckDisk" mode. check file system for known artefacts and return an error if _any_ problem discovered
       
    98         };
       
    99     
       
   100     void StartL(TScanDriveMode aMode);
    76 
   101 
    77 private:
   102 private:
    78 #if defined(DEBUG_SCANDRIVE)
       
    79 	void PrintErrors();
   103 	void PrintErrors();
    80 	void CompareFatsL() const;
   104 	void CompareFatsL(TBool aStopOnFirstErrorFound) ;
    81 #endif
   105 	void CompareAndFixFatsL();
    82 	void FixupDirErrorL();
   106 
       
   107     void FixupDirErrorL();
    83 
   108 
    84 	void ReadMediaFatL();
   109 	void ReadMediaFatL();
    85     void DoParseFatL();
   110     void DoParseFatL();
    86     void DoParseFat32L();
   111     void DoParseFat32L();
    87     void DoParseFat32Buf(const TPtrC8& aBuf, TUint32& aCurrFatEntry);
   112     void DoParseFat32Buf(const TPtrC8& aBuf, TUint32& aCurrFatEntry);
    88 
   113 
    89 	TBool AlreadyUsedL(TUint aCluster) const;
   114 	TBool IsClusterUsedL(TUint aCluster);
    90 	void SetUsedL(TUint aCluster);
   115 	void MarkClusterUsedL(TUint aCluster);
    91 
   116 
    92 	TUint32 ReadFatL(TInt aClusterNum) const;
   117 	TUint32 ReadFatL(TUint aClusterNum) ;
    93 	void FindSameStartClusterL();
   118 	void FindSameStartClusterL();
    94 	TInt FindStartClusterL(TInt aDirCluster);
   119 	TInt FindStartClusterL(TInt aDirCluster);
    95 	void CheckDirStructureL();
   120 	void CheckDirStructureL();
    96 	void CheckDirL(TInt aCluster);
   121 	void CheckDirL(TUint32 aCluster);
    97 	void ProcessEntryL(const TFatDirEntry& aEntry);
   122 	void ProcessEntryL(const TFatDirEntry& aEntry);
    98 	TInt CheckEntryClusterL(const TFatDirEntry& aEntry, const TEntryPos& aEntryPos);
   123 	TInt CheckEntryClusterL(const TFatDirEntry& aEntry, const TEntryPos& aEntryPos);
    99 	void WriteClusterChainL(TInt aCluster,TUint aSizeInBytes);
   124 	void RecordClusterChainL(TInt aCluster,TUint aSizeInBytes);
   100 	TBool MoveToVFatEndL(TEntryPos& aPos,TFatDirEntry& aEntry,TInt& aDirLength);
   125 	TBool MoveToVFatEndL(TEntryPos& aPos,TFatDirEntry& aEntry,TInt& aDirLength);
   101 	TBool IsValidVFatEntry(const TFatDirEntry& aEntry,TInt prevNum)const;
   126 	TBool IsValidVFatEntry(const TFatDirEntry& aEntry,TInt prevNum)const;
   102 	TBool IsDosEntry(const TFatDirEntry& aEntry)const;
   127 	TBool IsDosEntry(const TFatDirEntry& aEntry)const;
   103 	void AddPartialVFatL(const TEntryPos& aStartPos, const TFatDirEntry& aEntry);
   128 	void AddPartialVFatL(const TEntryPos& aStartPos, const TFatDirEntry& aEntry);
   104 	TBool AddMatchingEntryL(const TEntryPos& aEntryPos);
   129 	TBool AddMatchingEntryL(const TEntryPos& aEntryPos);
   105 	TInt GetReservedidL(const TEntryPos aVFatPos);
   130 	TInt GetReservedidL(const TEntryPos aVFatPos);
   106 	void WriteNewFatsL();
   131 	
   107 	void FixPartEntryL();
   132 	void FixPartEntryL();
   108 	void FixMatchingEntryL();
   133 	void FixMatchingEntryL();
   109 	void MovePastEntriesL(TEntryPos& aEntryPos,TFatDirEntry& aEntry,TInt aToMove,TInt& aDirEntries);
   134 	void MovePastEntriesL(TEntryPos& aEntryPos,TFatDirEntry& aEntry,TInt aToMove,TInt& aDirEntries);
   110 	void AddToClusterListL(TInt aCluster);
   135 	void AddToClusterListL(TInt aCluster);
   111 	inline TBool AlreadyExistsL(TInt aCluster)const;
   136 	inline TBool AlreadyExistsL(TInt aCluster)const;
   113 	inline TBool IsEofF(TInt aVal)const;
   138 	inline TBool IsEofF(TInt aVal)const;
   114 	inline TBool IsDirError()const;
   139 	inline TBool IsDirError()const;
   115 	void MoveToNextEntryL(TEntryPos& aPos);
   140 	void MoveToNextEntryL(TEntryPos& aPos);
   116 	void ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry);
   141 	void ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry);
   117 
   142 
   118     void IndicateErrorsFound();
   143     inline void IndicateErrorsFound(TGenericError aError);
       
   144     inline TUint32 MaxClusters() const;
       
   145     inline TBool CheckDiskMode() const;
       
   146 
       
   147 protected:
       
   148 	
       
   149     /**
       
   150     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.
       
   151     Othersise the FS is considered to be corrupted
       
   152     */
       
   153     enum TDirError 
       
   154         {
       
   155         ENoDirError= 0,         ///< no errors found
       
   156         EScanMatchingEntry=1,   ///< Two entries pointing to the same cluster chain; Rugged FAT rename/replace artefact
       
   157         EScanPartEntry,         ///< Deleted DOS entry and orphaned VFAT ones from the same entryset; Rugged FAT 'file/dir delete' artefact
       
   158         };
       
   159 
   119 
   160 
   120 private:
   161 private:
   121 	CFatMountCB*            iMount;             ///< The owning Fat mount
   162 	CFatMountCB*            iMount;             ///< The owning Fat mount
   122 	TPartVFatEntry          iPartEntry;         ///< Storage for a partial VFat entry set error
   163 	
   123 	TMatchingStartCluster   iMatching;          ///< Storage for Matching start cluster error
   164     TPartVFatEntry          iPartEntry;         ///< Storage for a partial VFat entry set error, see EScanPartEntry
   124 	TDirError               iDirError;          ///< Indicates the error tpye found also used to indicate if an error has occured
   165 	TMatchingStartCluster   iMatching;          ///< Storage for Matching start cluster error, see EScanMatchingEntry
   125 	TInt                    iDirsChecked;       ///< Count of the number of directories checked
   166 	
       
   167     TDirError               iDirError;          ///< Indicates the error tpye found also used to indicate if an error has occured
       
   168     TInt                    iDirsChecked;       ///< Count of the number of directories checked
   126 	TInt                    iRecursiveDepth;    ///< Depth of recursion the scan has reached
   169 	TInt                    iRecursiveDepth;    ///< Depth of recursion the scan has reached
   127 	RArray<TInt>*           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
   170 	RArray<TInt>*           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
   128 	TInt                    iListArrayIndex;    ///< Current position into cluster list array
       
   129 	TInt                    iTruncationCluster; ///< Cluster at which cluster chain truncation should take place, used for truncation errors
       
   130 	
   171 	
   131     TBool                   iFoundProblems; ///< if ETrue after finish, it means that there where some problems FS structure and they were probably fixed;
   172     TUint                   iListArrayIndex;    ///< Current position into cluster list array
   132     RBitVector              iMediaFatBits;  ///< Storage for bit packed Fat read from media 
   173 	TUint32                 iTruncationCluster; ///< Cluster at which cluster chain truncation should take place, used for truncation errors
   133     RBitVector              iScanFatBits;   ///< Storage for bit packed Fat built up by the scan
   174 	TUint32                 iMaxClusters;       ///< Max. amount of clusters on the volume
   134 
   175 
       
   176     RBitVector              iMediaFatBits;      ///< Storage for bit packed Fat read from media 
       
   177     RBitVector              iScanFatBits;       ///< Storage for bit packed Fat built up by the scan
       
   178 
       
   179     TGenericError           iGenericError;      ///< FS error that is discovered by scanning in any mode  
       
   180     TScanDriveMode          iScanDriveMode;     ///< mode of operation
   135 	};
   181 	};
   136 
   182 
   137 
   183 
   138 
   184 
   139 #endif //SL_SCANDRV_H
   185 #endif //SL_SCANDRV_H