mirror of https://github.com/lianthony/NT4.0
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.
713 lines
13 KiB
713 lines
13 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dossa.hxx
|
|
|
|
Abstract:
|
|
|
|
This class models the root of an HPFS or FAT file system.
|
|
|
|
Author:
|
|
|
|
Mark Shavlik (marks) 27-Mar-90
|
|
Norbert Kusters (norbertk) 25-July-91
|
|
|
|
Notes:
|
|
|
|
The super sector contains data that is common to both FAT and HPFS
|
|
file system. This data is stored at LBN 0 on such volumes. This
|
|
data maps a number of things defined by the data structures below.
|
|
|
|
--*/
|
|
|
|
#if !defined(DOSSA_DEFN)
|
|
|
|
#define DOSSA_DEFN
|
|
|
|
|
|
#include "supera.hxx"
|
|
|
|
//
|
|
// Forward references
|
|
//
|
|
|
|
DECLARE_CLASS( DOS_SUPERAREA );
|
|
DECLARE_CLASS( WSTRING );
|
|
|
|
|
|
|
|
#define sigBOOTSTRAP (UCHAR)0x29 // boot strap signature
|
|
|
|
// if any of these values change make sure alignment is not problem,
|
|
// see the alignment tables below for more information.
|
|
#define cOEM 8 // 8 bytes of OEM data
|
|
#define cLABEL 11 // number of bytes in the label
|
|
#define cSYSID 8 // number of bytes in SYS ID
|
|
|
|
enum PHYSTYPE { // ptype
|
|
PHYS_REMOVABLE, // physical drive is removable
|
|
PHYS_FIXED = 0x80 // physical drive is fixed
|
|
};
|
|
|
|
// The structures below are the aligned version of the above structures.
|
|
// Conversions between the two types is done by the Pack and UnPack methods.
|
|
// Any access to sector 0 data must be done via these aligned types.
|
|
|
|
//
|
|
// Define the Packed and Unpacked BIOS Parameter Block
|
|
//
|
|
|
|
// Unaligned Sector 0
|
|
typedef struct UNALIGNED_SECTOR_ZERO {
|
|
UCHAR IntelNearJumpCommand[1]; // Intel Jump command
|
|
UCHAR BootStrapJumpOffset[2]; // offset of boot strap code
|
|
UCHAR OemData[cOEM]; // OEM data
|
|
UCHAR BytesPerSector[2]; // BPB
|
|
UCHAR SectorsPerCluster[1]; //
|
|
UCHAR ReservedSectors[2]; //
|
|
UCHAR Fats[1]; //
|
|
UCHAR RootEntries[2]; //
|
|
UCHAR Sectors[2]; //
|
|
UCHAR Media[1]; //
|
|
UCHAR SectorsPerFat[2]; //
|
|
UCHAR SectorsPerTrack[2]; //
|
|
UCHAR Heads[2]; //
|
|
UCHAR HiddenSectors[4]; //
|
|
UCHAR LargeSectors[4]; //
|
|
UCHAR PhysicalDrive[1]; // 0 = removable, 80h = fixed
|
|
UCHAR CurrentHead[1]; // not used by fs utils
|
|
UCHAR Signature[1]; // boot signature
|
|
UCHAR SerialNumber[4]; // serial number
|
|
UCHAR Label[cLABEL]; // volume label, aligned padded
|
|
UCHAR SystemIdText[cSYSID]; // system ID, FAT for example
|
|
UCHAR StartBootCode; // First byte of boot code
|
|
} *PUNALIGNED_SECTOR_ZERO;
|
|
|
|
// Aligned Sector 0
|
|
typedef struct ALIGNED_SECTOR_ZERO {
|
|
UCHAR IntelNearJumpCommand; // Intel Jump command
|
|
USHORT BootStrapJumpOffset; // offset of boot strap code
|
|
UCHAR OemData[cOEM]; // OEM data
|
|
USHORT BytesPerSector;
|
|
UCHAR SectorsPerCluster;
|
|
USHORT ReservedSectors;
|
|
UCHAR Fats;
|
|
USHORT RootEntries;
|
|
USHORT SectorCount_16bits; // 16 bit count
|
|
UCHAR MediaByte;
|
|
USHORT SectorsPerFat;
|
|
USHORT SectorsPerTrack;
|
|
USHORT Heads;
|
|
ULONG HiddenSectors;
|
|
ULONG SectorCount_32bits; // 32 bit count
|
|
UCHAR PhysicalDrive; // 0 = removable, 80h = fixed
|
|
UCHAR CurrentHead; // not used by fs utils
|
|
UCHAR Signature; // boot signature
|
|
ULONG SerialNumber; // serial number
|
|
UCHAR Label[cLABEL]; // volume label, aligned padded
|
|
UCHAR SystemIdText[cSYSID]; // system ID
|
|
} *PALIGNED_SECTOR_ZERO;
|
|
|
|
//
|
|
// The following types and macros are used to help unpack the packed and
|
|
// misaligned fields found in the Bios parameter block
|
|
//
|
|
#if !defined( _UCHAR_DEFINED_ )
|
|
|
|
#define _UCHAR_DEFINED_
|
|
|
|
// This code is taken directly from the NT HPFS code
|
|
|
|
typedef union _UCHAR1 {
|
|
UCHAR Uchar[1];
|
|
UCHAR ForceAlignment;
|
|
} UCHAR1, *PUCHAR1;
|
|
|
|
typedef union _UCHAR2 {
|
|
UCHAR Uchar[2];
|
|
USHORT ForceAlignment;
|
|
} UCHAR2, *PUCHAR2;
|
|
|
|
typedef union _UCHAR4 {
|
|
UCHAR Uchar[4];
|
|
ULONG ForceAlignment;
|
|
} UCHAR4, *PUCHAR4;
|
|
|
|
//
|
|
// This macro copies an unaligned src byte to an aligned dst byte
|
|
//
|
|
|
|
#define CopyUchar1(Dst,Src) { \
|
|
((PUCHAR1)(Dst))->Uchar[0] = ((PUCHAR1)(Src))->Uchar[0]; \
|
|
}
|
|
|
|
//
|
|
// This macro copies an unaligned src word to an aligned dst word
|
|
//
|
|
|
|
#define CopyUchar2(Dst,Src) { \
|
|
((PUCHAR2)(Dst))->Uchar[0] = ((PUCHAR2)(Src))->Uchar[0]; \
|
|
((PUCHAR2)(Dst))->Uchar[1] = ((PUCHAR2)(Src))->Uchar[1]; \
|
|
}
|
|
|
|
//
|
|
// This macro copies an unaligned src longword to an aligned dsr longword
|
|
//
|
|
|
|
#define CopyUchar4(Dst,Src) { \
|
|
((PUCHAR4)(Dst))->Uchar[0] = ((PUCHAR4)(Src))->Uchar[0]; \
|
|
((PUCHAR4)(Dst))->Uchar[1] = ((PUCHAR4)(Src))->Uchar[1]; \
|
|
((PUCHAR4)(Dst))->Uchar[2] = ((PUCHAR4)(Src))->Uchar[2]; \
|
|
((PUCHAR4)(Dst))->Uchar[3] = ((PUCHAR4)(Src))->Uchar[3]; \
|
|
}
|
|
|
|
#endif // _UCHAR_DEFINED_
|
|
|
|
//
|
|
// This macro Uncopies an unaligned src byte to an aligned dst byte
|
|
//
|
|
|
|
#define UnCopyUchar1(Dst,Src) { \
|
|
((PUCHAR1)(Src))->Uchar[0] = ((PUCHAR1)(Dst))->Uchar[0]; \
|
|
}
|
|
|
|
//
|
|
// This macro Uncopies an unaligned src word to an aligned dst word
|
|
//
|
|
|
|
#define UnCopyUchar2(Dst,Src) { \
|
|
((PUCHAR2)(Src))->Uchar[0] = ((PUCHAR2)(Dst))->Uchar[0]; \
|
|
((PUCHAR2)(Src))->Uchar[1] = ((PUCHAR2)(Dst))->Uchar[1]; \
|
|
}
|
|
|
|
//
|
|
// This macro Uncopies an unaligned src longword to an aligned dst longword
|
|
//
|
|
|
|
#define UnCopyUchar4(Dst,Src) { \
|
|
((PUCHAR4)(Src))->Uchar[0] = ((PUCHAR4)(Dst))->Uchar[0]; \
|
|
((PUCHAR4)(Src))->Uchar[1] = ((PUCHAR4)(Dst))->Uchar[1]; \
|
|
((PUCHAR4)(Src))->Uchar[2] = ((PUCHAR4)(Dst))->Uchar[2]; \
|
|
((PUCHAR4)(Src))->Uchar[3] = ((PUCHAR4)(Dst))->Uchar[3]; \
|
|
}
|
|
|
|
// the text for the oem data field
|
|
#define OEMTEXT "MSDOS5.0"
|
|
#define OEMTEXTLENGTH 8
|
|
|
|
|
|
class DOS_SUPERAREA : public SUPERAREA {
|
|
|
|
public:
|
|
|
|
VIRTUAL
|
|
~DOS_SUPERAREA(
|
|
);
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
Read(
|
|
);
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
Write(
|
|
);
|
|
|
|
VIRTUAL
|
|
PVOID
|
|
GetBuf(
|
|
);
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
Create(
|
|
IN PCNUMBER_SET BadSectors,
|
|
IN OUT PMESSAGE Message,
|
|
IN PCWSTRING Label DEFAULT NULL,
|
|
IN ULONG ClusterSize DEFAULT 0
|
|
) PURE;
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
VerifyAndFix(
|
|
IN FIX_LEVEL FixLevel,
|
|
IN OUT PMESSAGE Message,
|
|
IN BOOLEAN Verbose DEFAULT FALSE,
|
|
IN BOOLEAN OnlyIfDirty DEFAULT FALSE,
|
|
IN BOOLEAN RecoverFree DEFAULT FALSE,
|
|
IN BOOLEAN RecoverAlloc DEFAULT FALSE
|
|
) PURE;
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
RecoverFile(
|
|
IN PCWSTRING FullPathFileName,
|
|
IN OUT PMESSAGE Message
|
|
) PURE;
|
|
|
|
NONVIRTUAL
|
|
PALIGNED_SECTOR_ZERO
|
|
GetSectorZero(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsFormatted(
|
|
) CONST;
|
|
|
|
VIRTUAL
|
|
PARTITION_SYSTEM_ID
|
|
QuerySystemId(
|
|
) CONST PURE;
|
|
|
|
NONVIRTUAL
|
|
SECTORCOUNT
|
|
QuerySectors(
|
|
) CONST;
|
|
|
|
VIRTUAL
|
|
SECTORCOUNT
|
|
QueryFreeSectors(
|
|
) CONST PURE;
|
|
|
|
NONVIRTUAL
|
|
VOLID
|
|
SetVolId(
|
|
IN VOLID VolId
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOLID
|
|
QueryVolId(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
VOLID
|
|
CreateVolId(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
UCHAR
|
|
QueryMediaByte(
|
|
) CONST;
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
QueryLabel(
|
|
OUT PWSTRING Label
|
|
) CONST;
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
SetLabel(
|
|
IN PCWSTRING NewLabel
|
|
);
|
|
|
|
STATIC
|
|
BOOLEAN
|
|
IsValidString(
|
|
IN PCWSTRING String
|
|
);
|
|
|
|
protected:
|
|
|
|
DECLARE_CONSTRUCTOR( DOS_SUPERAREA );
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
Initialize(
|
|
IN OUT PMEM Mem,
|
|
IN OUT PLOG_IO_DP_DRIVE Drive,
|
|
IN SECTORCOUNT NumberOfSectors,
|
|
IN OUT PMESSAGE Message
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
CreateBootSector(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
VerifyBootSector(
|
|
);
|
|
|
|
VIRTUAL
|
|
BOOLEAN
|
|
SetBpb(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
PackSectorZero(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
UnPackSectorZero(
|
|
);
|
|
|
|
ALIGNED_SECTOR_ZERO _sector_zero;
|
|
|
|
private:
|
|
|
|
PUCHAR _sector_sig; // sector signature
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
Construct(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
Destroy(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
QuerySecMeg(
|
|
IN ULONG MegaBytes
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetOemData(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetBootCode(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetBootSignature(
|
|
IN UCHAR Signature DEFAULT sigBOOTSTRAP
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetSignature(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetPhysicalDriveType(
|
|
IN PHYSTYPE PhysType
|
|
);
|
|
|
|
};
|
|
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
DOS_SUPERAREA::Read(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls SECRUN's read routine and then unpacks the
|
|
sectorzero data into a local structure.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
FALSE - Failure.
|
|
TRUE - Success.
|
|
|
|
--*/
|
|
{
|
|
return SECRUN::Read() && UnPackSectorZero();
|
|
}
|
|
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
DOS_SUPERAREA::Write(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine packs the sector zero structure in the SECRUN and then
|
|
calls SECRUN's write routine.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
FALSE - Failure.
|
|
TRUE - Success.
|
|
|
|
--*/
|
|
{
|
|
return PackSectorZero() && SECRUN::Write();
|
|
}
|
|
|
|
|
|
INLINE
|
|
PVOID
|
|
DOS_SUPERAREA::GetBuf(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a pointer to the beginning of the read/write
|
|
buffer.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A pointer to a read/write buffer.
|
|
|
|
--*/
|
|
{
|
|
return PackSectorZero() ? SECRUN::GetBuf() : NULL;
|
|
}
|
|
|
|
|
|
INLINE
|
|
PALIGNED_SECTOR_ZERO
|
|
DOS_SUPERAREA::GetSectorZero(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a pointer to the unpacked version of sector zero.
|
|
The values modified here will take effect on disk after a write.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A pointer to an unpacked sector zero.
|
|
|
|
--*/
|
|
{
|
|
return &_sector_zero;
|
|
}
|
|
|
|
|
|
INLINE
|
|
SECTORCOUNT
|
|
DOS_SUPERAREA::QuerySectors(
|
|
) 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.SectorCount_16bits ? _sector_zero.SectorCount_16bits :
|
|
_sector_zero.SectorCount_32bits;
|
|
}
|
|
|
|
|
|
INLINE
|
|
VOLID
|
|
DOS_SUPERAREA::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
|
|
VOLID
|
|
DOS_SUPERAREA::CreateVolId(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine puts a new volume identifier in the super area.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The volume id that was created.
|
|
|
|
--*/
|
|
{
|
|
return SetVolId(ComputeVolId());
|
|
}
|
|
|
|
|
|
INLINE
|
|
ULONG
|
|
DOS_SUPERAREA::QuerySecMeg(
|
|
IN ULONG MegaBytes
|
|
) CONST
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine computes the number of sectors contained in 'MegaBytes'
|
|
megabytes.
|
|
|
|
Arguments:
|
|
|
|
MegaBytes - Supplies the number of megabytes.
|
|
|
|
Return Value:
|
|
|
|
The number of sectors contained in 'MegaBytes' megabytes.
|
|
|
|
--*/
|
|
{
|
|
return ( (MegaBytes<<20) / _drive->QuerySectorSize());
|
|
}
|
|
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
DOS_SUPERAREA::SetOemData(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the OEM data in the super area.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
FALSE - Failure.
|
|
TRUE - Success.
|
|
|
|
--*/
|
|
{
|
|
memcpy( (void*)_sector_zero.OemData, (void*)OEMTEXT, OEMTEXTLENGTH);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
DOS_SUPERAREA::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
|
|
VOLID
|
|
DOS_SUPERAREA::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
|
|
UCHAR
|
|
DOS_SUPERAREA::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.MediaByte;
|
|
}
|
|
|
|
|
|
#endif // DOSSA_DEFN
|