NT4/private/ntos/boot/bootcode/hpfs/i386/dir.inc
2020-09-30 17:12:29 +02:00

286 lines
12 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;** 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