475 lines
6.8 KiB
C++
475 lines
6.8 KiB
C++
/*++
|
||
|
||
Copyright (c) 1990 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
dirblk.hxx
|
||
|
||
Abstract:
|
||
|
||
This module contains declarations for the DIRBLK object,
|
||
which models a directory block in an HPFS directory B-Tree.
|
||
|
||
Author:
|
||
|
||
Norbert Kusters (norbertk) 27-Aug-1990
|
||
Bill McJohn (billmc) 01-Dec-1990
|
||
|
||
Environment:
|
||
|
||
ULIB, User Mode
|
||
|
||
|
||
--*/
|
||
|
||
#if ! defined(DIRBLK_DEFN)
|
||
|
||
#define DIRBLK_DEFN
|
||
|
||
#include "hfsecrun.hxx"
|
||
#include "hmem.hxx"
|
||
#include "defer.hxx"
|
||
#include "verify.hxx"
|
||
|
||
//
|
||
// Forward references
|
||
//
|
||
|
||
DECLARE_CLASS( CASEMAP );
|
||
DECLARE_CLASS( DEFERRED_ACTIONS_LIST );
|
||
DECLARE_CLASS( DIRBLK );
|
||
DECLARE_CLASS( HOTFIXLIST );
|
||
DECLARE_CLASS( HPFS_BITMAP );
|
||
DECLARE_CLASS( HPFS_CENSUS );
|
||
DECLARE_CLASS( HPFS_MAIN_BITMAP );
|
||
DECLARE_CLASS( HPFS_NAME );
|
||
DECLARE_CLASS( HPFS_ORPHANS );
|
||
DECLARE_CLASS( HPFS_PATH );
|
||
DECLARE_CLASS( HPFS_SA );
|
||
DECLARE_CLASS( LOG_IO_DP_DRIVE );
|
||
DECLARE_CLASS( MESSAGE );
|
||
|
||
#define DIRBLK_SIZE 2048
|
||
#define DOWNPOINTER_SIZE 4
|
||
#define DIRBLK_HEADER_SIZE 20
|
||
|
||
|
||
|
||
DEFINE_TYPE( ULONG, UHPFS_TIME );
|
||
|
||
struct _DIRBLKD {
|
||
|
||
ULONG sig;
|
||
ULONG offulFirstFree;
|
||
ULONG culChange;
|
||
LBN lbnParent;
|
||
LBN lbnThisDir;
|
||
BYTE bFirst;
|
||
|
||
BYTE abDummy[DIRBLK_SIZE - (DIRBLK_HEADER_SIZE + 1)];
|
||
|
||
};
|
||
|
||
struct _DIRENTD {
|
||
|
||
USHORT cchThisEntry;
|
||
BYTE fFlags;
|
||
BYTE fAttr;
|
||
LBN lbnFnode;
|
||
UHPFS_TIME timLastMod;
|
||
ULONG cchFSize;
|
||
UHPFS_TIME timLastAccess;
|
||
UHPFS_TIME timCreate;
|
||
ULONG ulEALen;
|
||
BYTE fFlex;
|
||
BYTE bCodePage;
|
||
BYTE cchName;
|
||
BYTE bName[1];
|
||
|
||
// LBN BTree;
|
||
};
|
||
|
||
DEFINE_TYPE( struct _DIRBLKD, DIRBLKD );
|
||
DEFINE_TYPE( struct _DIRENTD, DIRENTD );
|
||
|
||
|
||
|
||
#define BTP( pde ) \
|
||
(*( (ULONG *)( (PBYTE)(pde) + \
|
||
(pde)->cchThisEntry - DOWNPOINTER_SIZE)))
|
||
|
||
#define NEXT_ENTRY( pde ) \
|
||
( (PDIRENTD)((PBYTE)(pde) + (pde)->cchThisEntry) )
|
||
|
||
#define FIRST_ENTRY( pdb ) \
|
||
( (PDIRENTD)(&((pdb)->bFirst)) )
|
||
|
||
CONST LeafEndEntrySize = sizeof( DIRENTD );
|
||
CONST MinimumDirentSize = sizeof( DIRENTD );
|
||
CONST MaximumDirentSize = sizeof( DIRENTD ) +
|
||
255 + // Maximum name
|
||
DOWNPOINTER_SIZE + // B-Tree pointer
|
||
12; // ACLs.
|
||
|
||
CONST MergeThreshhold = 2 * MaximumDirentSize + 2 * LeafEndEntrySize + 10;
|
||
|
||
enum {
|
||
DF_SPEC = 0x0001, /* special .. entry */
|
||
DF_ACL = 0x0002, /* item has ACL */
|
||
DF_BTP = 0x0004, /* entry has a btree down pointer */
|
||
DF_END = 0x0008, /* is dummy end record */
|
||
DF_ATTR = 0x0010, /* has an extended attribute list */
|
||
DF_PERM = 0x0020, /* has an extended permission list */
|
||
DF_XACL = 0x0040, /* item has explicit ACL */
|
||
DF_NEEDEAS = 0x0080 /* item has "need" EAs */
|
||
};
|
||
|
||
|
||
#define ATTR_READ_ONLY (0x01)
|
||
#define ATTR_HIDDEN (0x02)
|
||
#define ATTR_SYSTEM (0x04)
|
||
#define ATTR_DIRECTORY (0x10)
|
||
#define ATTR_ARCHIVE (0x20)
|
||
#define ATTR_NEWNAME (0x40)
|
||
|
||
class DIRBLK : public HOTFIX_SECRUN {
|
||
|
||
public:
|
||
|
||
UHPFS_EXPORT
|
||
DECLARE_CONSTRUCTOR( DIRBLK );
|
||
|
||
UHPFS_EXPORT
|
||
VIRTUAL
|
||
~DIRBLK (
|
||
);
|
||
|
||
UHPFS_EXPORT
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
Initialize(
|
||
IN PLOG_IO_DP_DRIVE Drive,
|
||
IN PHOTFIXLIST HotfixList,
|
||
IN LBN lbn
|
||
);
|
||
|
||
BOOLEAN
|
||
CreateRoot (
|
||
IN LBN FnodeLbn
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VERIFY_RETURN_CODE
|
||
VerifyAndFix(
|
||
IN PHPFS_SA SuperArea,
|
||
IN PDEFERRED_ACTIONS_LIST DeferredActions,
|
||
IN PHPFS_PATH CurrentPath,
|
||
IN OUT PHPFS_NAME PreviousName,
|
||
IN LBN ExpectedParentLbn,
|
||
IN LBN ParentFnodeLbn,
|
||
IN ULONG CurrentDepth,
|
||
IN OUT PULONG LeafDepth,
|
||
IN PMESSAGE Message,
|
||
OUT PBOOLEAN ErrorsDetected,
|
||
IN BOOLEAN UpdateAllowed = FALSE,
|
||
IN BOOLEAN Verbose = FALSE,
|
||
IN PHPFS_ORPHANS OrphansList = NULL
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
IsDirblk(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
Truncate(
|
||
IN PDIRENTD pde
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
VerifyAndFixEndEntry(
|
||
IN PDIRENTD pde,
|
||
IN OUT PBOOLEAN ErrorsDetected
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
MarkModified(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
MarkUnmodified(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
IsModified(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
FindName(
|
||
IN PHPFS_NAME Name,
|
||
OUT PDIRENTD* DirentFound,
|
||
IN PCASEMAP Casemap
|
||
);
|
||
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
FindAndResolveHotfix(
|
||
IN PHPFS_SA SuperArea,
|
||
IN DEFERRED_SECTOR_TYPE ChildSectorType
|
||
);
|
||
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
SetParents(
|
||
LBN ParentLbn,
|
||
LBN ParentFnodeLbn
|
||
);
|
||
|
||
NONVIRTUAL
|
||
ULONG
|
||
QueryEntryOffset(
|
||
IN PDIRENTD Entry
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
FixupChildren(
|
||
PHOTFIXLIST HotfixList = NULL
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
TakeCensusAndClear(
|
||
IN OUT PHPFS_BITMAP VolumeBitmap,
|
||
IN OUT PHPFS_MAIN_BITMAP HpfsOnlyBitmap,
|
||
IN OUT PHPFS_CENSUS Census
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PDIRENTD
|
||
GetFirstEntry(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
IsEmptyDirectory(
|
||
);
|
||
|
||
friend class HPFS_DIRECTORY_TREE;
|
||
|
||
private:
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
Construct (
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
InsertDirent(
|
||
IN PDIRENTD NewDirent,
|
||
OUT PBOOLEAN ErrorOccurred,
|
||
IN PCASEMAP Casemap,
|
||
IN PUCHAR InsertPoint = NULL,
|
||
IN ULONG NewDownPointer = 0
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PDIRENTD
|
||
FindSplitPoint(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PDIRENTD
|
||
EndEntry(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
PDIRENTD
|
||
LastNonEndEntry(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
BOOLEAN
|
||
IsEmpty(
|
||
);
|
||
|
||
NONVIRTUAL
|
||
VOID
|
||
Destroy(
|
||
);
|
||
|
||
PDIRBLKD _pdb;
|
||
|
||
HMEM _mem;
|
||
|
||
PLOG_IO_DP_DRIVE _Drive;
|
||
|
||
BOOLEAN _IsModified;
|
||
|
||
};
|
||
|
||
|
||
INLINE
|
||
BOOLEAN
|
||
DIRBLK::IsDirblk(
|
||
)
|
||
/*++
|
||
|
||
Routine description:
|
||
|
||
Checks the signature of the Dirblk to make sure that this is
|
||
indeed an Dirblk.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE if the signature is the Dirblk signature.
|
||
|
||
--*/
|
||
{
|
||
return( _pdb->sig == DirblkSignature );
|
||
}
|
||
|
||
|
||
|
||
INLINE
|
||
VOID
|
||
DIRBLK::MarkModified(
|
||
)
|
||
/*++
|
||
|
||
Routine description:
|
||
|
||
Mark the Dirblk as modified, so that when it comes time to flush
|
||
it we know we'd like to write it.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
_IsModified = TRUE;
|
||
}
|
||
|
||
|
||
|
||
INLINE
|
||
VOID
|
||
DIRBLK::MarkUnmodified(
|
||
)
|
||
/*++
|
||
|
||
Routine description:
|
||
|
||
Mark the Dirblk as unmodified, so that when it comes time to flush
|
||
it we know we don't need to write it.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
_IsModified = FALSE;
|
||
}
|
||
|
||
|
||
|
||
INLINE
|
||
BOOLEAN
|
||
DIRBLK::IsModified(
|
||
)
|
||
/*++
|
||
|
||
Routine description:
|
||
|
||
Query whether the Dirblk has been modified since our last I/O
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE if the Dirlblk has been modified.
|
||
|
||
--*/
|
||
{
|
||
return _IsModified;
|
||
}
|
||
|
||
|
||
|
||
INLINE
|
||
ULONG
|
||
DIRBLK::QueryEntryOffset(
|
||
IN PDIRENTD Entry
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Compute the offset into the dirblk of an entry
|
||
|
||
Arguments:
|
||
|
||
Entry -- Supplies the entry whose offset we want
|
||
|
||
Return Value:
|
||
|
||
Offset of entry into DIRBLK; zero if error.
|
||
|
||
--*/
|
||
{
|
||
ULONG Offset;
|
||
|
||
Offset = (PBYTE)Entry - (PBYTE)_pdb;
|
||
|
||
return (Offset >= DIRBLK_SIZE) ? 0 : Offset;
|
||
}
|
||
|
||
|
||
INLINE
|
||
PDIRENTD
|
||
DIRBLK::GetFirstEntry(
|
||
)
|
||
{
|
||
return FIRST_ENTRY( _pdb );
|
||
}
|
||
|
||
|
||
INLINE
|
||
BOOLEAN
|
||
DIRBLK::IsEmpty(
|
||
)
|
||
{
|
||
return( GetFirstEntry()->fFlags & DF_END );
|
||
}
|
||
|
||
|
||
|
||
|
||
#endif
|