/*++ Copyright (c) 1990-2001 Microsoft Corporation Module Name: rfatsa.hxx Abstract: Author: Mark Shavlik (marks) 27-Mar-90 Norbert Kusters (norbertk) 15-Jan-91 Matthew Bradburn (mattbr) 01-Oct-93 --*/ #ifndef REAL_FAT_SA_DEFN #define REAL_FAT_SA_DEFN #include "hmem.hxx" #include "message.hxx" #include "fatsa.hxx" #include "bpb.hxx" #if defined ( _AUTOCHECK_ ) #define UFAT_EXPORT #elif defined ( _UFAT_MEMBER_ ) #define UFAT_EXPORT __declspec(dllexport) #else #define UFAT_EXPORT __declspec(dllimport) #endif // // 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 ); DECLARE_CLASS( INTSTACK ); 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 ); // // Sony Memory Stick thresholds // #define SMS_VOLSIZE_SMALL (70*1024*1024) // Maximum volume size to be formatted as FAT12 // Internal data types // Possible return status after validating a given cluster size typedef enum _VALIDATION_STATUS { VALID, TOO_SMALL, TOO_BIG } VALIDATION_STATUS; class REAL_FAT_SA : public FAT_SA { public: UFAT_EXPORT DECLARE_CONSTRUCTOR(REAL_FAT_SA); VIRTUAL UFAT_EXPORT ~REAL_FAT_SA( ); NONVIRTUAL UFAT_EXPORT BOOLEAN Initialize( IN OUT PLOG_IO_DP_DRIVE Drive, IN OUT PMESSAGE Message, IN BOOLEAN Formatted DEFAULT TRUE ); NONVIRTUAL UFAT_EXPORT BOOLEAN InitFATChkDirty( IN OUT PLOG_IO_DP_DRIVE Drive, IN OUT PMESSAGE Message ); NONVIRTUAL BOOLEAN Create( IN PCNUMBER_SET BadSectors, IN OUT PMESSAGE Message, IN PCWSTRING Label DEFAULT NULL, IN ULONG Flags DEFAULT FORMAT_BACKWARD_COMPATIBLE, IN ULONG ClusterSize DEFAULT 0, IN ULONG VirtualSize DEFAULT 0 ); NONVIRTUAL BOOLEAN RecoverFile( IN PCWSTRING FullPathFileName, IN OUT PMESSAGE Message ); NONVIRTUAL UFAT_EXPORT BOOLEAN Read( IN OUT PMESSAGE Message ); NONVIRTUAL BOOLEAN Write( IN OUT PMESSAGE Message ); NONVIRTUAL VOID QueryGeometry( OUT PUSHORT SectorSize, OUT PUSHORT SectorsPerTrack, OUT PUSHORT Heads, OUT PULONG HiddenSectors ); NONVIRTUAL USHORT QuerySectorsPerCluster( ) CONST; NONVIRTUAL ULONG QuerySectorsPerFat( ) CONST; NONVIRTUAL USHORT QueryReservedSectors( ) CONST; NONVIRTUAL USHORT QueryFats( ) CONST; NONVIRTUAL ULONG QueryRootEntries( ) CONST; NONVIRTUAL PARTITION_SYSTEM_ID QuerySystemId( ) CONST; NONVIRTUAL LBN QueryStartDataLbn( ) CONST; NONVIRTUAL ULONG QueryClusterCount( ) CONST; NONVIRTUAL UFAT_EXPORT SECTORCOUNT QueryFreeSectors( ) CONST; NONVIRTUAL FATTYPE QueryFatType( ) CONST; NONVIRTUAL BYTE QueryVolumeFlags( ) CONST; NONVIRTUAL VOID SetVolumeFlags( BYTE Flags, BOOLEAN ResetFlags ); NONVIRTUAL BOOLEAN RecoverChain( IN OUT PULONG StartingCluster, OUT PBOOLEAN ChangesMade, IN ULONG EndingCluster DEFAULT 0, IN BOOLEAN Replace DEFAULT FALSE, IN PBITVECTOR FatBitMap DEFAULT NULL ); STATIC USHORT ComputeSecClus( IN SECTORCOUNT Sectors, IN FATTYPE FatType, #if defined(FE_SB) && defined(_X86_) IN MEDIA_TYPE MediaType, IN ULONG SectorSize = 512 #else IN MEDIA_TYPE MediaType #endif ); NONVIRTUAL BOOLEAN IsFileContiguous( IN ULONG StartingCluster ) CONST; NONVIRTUAL BOOLEAN IsCompressed( ) CONST; NONVIRTUAL BOOLEAN IsVolumeDataAligned( ) CONST; NONVIRTUAL BOOLEAN ReadSectorZero( ); NONVIRTUAL PBIOS_PARAMETER_BLOCK GetBpb( ); NONVIRTUAL SECTORCOUNT QueryVirtualSectors( ) CONST; NONVIRTUAL VOID PrintFormatReport ( IN OUT PMESSAGE Message, IN PFILE_FS_SIZE_INFORMATION FsSizeInfo, IN PFILE_FS_VOLUME_INFORMATION FsVolInfo ); private: HMEM _mem; // memory for SECRUN // _fat inherited from FAT_SA // _fattype inherited from FAT_SA // _dir inherited from FAT_SA HMEM _mem2; // memory for SECRUN2 SECRUN _secrun2; // secrun to hold one sector FAT sector LBN _StartDataLbn; // LBN of files, or data area ULONG _ClusterCount; // number of clusters in Super Area // It actually means the number of // fat entries. PARTITION_SYSTEM_ID _sysid; // system id ULONG _sec_per_boot; // sectors for boot code. EXTENDED_BIOS_PARAMETER_BLOCK _sector_zero; PUCHAR _sector_sig; // sector signature BOOLEAN _data_aligned; // TRUE if data clusters are aligned to // FAT_FIRST_DATA_CLUSTER_ALIGNMENT boundary ULONG _AdditionalReservedSectors; // padding to be added for data alignment NONVIRTUAL VOID Construct( ); NONVIRTUAL VOID Destroy( ); NONVIRTUAL VALIDATION_STATUS ValidateClusterSize( IN ULONG ClusterSize, IN ULONG Sectors, IN ULONG SectorSize, IN ULONG Fats, IN OUT FATTYPE *FatType, OUT PULONG FatSize, OUT PULONG ClusterCount ); NONVIRTUAL ULONG ComputeDefaultClusterSize( IN ULONG Sectors, IN ULONG SectorSize, IN ULONG ReservedSectors, IN ULONG Fats, IN MEDIA_TYPE MediaType, IN FATTYPE FatType, OUT PULONG FatSize, OUT PULONG ClusterCount ); NONVIRTUAL ULONG DetermineClusterCountAndFatType ( IN OUT PULONG StartingDataLbn, IN OUT FATTYPE *Fattype ); NONVIRTUAL BOOLEAN InitializeRootDirectory ( IN PMESSAGE Message ); NONVIRTUAL BOOLEAN SetBpb( IN ULONG ClusterSize, IN ULONG Flags, IN PMESSAGE Message ); NONVIRTUAL BOOLEAN SetBpb( ); NONVIRTUAL BOOLEAN DupFats( ); NONVIRTUAL LBN ComputeStartDataLbn( ) CONST; NONVIRTUAL ULONG ComputeRootEntries( ) CONST; 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 ); NONVIRTUAL BOOLEAN CopyClusters( IN ULONG SourceChain, OUT PULONG DestChain, IN OUT PBITVECTOR FatBitMap, IN FIX_LEVEL FixLevel, IN OUT PMESSAGE Message ); 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 ); NONVIRTUAL ULONG SecPerBoot( ); NONVIRTUAL VOLID QueryVolId( ) CONST; NONVIRTUAL VOLID SetVolId( IN VOLID VolId ); NONVIRTUAL UCHAR QueryMediaByte( ) CONST; VIRTUAL VOID SetMediaByte( UCHAR MediaByte ); NONVIRTUAL BOOLEAN VerifyBootSector( ); NONVIRTUAL BOOLEAN CreateBootSector( IN ULONG ClusterSize, IN ULONG Flags, IN PMESSAGE Message ); BOOLEAN REAL_FAT_SA::SetBootCode( ); NONVIRTUAL BOOLEAN SetPhysicalDriveType( IN PHYSTYPE PhysType ); NONVIRTUAL BOOLEAN SetOemData( ); NONVIRTUAL BOOLEAN SetSignature( ); NONVIRTUAL BOOLEAN SetBootSignature( IN UCHAR Signature DEFAULT sigBOOTSTRAP ); BOOLEAN DosSaInit( IN OUT PMEM Mem, IN OUT PLOG_IO_DP_DRIVE Drive, IN SECTORCOUNT NumberOfSectors, IN OUT PMESSAGE Message ); BOOLEAN DosSaSetBpb( ); 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 ); NONVIRTUAL ULONG QuerySectorFromCluster( IN ULONG Cluster, OUT PUCHAR NumSectors DEFAULT NULL ); NONVIRTUAL BOOLEAN IsClusterCompressed( IN ULONG Cluster ) CONST; NONVIRTUAL VOID SetClusterCompressed( IN ULONG Cluster, IN BOOLEAN fCompressed ); NONVIRTUAL UCHAR QuerySectorsRequiredForPlainData( IN ULONG Cluster ); NONVIRTUAL BOOLEAN VerifyFatExtensions( IN FIX_LEVEL FixLevel, IN PMESSAGE Message, IN PBOOLEAN pfNeedMsg ); NONVIRTUAL VOID SetFat32RootDirStartingCluster( IN ULONG RootCluster ); NONVIRTUAL ULONG QueryFat32RootDirStartingCluster( ); NONVIRTUAL BOOLEAN CheckSectorHeapAllocation( IN FIX_LEVEL FixLevel, IN PMESSAGE Message, IN PBOOLEAN pfNeedMsg ); NONVIRTUAL BOOLEAN FreeClusterData( ULONG Cluster ); NONVIRTUAL BOOLEAN AllocateClusterData( ULONG Cluster, UCHAR NumSectors, BOOLEAN bCompressed, UCHAR PlainSize ); // // The following routines are defined for the new lightweight // format. // NONVIRTUAL BOOLEAN DiskIsUsable ( IN PCNUMBER_SET BadSectors, IN PMESSAGE Message ); NONVIRTUAL BOOLEAN WriteNewFats ( IN PCNUMBER_SET BadSectors, IN OUT PULONG BadClusters, IN PMESSAGE Message ); NONVIRTUAL BOOLEAN WriteNewRootDirAndVolumeLabel ( IN PCWSTRING Label, IN PMESSAGE Message ); NONVIRTUAL BOOLEAN WriteNewBootArea ( IN PMESSAGE Message ); NONVIRTUAL VOID PrintFormatReport ( IN ULONG BadClusters, IN PMESSAGE Message ); }; INLINE USHORT REAL_FAT_SA::QuerySectorsPerCluster( ) CONST /*++ Routine Description: This routine computes the number of sectors per cluster for the volume. Arguments: None. Return Value: The number of sectors per cluster for the volume. --*/ { return _sector_zero.Bpb.SectorsPerCluster ? _sector_zero.Bpb.SectorsPerCluster : 256; } INLINE ULONG REAL_FAT_SA::QuerySectorsPerFat( ) CONST /*++ Routine Description: This routine computes the number of sectors per FAT for the volume. Arguments: None. Return Value: The number of sectors per FAT for the volume. --*/ { if ( 0 == _sector_zero.Bpb.SectorsPerFat ) { return _sector_zero.Bpb.BigSectorsPerFat; } else { return _sector_zero.Bpb.SectorsPerFat; } } INLINE USHORT REAL_FAT_SA::QueryReservedSectors( ) CONST /*++ Routine Description: This routine computes the volume's number of Reserved Sectors, i.e. the number of sectors before the first FAT. Arguments: None. Return Value: The number of Reserved Sectors. --*/ { return _sector_zero.Bpb.ReservedSectors; } INLINE USHORT REAL_FAT_SA::QueryFats( ) CONST /*++ Routine Description: This routine computes the number of FATs on the volume. Arguments: None. Return Value: The number of FATs on the volume. --*/ { return _sector_zero.Bpb.Fats; } INLINE ULONG REAL_FAT_SA::QueryRootEntries( ) CONST /*++ Routine Description: This routine returns the number of entries in the root directory. Arguments: None. Return Value: The number of root directory entries. --*/ { return _sector_zero.Bpb.RootEntries; } INLINE PARTITION_SYSTEM_ID REAL_FAT_SA::QuerySystemId( ) CONST /*++ Routine Description: This routine computes the system ID for the volume. Arguments: None. Return Value: The system ID for the volume. --*/ { return _sysid; } INLINE LBN REAL_FAT_SA::QueryStartDataLbn( ) CONST /*++ Routine Description: This routine computes the LBN of the first logical cluster of the volume. Arguments: None. Return Value: The LBN of the first logical cluster of the volume. --*/ { return _StartDataLbn; } INLINE ULONG REAL_FAT_SA::QueryClusterCount( ) CONST /*++ Routine Description: This routine computes the total number of clusters for the volume. That is to say that the largest addressable cluster on the disk is cluster number 'QueryClusterCount() - 1'. Note that the smallest addressable cluster on the disk is 2. Arguments: None. Return Value: The total number of clusters for the volume. --*/ { return _ClusterCount; } INLINE BOOLEAN REAL_FAT_SA::IsCompressed( ) CONST /*++ Routine Description: This routine tells whether this volume is doublespaced or not. Since the class is REAL_FAT_SA, we know it's not. Arguments: Return Value: TRUE - Compressed. FALSE - Not compressed. --*/ { return FALSE; } INLINE BOOLEAN REAL_FAT_SA::IsVolumeDataAligned( ) CONST /*++ Routine Description: This routine tells whether the data clusters of this volume is aligned to FAT_FIRST_DATA_CLUSTER_ALIGNMENT boundary. Arguments: Return Value: TRUE - Aligned. FALSE - Not aligned. --*/ { return _data_aligned; } INLINE BOOLEAN REAL_FAT_SA::ReadSectorZero( ) /*++ Routine Description: This routine used to be DOS_SUPERAREA::Read(). Arguments: Return Value: TRUE - Success. FALSE - Failure. --*/ { BOOLEAN b; PEXTENDED_BIOS_PARAMETER_BLOCK Pbios; b = SECRUN::Read(); if (!b) return FALSE; Pbios = (PEXTENDED_BIOS_PARAMETER_BLOCK)SECRUN::GetBuf(); UnpackExtendedBios(&_sector_zero, Pbios); return TRUE; } INLINE PBIOS_PARAMETER_BLOCK REAL_FAT_SA::GetBpb( ) { return &(_sector_zero.Bpb); } INLINE UCHAR REAL_FAT_SA::QueryMediaByte( ) CONST /*++ Routine Description: This routine fetches the media byte from the super area's data. Arguments: None. Return Value: The media byte residing in the super area. --*/ { return _sector_zero.Bpb.Media; } INLINE VOID REAL_FAT_SA::SetMediaByte( UCHAR MediaByte ) /*++ Routine Description: This routine sets the media byte in the super area's data. Arguments: MediaByte -- Supplies the new media byte. Return Value: None. --*/ { _sector_zero.Bpb.Media = MediaByte; } INLINE SECTORCOUNT REAL_FAT_SA::QueryVirtualSectors( ) CONST /*++ Routine Description: This routine computes the number of sectors on the volume according to the file system. Arguments: None. Return Value: The number of sectors on the volume according to the file system. --*/ { return _sector_zero.Bpb.Sectors ? _sector_zero.Bpb.Sectors : _sector_zero.Bpb.LargeSectors; } INLINE VOLID REAL_FAT_SA::QueryVolId( ) CONST /*++ Routine Description: This routine fetches the volume ID from the super area's data. This routine will return 0 if volume serial numbers are not supported by the partition. Arguments: None. Return Value: The volume ID residing in the super area. --*/ { return (_sector_zero.Signature == 0x28 || _sector_zero.Signature == 0x29) ? _sector_zero.SerialNumber : 0; } INLINE VOLID REAL_FAT_SA::SetVolId( IN VOLID VolId ) /*++ Routine Description: This routine puts the volume ID into the super area's data. Arguments: VolId - The new volume ID. Return Value: The volume ID that was put. --*/ { return _sector_zero.SerialNumber = VolId; } INLINE BOOLEAN REAL_FAT_SA::SetBootSignature( IN UCHAR Signature ) /*++ Routine Description: This routine sets the boot signature in the super area. Arguments: Signature - Supplies the character to set the signature to. Return Value: FALSE - Failure. TRUE - Success. --*/ { _sector_zero.Signature = Signature; return TRUE; } INLINE VOID REAL_FAT_SA::QueryGeometry( OUT PUSHORT SectorSize, OUT PUSHORT SectorsPerTrack, OUT PUSHORT Heads, OUT PULONG HiddenSectors ) /*++ Routine Description: This method returns the geometry information stored in the Bios Parameter Block. Arguments: SectorSize -- Receives the recorded sector size. SectorsPerTrack -- Receives the recorded sectors per track. Heads -- Receives the recorded number of heads. HiddenSectors -- Receives the recorded number of hidden sectors. Return Value: None. --*/ { *SectorSize = _sector_zero.Bpb.BytesPerSector; *SectorsPerTrack = _sector_zero.Bpb.SectorsPerTrack; *Heads = _sector_zero.Bpb.Heads; *HiddenSectors = _sector_zero.Bpb.HiddenSectors; } INLINE BOOLEAN AllocateClusterData( ULONG Cluster, UCHAR NumSectors, BOOLEAN bCompressed, UCHAR PlainSize ) { DebugAbort("Didn't expect REAL_FAT_SA::AllocateClusterData() to be called"); return FALSE; } // // Defines for the volume flags in the BPB current head field. // #define FAT_BPB_RESERVED_DIRTY 0x01 #define FAT_BPB_RESERVED_TEST_SURFACE 0x02 // // Defines for the volume flags in FAT[1]. // #define CLUS1CLNSHUTDWNFAT16 0x00008000 #define CLUS1NOHRDERRFAT16 0x00004000 #define CLUS1CLNSHUTDWNFAT32 0x08000000 #define CLUS1NOHRDERRFAT32 0x04000000 #endif // REAL_FAT_SA_DEFN