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.
474 lines
6.8 KiB
474 lines
6.8 KiB
/*++
|
|
|
|
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
|