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.
767 lines
15 KiB
767 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
spareb.hxx
|
|
|
|
Abstract:
|
|
|
|
SpareB contains various emergency supplies and fixup information
|
|
which isn't in the superblock since the Superblock
|
|
is read only and to decrease the liklihood that a flakey write
|
|
will cause the superblock to become unreadable.
|
|
|
|
This sector is located directly after the superblock - sector 17.
|
|
|
|
Note that the number of spare DIRBLKs is a format computed by
|
|
HPFS format.
|
|
|
|
Checksums are done on both Super Block and the Spare Block.
|
|
Both checksums are stored in the Spare Block. The checksum
|
|
field for the Super Block must be set when
|
|
calculating the checksum for the Spare Block. The checksum
|
|
field for the Spare Block must be zero when
|
|
calculating the checksum for the Spare Block.
|
|
If both checksum fields are zero, the checksums have not been
|
|
calculated for the volume.
|
|
|
|
The data in this object reflects the HPFS on disk super area,
|
|
which must be compatable w/ all other HPFS' so NOTHING can
|
|
be changed in this data structure that will change the on disk
|
|
format!
|
|
|
|
The Spare block use a number of helper objects to perform its
|
|
tasks:
|
|
HOTFIXLISTS
|
|
DIRBLKS
|
|
CODEPAGETABLE
|
|
|
|
These objects are Created by SpareB's Create method, and are gotten
|
|
by SpareB's Get method. SpareB stores only the LBNs for these
|
|
objects because the objects are LBN based. Queries for these
|
|
objects return LBNs, NOT object pointers since the LBN can be
|
|
used to create an object of the requested type.
|
|
|
|
NB The member 'Create' is to be used by FORMAT.
|
|
Beware!! It will trash your disk.
|
|
|
|
Author:
|
|
|
|
Mark Shavlik (marks) 27-Mar-90
|
|
|
|
--*/
|
|
|
|
#if ! defined( SPAREB_DEFN )
|
|
|
|
#define SPAREB_DEFN
|
|
|
|
|
|
#include "secrun.hxx"
|
|
|
|
DECLARE_CLASS( SPAREB );
|
|
DECLARE_CLASS( HPFS_BITMAP );
|
|
DECLARE_CLASS( LOG_IO_DP_DRIVE );
|
|
DECLARE_CLASS( MEM );
|
|
DECLARE_CLASS( SUPERB );
|
|
|
|
|
|
// lbn where SPAREBLOCK is located
|
|
#define lbnSPAREB 17
|
|
|
|
// 1 sector size
|
|
#define csecSPAREB 1
|
|
|
|
#define DIRBLK_SIZE 2048 // The number of bytes in a dir block.
|
|
|
|
// Spare Block information stored in a bit vector form in the bFlag
|
|
// field of the _SPAREB data structure defined below.
|
|
|
|
enum SPI {
|
|
|
|
SPI_DIRTY = 1, // File system is dirty
|
|
SPI_SPARE = 2, // spare DIRBLKs are used
|
|
SPI_HFUSED = 4, // Hot fix list used
|
|
SPI_BADSEC = 8, // bad sectors, corrupt disk
|
|
SPI_BADBM = 0x10, // bad bitmap block
|
|
SPI_FSVER = 0x80 // FS version < SuperBlocks version
|
|
|
|
};
|
|
|
|
|
|
// spare block data, the data layout must not change because this data
|
|
// must be on disk compatable w/ all other HPFS'
|
|
|
|
struct _SPAREB {
|
|
|
|
ULONG sig1; /* signature value 1 */
|
|
ULONG sig2; /* signature value 2 */
|
|
|
|
BYTE bFlag; /* cleanliness flag */
|
|
BYTE bAlign[3]; /* alignment */
|
|
|
|
LBN lbnHotFix; /* first hotfix list Psector */
|
|
ULONG culHotFixes; /* # of hot fixes in effect */
|
|
ULONG culMaxHotFixes; /* max size of hot fix list */
|
|
|
|
ULONG cdbSpares; /* # of spare dirblks */
|
|
ULONG cdbMaxSpare; /* max num of spare DB values. */
|
|
LBN lbnCPInfo; /* code page info sector */
|
|
ULONG culCP; /* number of code pages */
|
|
ULONG chkSuperBlock; /* Checksum of Super Block */
|
|
ULONG chkSpareBlock; /* Checksum of Spare Block */
|
|
ULONG aulExtra[15]; /* some extra space for future use */
|
|
LBN albnSpareDirblks[101];/* LBNs of spare dirblks */
|
|
|
|
};
|
|
|
|
class SPAREB : public SECRUN {
|
|
|
|
public:
|
|
|
|
DECLARE_CONSTRUCTOR( SPAREB );
|
|
|
|
VIRTUAL
|
|
~SPAREB(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
Initialize(
|
|
IN OUT PMEM Mem,
|
|
IN OUT PLOG_IO_DP_DRIVE Drive
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
Create(
|
|
IN PCLOG_IO_DP_DRIVE Drive,
|
|
IN OUT PHPFS_BITMAP BitMap,
|
|
IN PSUPERB SuperBlock,
|
|
IN LBN HotFixLbn,
|
|
IN SECTORCOUNT MaxHotFixes,
|
|
IN LBN CodePageSectorLbn,
|
|
IN ULONG NumCodePages,
|
|
IN LBN StartSparesLbn,
|
|
IN ULONG NumSpares
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
Verify(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsValid(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetSpareDirblksUsed(
|
|
IN BOOLEAN Flag DEFAULT TRUE
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetHotFixesUsed(
|
|
IN BOOLEAN Flag DEFAULT TRUE
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetBadSectorsPresent(
|
|
IN BOOLEAN Flag DEFAULT TRUE
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetBadBitMapBlock(
|
|
IN BOOLEAN Flag DEFAULT TRUE
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetFsVersionDifferent(
|
|
IN BOOLEAN Flag DEFAULT TRUE
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsSpareDirblksUsed(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsHotFixesUsed(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsBadSectorsPresent(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsBadBitMapBlock(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsFsDirty(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
SetFsDirty(
|
|
BOOLEAN Dirty
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
IsFsVersionDifferent(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
QueryHotFixCount(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
QueryMaxHotFixes(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
LBN
|
|
QueryHotFixLbn(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
LBN
|
|
QueryCpInfoLbn(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
QueryCodePageCount(
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
LBN
|
|
QuerySpareDirblkLbn(
|
|
IN ULONG Index
|
|
) CONST;
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
SetHotFixCount(
|
|
IN ULONG HotFixCount
|
|
);
|
|
|
|
NONVIRTUAL
|
|
ULONG
|
|
SetMaxHotFixes(
|
|
IN ULONG MaxHotFixes
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
ComputeAndSetChecksums(
|
|
IN PSUPERB SuperBlock
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
SetFlags(
|
|
IN BOOLEAN IsClean
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
Print(
|
|
IN BOOLEAN TotalDump DEFAULT TRUE
|
|
) CONST;
|
|
|
|
private:
|
|
|
|
VOID
|
|
Construct (
|
|
);
|
|
|
|
NONVIRTUAL
|
|
VOID
|
|
Destroy(
|
|
);
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SetFlag(
|
|
IN BOOLEAN Flag,
|
|
IN SPI Bit
|
|
);
|
|
|
|
STATIC
|
|
ULONG
|
|
ccs(
|
|
IN PVOID Buffer,
|
|
IN ULONG Size
|
|
);
|
|
|
|
_SPAREB* _pspd;
|
|
|
|
};
|
|
|
|
INLINE
|
|
ULONG
|
|
SPAREB::SetHotFixCount(
|
|
IN ULONG HotFixCount
|
|
)
|
|
{
|
|
return (_pspd) ? (_pspd->culHotFixes = HotFixCount) : !HotFixCount;
|
|
}
|
|
|
|
INLINE
|
|
ULONG
|
|
SPAREB::SetMaxHotFixes(
|
|
IN ULONG MaxHotFixes
|
|
)
|
|
{
|
|
return (_pspd) ? (_pspd->culMaxHotFixes = MaxHotFixes) : !MaxHotFixes;
|
|
}
|
|
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: SetSpareDirblksUsed
|
|
|
|
SYNOPSIS: Set spare block to reflect HPFS's usage of spare dir blocks
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: Spare dirblks are only used when the normal pool of dir blocks
|
|
is exhausted.
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::SetSpareDirblksUsed (
|
|
IN BOOLEAN Flag
|
|
) {
|
|
return SetFlag(Flag, SPI_SPARE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: SetHotFixesUsed
|
|
|
|
SYNOPSIS: Set spare block to reflect HPFS's usage of Hot Fixes
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: Hot fixes occur when a sector goes bad after a format. Chkdsk
|
|
will clear hot fixes. A hot fix maps a bad sector to a good sector.
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::SetHotFixesUsed (
|
|
IN BOOLEAN Flag
|
|
) {
|
|
return SetFlag(Flag, SPI_HFUSED);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: SetBadSectorsPresent
|
|
|
|
SYNOPSIS: Set spare block to reflect existance of bad sectors
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: If a volume has bad sectors this bit is set
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::SetBadSectorsPresent (
|
|
IN BOOLEAN Flag
|
|
) {
|
|
return SetFlag(Flag, SPI_BADSEC);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: SetBadBitMapBlock
|
|
|
|
SYNOPSIS: Set spare block to reflect existance of a bad bit map block
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::SetBadBitMapBlock (
|
|
IN BOOLEAN Flag
|
|
) {
|
|
return SetFlag(Flag, SPI_BADBM);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: SetFSVersionDifferent
|
|
|
|
SYNOPSIS: Set when the HPFS version differs from current OS version
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::SetFsVersionDifferent (
|
|
IN BOOLEAN Flag
|
|
) {
|
|
return SetFlag(Flag, SPI_FSVER);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsFSDirty
|
|
|
|
SYNOPSIS: FS dirty is set after improper shutdown of the file system
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsFsDirty (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_DIRTY) : FALSE;
|
|
}
|
|
|
|
INLINE
|
|
VOID
|
|
SPAREB::SetFsDirty(
|
|
BOOLEAN Dirty
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method sets the volume dirty bit.
|
|
|
|
Arguments:
|
|
|
|
Dirty -- supplies a flag which indicates, if TRUE, that the dirty
|
|
bit is to be set; if this flag is FALSE, the dirty bit is
|
|
to be reset.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
DebugPtrAssert( _pspd);
|
|
|
|
if( Dirty ) {
|
|
|
|
_pspd->bFlag |= SPI_DIRTY;
|
|
|
|
} else {
|
|
|
|
_pspd->bFlag &= ~SPI_DIRTY;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsSpareDirblksUsed
|
|
|
|
SYNOPSIS: Check spare block to reflect HPFS's usage of spare dir blocks
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: Spare dirblks are only used when the normal pool of dir blocks
|
|
is exhausted.
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsSpareDirblksUsed (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_SPARE) : FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsHotFixesUsed
|
|
|
|
SYNOPSIS: Check HPFS's usage of Hot Fixes
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: Hot fixes occur when a sector goes bad after a format. Chkdsk
|
|
will clear hot fixes. A hot fix maps a bad sector to a good sector.
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsHotFixesUsed (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_HFUSED) : FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsBadSectorsPresent
|
|
|
|
SYNOPSIS: Is spare block to reflect existance of bad sectors
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: If a volume has bad sectors this bit is set
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsBadSectorsPresent (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_BADSEC) : FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsBadBitMapBlock
|
|
|
|
SYNOPSIS: Check spare block to reflect existance of a bad bit map block
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsBadBitMapBlock (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_BADBM) : FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: IsFSVersionDifferent
|
|
|
|
SYNOPSIS: Check if the HPFS version differs from current OS version
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
BOOLEAN
|
|
SPAREB::IsFsVersionDifferent (
|
|
) CONST {
|
|
return (_pspd) ? (_pspd->bFlag & SPI_FSVER) : FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: QueryHotFixes
|
|
|
|
SYNOPSIS: Query the number of hot fixes present in an HPFS instance
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
ULONG
|
|
SPAREB::QueryHotFixCount(
|
|
) CONST {
|
|
return (_pspd) ? _pspd->culHotFixes : 0;
|
|
};
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: QueryMaxHotFixes
|
|
|
|
SYNOPSIS: Query maximum number of hot fixes that can occur
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
ULONG
|
|
SPAREB::QueryMaxHotFixes(
|
|
) CONST {
|
|
return (_pspd) ? _pspd->culMaxHotFixes : 0;
|
|
};
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: QueryLBNHotFixes
|
|
|
|
SYNOPSIS: Query the LBN which starts the hot fix list
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: Hotfixes are contained in a consecutive set of sectors
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
LBN
|
|
SPAREB::QueryHotFixLbn(
|
|
) CONST {
|
|
return (_pspd) ? _pspd->lbnHotFix : 0;
|
|
};
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: QueryLBNCPInfo
|
|
|
|
SYNOPSIS: Query the LBN of Code page information
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES: CP information starts at this location and then the CP data
|
|
structures (or objects) map to the remaining CP data structures
|
|
in an on disk LBN linked list.
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
LBN
|
|
SPAREB::QueryCpInfoLbn (
|
|
) CONST {
|
|
return (_pspd) ? _pspd->lbnCPInfo : 0;
|
|
};
|
|
|
|
|
|
/***************************************************************************\
|
|
|
|
MEMBER: QueryUsedCPs
|
|
|
|
SYNOPSIS: Query the number of code pages in use
|
|
|
|
ARGUMENTS:
|
|
|
|
NOTES:
|
|
|
|
ALGORITHM:
|
|
|
|
HISTORY: 26-July-90 marks
|
|
code
|
|
\***************************************************************************/
|
|
|
|
INLINE
|
|
ULONG
|
|
SPAREB::QueryCodePageCount(
|
|
) CONST {
|
|
return (_pspd) ? _pspd->culCP : 0;
|
|
};
|
|
|
|
|
|
#endif
|