Windows NT 4.0 source code leak
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

/*++
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