Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

887 lines
18 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
fatsa.hxx
Abstract:
--*/
#ifndef FATSUPERA_DEFN
#define FATSUPERA_DEFN
#include "hmem.hxx"
#include "supera.hxx"
#include "message.hxx"
#if defined ( _AUTOCHECK_ ) || defined( _EFICHECK_ )
#define UFAT_EXPORT
#elif defined ( _UFAT_MEMBER_ )
#define UFAT_EXPORT __declspec(dllexport)
#else
#define UFAT_EXPORT __declspec(dllimport)
#endif
#define FAT_TYPE_UNKNOWN 42 // DRIVE where type wasn't known
#define FAT_TYPE_FAT32 32 // FAT 32 with DWORD SCN and no EA
#define FAT_TYPE_EAS_OKAY 16 // Fat drive with EA's OK
//
// Forward references
//
DECLARE_CLASS( ARRAY );
DECLARE_CLASS( BITVECTOR );
DECLARE_CLASS( EA_HEADER );
DECLARE_CLASS( FAT );
DECLARE_CLASS( FAT_SA );
DECLARE_CLASS( FAT_DIRENT );
DECLARE_CLASS( FATDIR );
DECLARE_CLASS( GENERIC_STRING );
#if !defined(_EFICHECK_)
DECLARE_CLASS( INTSTACK );
#endif
DECLARE_CLASS( NUMBER_SET );
DECLARE_CLASS( LOG_IO_DP_DRIVE );
DECLARE_CLASS( MESSAGE );
DECLARE_CLASS( ROOTDIR );
DECLARE_CLASS( SORTED_LIST );
DECLARE_CLASS( TIMEINFO );
DECLARE_CLASS( WSTRING );
DEFINE_POINTER_TYPES( PFATDIR );
DECLARE_CLASS( FILEDIR );
enum FATTYPE {
SMALL, // 12 bit fat
LARGE16, // 16 bit fat
LARGE32, // 32 bit fat
INVALID_FATTYPE // Invalid value
};
// the text for the oem data field
#define OEMTEXT "MSDOS5.0"
#define OEMTEXTLENGTH 8
#define sigBOOTSTRAP (UCHAR)0x29 // boot strap signature
CONST MaxSecPerClus = 128; // The maximum number of sectors per cluster.
struct _EA_INFO {
USHORT OwnHandle;
ULONG PreceedingCn; // Clus num preceeding first cluster of set.
ULONG LastCn; // The number of the last cluster in the set.
STR OwnerFileName[14]; // Owner file name as found in ea set.
UCHAR UsedCount; // Number of files using ea set.
STR UserFileName[14]; // File name of ea set user.
ULONG UserFileEntryCn; // Clus num of directory for file.
ULONG UserFileEntryNumber; // Dirent num for file name.
};
DEFINE_TYPE( struct _EA_INFO, EA_INFO );
struct _FATCHK_REPORT {
ULONG HiddenEntriesCount;
ULONG HiddenClusters;
ULONG FileEntriesCount;
ULONG FileClusters;
ULONG DirEntriesCount;
ULONG DirClusters;
ULONG ExitStatus;
};
DEFINE_TYPE( struct _FATCHK_REPORT, FATCHK_REPORT );
#if !defined(_EFICHECK_)
struct _CENSUS_REPORT {
ULONG FileEntriesCount;
ULONG FileClusters;
ULONG DirEntriesCount;
ULONG DirClusters;
ULONG EaClusters;
};
DEFINE_TYPE( struct _CENSUS_REPORT, CENSUS_REPORT );
#endif
class FAT_SA : public SUPERAREA {
public:
UFAT_EXPORT
DECLARE_CONSTRUCTOR(FAT_SA);
VIRTUAL
UFAT_EXPORT
~FAT_SA(
);
VIRTUAL
BOOLEAN
Initialize(
IN OUT PLOG_IO_DP_DRIVE Drive,
IN OUT PMESSAGE Message,
IN BOOLEAN Formatted
) PURE;
VIRTUAL
BOOLEAN
Create(
IN PCNUMBER_SET BadSectors,
IN OUT PMESSAGE Message,
IN PCWSTRING Label DEFAULT NULL,
IN BOOLEAN BackwardCompatible DEFAULT TRUE,
IN ULONG ClusterSize DEFAULT 0,
IN ULONG VirtualSize DEFAULT 0
) PURE;
NONVIRTUAL
BOOLEAN
VerifyAndFix(
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN ULONG Flags DEFAULT 0,
IN ULONG LogFileSize DEFAULT 0,
OUT PULONG ExitStatus DEFAULT NULL,
IN PCWSTRING DriveLetter DEFAULT NULL
);
NONVIRTUAL
BOOLEAN
RecoverFile(
IN PCWSTRING FullPathFileName,
IN OUT PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
Read(
);
VIRTUAL
BOOLEAN
Read(
IN OUT PMESSAGE Message
) PURE;
NONVIRTUAL
BOOLEAN
Write(
);
VIRTUAL
BOOLEAN
Write(
IN OUT PMESSAGE Message
) PURE;
NONVIRTUAL
PFAT
GetFat(
);
NONVIRTUAL
PROOTDIR
GetRootDir(
);
NONVIRTUAL
PFILEDIR
GetFileDir(
);
VIRTUAL
USHORT
QuerySectorsPerCluster(
) CONST PURE;
VIRTUAL
ULONG
QuerySectorsPerFat(
) CONST PURE;
VIRTUAL
ULONG
QueryVirtualSectors(
) CONST PURE;
VIRTUAL
USHORT
QueryFats(
) CONST PURE;
VIRTUAL
PARTITION_SYSTEM_ID
QuerySystemId(
) CONST PURE;
VIRTUAL
LBN
QueryStartDataLbn(
) CONST PURE;
VIRTUAL
ULONG
QueryClusterCount(
) CONST PURE;
NONVIRTUAL
SECTORCOUNT
QueryFreeSectors(
) CONST;
NONVIRTUAL
FATTYPE
QueryFatType(
) CONST;
VIRTUAL
BYTE
QueryVolumeFlags(
) CONST PURE;
VIRTUAL
VOID
SetVolumeFlags(
BYTE Flags,
BOOLEAN ResetFlags
) PURE;
VIRTUAL
BOOLEAN
RecoverChain(
IN OUT PULONG StartingCluster,
OUT PBOOLEAN ChangesMade,
IN ULONG EndingCluster DEFAULT 0,
IN BOOLEAN Replace DEFAULT FALSE
) PURE;
VIRTUAL
BOOLEAN
QueryLabel(
OUT PWSTRING Label
) CONST;
NONVIRTUAL
BOOLEAN
QueryLabel(
OUT PWSTRING Label,
OUT PTIMEINFO TimeInfo
) CONST;
NONVIRTUAL
BOOLEAN
SetLabel(
IN PCWSTRING NewLabel
);
NONVIRTUAL
UFAT_EXPORT
ULONG
QueryFileStartingCluster(
IN PCWSTRING FullPathFileName,
OUT PHMEM Hmem DEFAULT NULL,
OUT PPFATDIR Directory DEFAULT NULL,
OUT PBOOLEAN DeleteDirectory DEFAULT NULL,
OUT PFAT_DIRENT DirEntry DEFAULT NULL
);
#if !defined(_EFICHECK_)
NONVIRTUAL
UFAT_EXPORT
BOOLEAN
QueryCensusAndRelocate (
OUT PCENSUS_REPORT CensusReport DEFAULT NULL,
IN OUT PINTSTACK RelocationStack DEFAULT NULL,
OUT PBOOLEAN Relocated DEFAULT NULL
);
#endif
STATIC
USHORT
ComputeSecClus(
IN SECTORCOUNT Sectors,
IN FATTYPE FatType,
#if defined(FE_SB) && defined(_X86_)
IN MEDIA_TYPE MediaType,
IN ULONG SectorSize = 512 /* FMR */
#else
IN MEDIA_TYPE MediaType
#endif
);
VIRTUAL
BOOLEAN
IsCompressed(
) CONST PURE;
VIRTUAL
BOOLEAN
ReadSectorZero(
) PURE;
STATIC BOOLEAN
FAT_SA::IsValidString(
IN PCWSTRING String
);
//
// These routines are used to access the CVF_EXTENSIONS on
// FATDB, and they do the minimal thing on REAL_FAT.
//
VIRTUAL
ULONG
QuerySectorFromCluster(
IN ULONG Cluster,
OUT PUCHAR NumSectors DEFAULT NULL
) PURE;
VIRTUAL
BOOLEAN
IsClusterCompressed(
IN ULONG Cluster
) CONST PURE;
VIRTUAL
VOID
SetClusterCompressed(
IN ULONG Cluster,
IN BOOLEAN fCompressed
) PURE;
VIRTUAL
UCHAR
QuerySectorsRequiredForPlainData(
IN ULONG Cluster
) PURE;
//
// These routines are used to manage the sector heap for
// FATDB, and do nothing on REAL_FAT.
//
VIRTUAL
BOOLEAN
FreeClusterData(
IN ULONG Cluster
) PURE;
VIRTUAL
BOOLEAN
AllocateClusterData(
IN ULONG Cluster,
IN UCHAR NumSectors,
IN BOOLEAN bCompressed,
IN UCHAR PlainSize
) PURE;
protected:
PFAT _fat; // Pointer to FAT;
FATTYPE _ft; // fat type required by area
PROOTDIR _dir; // Pointer to Root directory
PFILEDIR _dirF32; // Pointer to FAT 32 Root dir
PHMEM _hmem_F32; // Pointer to the Fat 32 Root dir data
VIRTUAL
BOOLEAN
SetBpb(
) PURE;
VIRTUAL
ULONG
SecPerBoot(
) PURE;
VIRTUAL
VOLID
QueryVolId(
) CONST PURE;
VIRTUAL
VOLID
SetVolId(
IN VOLID VolId
) PURE;
VIRTUAL
UCHAR
QueryMediaByte(
) CONST PURE;
VIRTUAL
VOID
SetMediaByte(
UCHAR MediaByte
) PURE;
NONVIRTUAL
PARTITION_SYSTEM_ID
ComputeSystemId(
) CONST;
NONVIRTUAL
FATTYPE
ComputeFatType(
) CONST;
NONVIRTUAL
BOOLEAN
RecoverOrphans(
IN OUT PBITVECTOR FatBitMap,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage,
IN OUT PFATCHK_REPORT Report,
OUT PBOOLEAN Changes
);
VIRTUAL
BOOLEAN
VerifyFatExtensions(
IN FIX_LEVEL FixLevel,
IN PMESSAGE Message,
IN PBOOLEAN pfNeedMsg
) PURE;
VIRTUAL
VOID
SetFat32RootDirStartingCluster (
IN ULONG RootCluster
) PURE;
VIRTUAL
ULONG
QueryFat32RootDirStartingCluster (
) PURE;
VIRTUAL
BOOLEAN
CheckSectorHeapAllocation(
IN FIX_LEVEL FixLevel,
IN PMESSAGE Message,
IN PBOOLEAN pfNeedMsg
) PURE;
private:
NONVIRTUAL
VOID
Construct(
);
NONVIRTUAL
VOID
Destroy(
);
NONVIRTUAL
ULONG
ComputeRootEntries(
) CONST;
NONVIRTUAL
BOOLEAN
PerformEaLogOperations(
IN ULONG EaFileCn,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
PEA_INFO
RecoverEaSets(
IN ULONG EaFileCn,
OUT PUSHORT NumEas,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
ULONG
VerifyAndFixEaSet(
IN ULONG PreceedingCluster,
OUT PEA_INFO EaInfo,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
VerifyAndFixFat32RootDir (
IN OUT PBITVECTOR FatBitMap,
IN PMESSAGE Message,
IN OUT PFATCHK_REPORT Report,
IN OUT PBOOLEAN NeedErrorMessage
);
NONVIRTUAL
BOOLEAN
RelocateNewFat32RootDirectory (
IN OUT PFATCHK_REPORT Report,
IN OUT PBITVECTOR FatBitMap,
IN PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
EaSort(
IN OUT PEA_INFO EaInfos,
IN ULONG NumEas,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
RebuildEaHeader(
IN OUT PULONG StartingCluster,
IN OUT PEA_INFO EaInfos,
IN ULONG NumEas,
IN OUT PMEM EaHeaderMem,
OUT PEA_HEADER EaHeader,
IN OUT PBITVECTOR FatBitMap,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
WalkDirectoryTree(
IN OUT PEA_INFO EaInfos,
IN OUT PUSHORT NumEas,
IN OUT PBITVECTOR FatBitMap,
OUT PFATCHK_REPORT Report,
IN FIX_LEVEL FixLevel,
IN BOOLEAN RecoverAlloc,
IN OUT PMESSAGE Message,
IN BOOLEAN Verbose,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
ValidateDirent(
IN OUT PFAT_DIRENT Dirent,
IN PCWSTRING FilePath,
IN FIX_LEVEL FixLevel,
IN BOOLEAN RecoverAlloc,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage,
IN OUT PBITVECTOR FatBitMap,
OUT PBOOLEAN CrossLinkDetected,
OUT PULONG CrossLinkPreviousCluster,
OUT PULONG ExitStatus
);
NONVIRTUAL
BOOLEAN
EraseEaHandle(
IN PEA_INFO EaInfos,
IN USHORT NumEasLeft,
IN USHORT NumEas,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
ValidateEaHandle(
IN OUT PFAT_DIRENT Dirent,
IN ULONG DirClusterNumber,
IN ULONG DirEntryNumber,
IN OUT PEA_INFO EaInfos,
IN USHORT NumEas,
IN PCWSTRING FilePath,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
CopyClusters(
IN ULONG SourceChain,
OUT PULONG DestChain,
IN OUT PBITVECTOR FatBitMap,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
ValidateDirent(
IN OUT PFAT_DIRENT Dirent,
IN PCWSTRING FilePath,
IN FIX_LEVEL FixLevel,
IN BOOLEAN RecoverAlloc,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage,
IN OUT PBITVECTOR FatBitMap,
OUT PBOOLEAN CrossLinkDetected,
OUT PUSHORT CrossLinkPreviousCluster,
OUT PULONG ExitStatus
);
NONVIRTUAL
BOOLEAN
ValidateEaHandle(
IN OUT PFAT_DIRENT Dirent,
IN USHORT DirClusterNumber,
IN ULONG DirEntryNumber,
IN OUT PEA_INFO EaInfos,
IN USHORT NumEas,
IN PCWSTRING FilePath,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
NONVIRTUAL
BOOLEAN
CopyClusters(
IN USHORT SourceChain,
OUT PUSHORT DestChain,
IN OUT PBITVECTOR FatBitMap,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
PurgeEaFile(
IN PEA_INFO EaInfos,
IN USHORT NumEas,
IN OUT PBITVECTOR FatBitMap,
IN FIX_LEVEL FixLevel,
IN OUT PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);
#if !defined(_EFICHECK_)
NONVIRTUAL
BOOLEAN
InitRelocationList(
IN OUT PINTSTACK RelocationStack,
IN OUT PULONG RelocatedChain,
IN OUT PSORTED_LIST ClustersToRelocate,
OUT PBOOLEAN Relocated
);
NONVIRTUAL
BOOLEAN
RelocateFirstCluster(
IN OUT PFAT_DIRENT Dirent
);
NONVIRTUAL
ULONG
RelocateOneCluster(
IN ULONG Cluster,
IN ULONG Previous
);
NONVIRTUAL
BOOLEAN
DoDirectoryCensusAndRelocation(
IN OUT PFATDIR Directory,
IN OUT PCENSUS_REPORT CensusReport,
IN OUT PSORTED_LIST ClustersToRelocate,
IN OUT PULONG RelocatedChain,
OUT PBOOLEAN Relocated
);
NONVIRTUAL
BOOLEAN
DoVolumeCensusAndRelocation(
IN OUT PCENSUS_REPORT CensusReport,
IN OUT PSORTED_LIST ClustersToRelocate,
IN OUT PULONG RelocatedChain,
OUT PBOOLEAN Relocated
);
#endif
NONVIRTUAL
BOOLEAN
RecoverFreeSpace(
IN OUT PMESSAGE Message
);
NONVIRTUAL
BOOLEAN
AllocSectorsForChain(
IN ULONG StartingCluster
);
};
INLINE
BOOLEAN
FAT_SA::Read(
)
/*++
Routine Description:
This routine simply calls the other read with the default message
object.
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
MESSAGE msg;
return Read(&msg);
}
INLINE
BOOLEAN
FAT_SA::Write(
)
/*++
Routine Description:
This routine simply calls the other write with the default message
object.
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
MESSAGE msg;
return Write(&msg);
}
INLINE
PFAT
FAT_SA::GetFat(
)
/*++
Routine Description:
This routine returns a pointer to the FAT maintained by this class.
It is not necessary to read or write this FAT since it shares memory
with the FAT_SA class and thus performing FAT_SA::Read will read in
the FAT and performing FAT_SA::Write will write the FAT. Additionally,
performing a FAT_SA::Write will duplicate the information in the local
FAT object to all other FATs on the disk.
Arguments:
None.
Return Value:
A pointer to the FAT super area's FAT.
--*/
{
return _fat;
}
INLINE
PROOTDIR
FAT_SA::GetRootDir(
)
/*++
Routine Description:
This routine return a pointer to the FAT super area's root directory.
The memory of this root directory is shared with the FAT super area.
Hence, as with 'GetFat' it is not necessary to read or write the
root directory returned by this routine if a FAT_SA::Read or
FAT_SA::Write is being performed respecively.
Arguments:
None.
Return Value:
A pointer to the FAT super area's root directory.
--*/
{
return _dir;
}
INLINE
PFILEDIR
FAT_SA::GetFileDir(
)
/*++
Routine Description:
This routine return a pointer to the FAT super area's root directory.
The memory of this root directory is shared with the FAT super area.
Hence, as with 'GetFat' it is not necessary to read or write the
root directory returned by this routine if a FAT_SA::Read or
FAT_SA::Write is being performed respecively.
NOTE: Compiler refused to let me return either type FILE or ROOT DIR
as a FATDIR from GetRootDir() above, so I made this parallel function,
and coded a call to both in the FAT 32 cases that called GetRootDir.
Arguments:
None.
Return Value:
A pointer to the FAT 32 super area's FILEDIR type root directory.
--*/
{
return _dirF32;
}
extern BOOLEAN
IsValidString(
IN PCWSTRING String
);
#endif // FATSUPERA_DEFN
extern VOID
dofmsg(
IN PMESSAGE Message,
IN OUT PBOOLEAN NeedErrorsMessage
);