NT4/private/ntos/boot/bootcode/hpfs/i386/dir.inc

286 lines
12 KiB
PHP
Raw Normal View History

2001-01-01 00:00:00 +01:00
;** DIR.H - Dirblk and Dirent definitions
;
; FILESYS
; Gregory A. Jones
; Copyright 1988 Microsoft Corporation
;
; Modification history:
; P.A. Williams 06/01/89 Replaced field DIR_USECNT with fields
; DIR_FLEX and DIR_CPAGE. Added DF_NEEDEAS
; define.
; P.A. Williams 07/10/89 Add define DF_NEWNAME for "new" hpfs file
; names.
; P.A. Williams 07/14/89 Added typedefs for DIRENT and DIRBLK.
; P.A. Williams 07/21/89 Converted DIRSIZP form ASM defn to C defn.
;
ifdef MASM
include dirent.inc
else
attr_directory equ 10h
endif
; Directory Entry Fields
;
; Directory entries are always left as a multiple of 4
; to speed up moves. The DIR_NAMA field is variable length,
; the DIR_BTP field, if present, is the last dword in the record.
; ACL information may be stored after the DIR_NAMA field but before
; the DIR_BTP field so the DIR_BTP field must be located by going
; backwards from the end of the record
;
; WARNING - Mkdir block copies some of these entries and
; makes assumptions about which fields get copied. Check
; mkdir if stuff is added.
;
DIRENT struc
DIR_ELEN dw ? ; length of this entry (including free space)
DIR_FLAG dw ? ; flags - low byte defined below
; high byte holds the old attr_ FAT values
DIR_FN dd ? ; FNODE Sector
DIR_MTIM dd ? ; last modification time
DIR_SIZE dd ? ; file size
DIR_ATIM dd ? ; last access time
DIR_CTIM dd ? ; fnode creation time
DIR_EALEN dd ? ; bytes of extended attributes
DIR_FLEX db ? ; description of "flex" area,
; following file name:
; bits 0-2: # of ACEs in DE
; bits 3-7: reserved
DIR_CPAGE db ? ; code page index on volume
; the following fields have information specific to the name and directory
; position of the file. This info is not propigated for a move/rename
; That code uses DIR_NAML as a seperator - check MOVE if changes are
; made to this structure
DIR_NAML db ? ; length of file name
DIR_NAMA db ? ; name goes here
; ACL information may be stored here
; long DIR_BTP; btree pointer to descendent DIRBLK record.
; This is only present if DF_BTP is set.
; This field is referenced from the end of
; the record, not DIR_NAMA+DIR_NAML
DIRENT ends
ifdef MASM
DIR_BTP equ dword ptr -4 ; referenced from the end of the record
endif
SIZE_DIR_BTP equ 4
MAX_DIRACL equ 3 ; max of 3 ACLs in dirent
DIRSIZL equ offset DIR_NAMA ; base size of leaf dir entry (minus name)
DIRSIZP equ (size DIRENT+4) ; base size of dir entry with btree ptr w/o name
MAX_DIRENT equ (DIRSIZP+255+MAX_DIRACL*(size (long))+10) ; max size of a DIRENT
; (plus some slop)
; Directory Block Definition
;
; The change count field is incremented every time we move any
; of the entries in this block. For efficiency reasons, folks
; remember the Sector # and offset of a directory entry, and the
; value of the DB_CCNT field when that info was recorded.
; If the DB_CCNT field is different then the remembered value,
; then the entry offset is invalid and the entry should be
; refound from the top. Note that when a directory block splits,
; the old DIRBLK gets the old DB_CCNT field. Since
; the new DIRBLK is previously unknown, it can have
; any DB_CCNT value. We start with zero so that DB_CCNT
; gives us a feel for the change rate in the directory.
;
DIRBLK struc
DB_SIG dd ? ; signature value
DB_FREP dd ? ; offset of first free byte
DB_CCNT dd ? ; change count (low order bit is flag)
; =1 if this block is topmost
; =0 otherwise
DB_PAR dd ? ; parent directory PSector # if not topmost
; FNODE sector if topmost
DB_SEC dd ? ; PSector # of this directory block
DB_START db ? ; first dirent record goes here
DB_DUMY db 2027 dup (?) ; round out to 2048 bytes
DIRBLK ends
; BUGBUG - we should init DB_CCNT with a random value
; to prevent a fakeout by deleting one directory
; and then creating another (find sequences will
; remember sector numbers and signatures...)
; Maximum entries per directory.
MAXDIRE equ (size DIRBLK- DB_START)/(size DIRENT)
;* DIR_FLAG values
;
DF_SPEC equ 0001h ; special .. entry
DF_ACL equ 0002h ; item has ACL
DF_BTP equ 0004h ; entry has a btree down pointer
DF_END equ 0008h ; is dumy end record
DF_XACL equ 0040h ; item has explicit ACL
DF_NEEDEAS equ 0080h ; item has "need" EAs
DF_NEWNAME equ 4000h ; item name is of "new" pinball format
DF_RMASK equ DF_ACL+DF_XACL ; only attributes preserved for rename
ifdef MASM
.errnz DF_BTP - SIZE_DIR_BTP ; code uses this "coincidence"
endif
; Attributes which creation can specify
DF_CMASK equ attr_read_only+attr_hidden+attr_archive
; Directory Lookaside Structure
;
; We keep info on all directories that we've seen in SBDIR records
; in RAM, but we keep the last N that we've seen in a special
; DIRLOOK list in RAM.
;
DIRLOOK struc
DL_LNK db (size DCHDR) dup (?) ; forward and backwards link
DL_VSECVAL dd ? ; VOL_SECVAL value
DL_SUM dd ? ; checksum value
DL_NAM dd ? ; pointer to name string on heap
DL_SBD dd ? ; pointer to SBDIR structure
DIRLOOK ends
; Subdirectory Linkage Structure
;
; For every directory that we've seen on the disk we keep a
; SBDIR record in ram, linked into a heirarchy which parallels
; the disk heirarchy. We never discard these, so we end up
; with a RAM copy of all the parts of the directory heirarchy
; that the user is using.
;
; Each SBDIR entry is on a circular doubly linked chain of
; siblings (directors with the same parent directory). If a
; directory contains no subdirectories the SD_ENT field is 0.
; If a directory has subdirectories, their SBDIR entries are
; in turn in a SD_SIB chain and the SD_ENT field points to
; one of those SBDIR entries.
;
; SBDIR contains a lock and a hold mechanism. A directory is
; locked when it is being edited; no other threads may view it
; until it is unlocked. A directory which is HELD is one which
; is being accessed and can't be edited.
;
; The locking and holding algorithms are complicated by the fact
; that we almost never block so we want to do our typical locking
; and unlocking inline, without calls, and with minimum tests.
; We do this with a held count, and bits for locked, lock pending,
; and solo pending. (Solo means that a user wants sole access to
; the structure. He'll continue to block until no one else is
; using it. This is typically done to delete the structure)
; Another bit is the OR of the lock pending and solo pending bits,
; and is high order in the dword which encompases SD_HCNT so that
; when folks release their SD_HCNT value they can simulatneously
; test to see if there is a pending action.
;
; To Hold the SBDIR:
; If it's not locked and doesn't have a lock pending,
; increment hold count
; else
; block on it and retry.
;
; To Unhold the SBDIR:
; decrement the HCNT field.
; If SD_PND & (HCNT == 0)
; wake up waiters.
;
; To lock the SBDIR:
; If locked, block and retry.
; If HCNT != 0
; if (lock pending already set)
; block and retry
; set lock pending. Block until HCNT is zero.
; set locked
;
; To unlock the SBDIR:
; clear lock bit.
; If the block list is non-zero, issue a wakeup.
;
; To Solo the SBDIR:
; Keep blocking until no one else is blocked on it and
; no one has it held or locked.
;
; General Considerations:
; Anyone who blocks on an SBDIR because it's held must
; be sure to set a pending bit and the SD_PND bit so
; that the unhold operation will wake them up.
;
; Anyone who blocks on an SBDIR must increment the
; SD_BCNT field to prevent a SOLO operation from yanking
; the rug out from under them. SOLO can't depend upon
; checking the lock list because a blanket wakeup may
; have cleared the lock list. If the SOLO guy gets control
; first he'll believe that he can have it.
;
;
SBDIR struc
SD_FNW db (size DCHDR) dup (?) ; FNWORK (findnotify) chain
SD_SIB db (size DCHDR) dup (?) ; chain of siblings
SD_LRU db (size DCHDR) dup (?) ; LRU chain
SD_ENT dd ? ; pointer to a descendent, or 0
SD_PAR dd ? ; pointer to parent SBDIR, 0 if root
SD_SEC db (size SECPTR) dup (?) ; VSector and hint of top dirblk
SD_FNO dd ? ; FNODE # of directory
SD_SUM dd ? ; checksum of name string
SD_CNT dw ? ; # of subdirectories in this one
SD_OPEN dw ? ; count of # of guys that have this open
; We sometimes inc/dec SD_HCNT as a dword to test the HO bit in SD_FLAG
; the following three fields are used to
; control access. They're identical in use
; to the equivalent fields in OFT
SD_HCNT dw ? ; held count, has SDH_PND bit also
SD_DMYZERO db ? ; must be zero
SD_FLAG db ? ; flag byte, high order in SD_HCNT dword
SD_WAIT dd ? ; head of the wait chain
SD_FREEDCNT dd ? ; incremented each time we free a DIRBLK
; for this guy. See RDE for details
SD_WCNT dw ? ; count of folks blocked on this
SD_FNDCNT dw ? ; count of active finds in this directory
SD_ATIME dd ? ; time of last access
SD_NAM dd ? ; address of name string
SD_ACL dd ? ; SBDIR ACL pointer, 0 if none
; points to DWORD count, followed by ACEs
; if low bit of address is 0, is heap space
; if low bit is 1, is system memory
SBDIR ends
SD_ACL_LIM equ 1024 ; *SD_ACL lists bigger than this come from
; system memory, smaller come from heap
SDF_PND equ 80h ; lock pending bit
SDF_RTP equ 20h ; restricted traversal permissions
; =0 if anyone can traverse the dir
SDF_REALLYBAD equ 10h ; directory is really bad
SDF_IPR equ 08h ; SD_ACL has inherit records
SDF_PSO equ 04h ; pending solo
SDF_PLK equ 02h ; pending lock
SDF_LCK equ 01h ; directory is locked against access