176 lines
7.2 KiB
PHP
176 lines
7.2 KiB
PHP
|
BREAK <MFT Definitions>
|
|||
|
|
|||
|
;** MSDOS MFT definitions
|
|||
|
;
|
|||
|
; The Master File Table (MFT) associates the cannonicalized pathnames, lock
|
|||
|
; records and SFTs for all files open on this machine.
|
|||
|
;
|
|||
|
; The MFT implementation employs a single memory buffer which is used from
|
|||
|
; both ends. This gives the effect (at least until they run into each
|
|||
|
; other) of two independent buffers.
|
|||
|
;
|
|||
|
; MFT buffer
|
|||
|
; ==========
|
|||
|
; The MFT buffer contains MFT name records and free space. It uses a
|
|||
|
; classic heap architecture: freed name records are marked free and
|
|||
|
; conglomerated with any adjacent free space. When one is to create a name
|
|||
|
; entry the free list is searched first-fit. The list of name and free
|
|||
|
; records is always terminated by a single END record.
|
|||
|
;
|
|||
|
; LOCK buffer
|
|||
|
; ===========
|
|||
|
; The lock buffer contains fixed format records containing record locking
|
|||
|
; information. Since they are fixed format the space is handled as a series
|
|||
|
; of chains: one for each MFT name record and one for the free list. No
|
|||
|
; garbage collection is necessary.
|
|||
|
;
|
|||
|
; Space allocation
|
|||
|
; ================
|
|||
|
; The MFT is managed as a heap. Empty blocks are allocated on a first-fit
|
|||
|
; basis. If there is no single large enough empty block the list is garbage
|
|||
|
; collected.
|
|||
|
;
|
|||
|
; MFT name records:
|
|||
|
;
|
|||
|
; 8 16 8 16 32 16 n
|
|||
|
; |------|-----|-----|------|------|------|---------~~~~~~---------|
|
|||
|
; | FLAG | LEN | SUM | LPTR | SPTR | SERL | <.asciz string> |
|
|||
|
; --------------------------------------------------~~~~~~----------
|
|||
|
;
|
|||
|
; FLAG = record type flag
|
|||
|
; LEN = total byte length of record.
|
|||
|
; SUM = sum of bytes in asciz string. Used to speed
|
|||
|
; searches
|
|||
|
; LPTR= pointer to first record in lock chain segment
|
|||
|
; is MFT segment
|
|||
|
; SPTR= pointer to first sft in sft chain
|
|||
|
; SERL= serial number
|
|||
|
; <string> = name string, zero-byte terminated. There
|
|||
|
; may be garbage bytes following the 00 byte;
|
|||
|
; these are counted in the LEN field.
|
|||
|
;
|
|||
|
;
|
|||
|
; MFT free records
|
|||
|
;
|
|||
|
; 8 16
|
|||
|
; |------|-----|----~~~~~~~~~~~~~~~~~~~~~~~~~~~---------|
|
|||
|
; | FLAG | LEN | free |
|
|||
|
; ------------------~~~~~~~~~~~~~~~~~~~~~~~~~~~----------
|
|||
|
;
|
|||
|
; FLAG = record type flag
|
|||
|
; LEN = total byte length of record.
|
|||
|
;
|
|||
|
;
|
|||
|
; MFT END records
|
|||
|
;
|
|||
|
; 8
|
|||
|
; |------|
|
|||
|
; | FLAG |
|
|||
|
; --------
|
|||
|
;
|
|||
|
; FLAG = record type flag
|
|||
|
|
|||
|
;** MFT definitions
|
|||
|
;*
|
|||
|
;* NOTE: the flag and length fields are identical for all record types
|
|||
|
;* (except the END type has no length) This must remain so as
|
|||
|
;* some code depends upon it.
|
|||
|
;*
|
|||
|
;* NOTE: Many routines check for "n-1" of the N flag values and if no
|
|||
|
;* match is found assume the flag value must be the remaining
|
|||
|
;* possibility. If you add or remove flag values you must check
|
|||
|
;* all references to mft_flag.
|
|||
|
|
|||
|
MFT_entry STRUC
|
|||
|
|
|||
|
mft_flag DB ? ; flag/len field
|
|||
|
mft_len DW ?
|
|||
|
mft_sum DB ? ; string sum word
|
|||
|
mft_lptr DW ? ; LCK pointer
|
|||
|
mft_sptr DD ? ; sft pointer
|
|||
|
mft_serl DW ? ; serial number
|
|||
|
mft_name DB ? ; offset to start of name
|
|||
|
|
|||
|
MFT_entry ENDS
|
|||
|
|
|||
|
MFLG_NAM EQU 1 ; min value for name record
|
|||
|
MFLG_FRE EQU 0 ; free record
|
|||
|
MFLG_END EQU -1 ; end record
|
|||
|
|
|||
|
;* Record Lock Record (RLR):
|
|||
|
;
|
|||
|
; 16 32 32 32
|
|||
|
; |-------|--------|--------|--------|
|
|||
|
; | NEXT | FBA | LBA | SPTR |
|
|||
|
; | | lo hi | lo hi | |
|
|||
|
; ------------|--------|--------------
|
|||
|
;
|
|||
|
; CHAIN = pointer to next RLR. 0 if end
|
|||
|
; FBA = offset of 1st byte of locked region
|
|||
|
; LBA = offset of last byte of locked region
|
|||
|
; SPTR = pointer to SFT lock was issued on
|
|||
|
|
|||
|
RLR_entry STRUC
|
|||
|
|
|||
|
rlr_next DW ? ; chain to next RLR, 0 if end
|
|||
|
rlr_fba DW ? ; first byte addr (offset) of reigion
|
|||
|
DW ?
|
|||
|
rlr_lba DW ? ; last byte addr of region
|
|||
|
DW ?
|
|||
|
rlr_sptr DD ? ; SFT pointer
|
|||
|
rlr_pid dw ? ; process id of issuer
|
|||
|
rlr_type dw ? ; lock type
|
|||
|
RLR_entry ENDS
|
|||
|
|
|||
|
rlr_lall equ 00h ; lock all ops
|
|||
|
rlr_lwr equ 01h ; lock write ops
|
|||
|
|
|||
|
;
|
|||
|
; A pictorial diagram for the linkages is as follows:
|
|||
|
;
|
|||
|
; +---sptr------+
|
|||
|
; V |
|
|||
|
; +---+<----------|---sptr------+------------+
|
|||
|
; |SFT+----+ | | |
|
|||
|
; +-+-+ | +-+-+ +--+-+ +--+-+
|
|||
|
; V +--->|MFT+-lptr->-|LOCK+-next->|LOCK+->0
|
|||
|
; +---+ | +---+ +----+ +----+
|
|||
|
; |SFT+----+ ^
|
|||
|
; +-+-+ |
|
|||
|
; | |
|
|||
|
; +-------------+
|
|||
|
;
|
|||
|
;
|
|||
|
|
|||
|
;**
|
|||
|
;
|
|||
|
; Interesting behavior should be noted:
|
|||
|
;
|
|||
|
; The sharer must maintain information on files in three forms:
|
|||
|
;
|
|||
|
; local/remote handles. These are normal handles and behave in no
|
|||
|
; strange manner. They are identified by SF_mode not having the
|
|||
|
; sfIsFCB flag nor by having the sf_mode = 70. No problems with
|
|||
|
; locking. No problems with open. No problems with close.
|
|||
|
; CloseByName will iterate closes until the mft disappears.
|
|||
|
; CloseUser will iterate closes until no SFT for the particular user
|
|||
|
; appears. CloseProcess will iterate closes until no SFT for the
|
|||
|
; particular user/process appears.
|
|||
|
;
|
|||
|
; local FCBs. There are no corresponding SFT's for these as the SFTs
|
|||
|
; are cached but will be valid for the particular file. There is
|
|||
|
; one SFT for each open on a file by a specific process. These are
|
|||
|
; identified the sfIsFCB flag in the sf_mode field. When multiple
|
|||
|
; opens occur, we merely find the sf pertinent to the file and
|
|||
|
; process. Close decrements the ref count. CloseByName, CloseUser,
|
|||
|
; CloseProcess will iterate closes until no more SFTs exist.
|
|||
|
;
|
|||
|
; handles with mode 70. These represent FCB's open across the network.
|
|||
|
; As such, identical sfts may have been collapsed by the $open code.
|
|||
|
; This results in a reuse of the same SFT. The $Open code must
|
|||
|
; correctly set the ref-count for the sft to reflect the number of
|
|||
|
; collapses that have occurred. These are identified by a 70 in the
|
|||
|
; SF_mode field. There can be no locking on these SFTs. Open must
|
|||
|
; scan the list of SFTs for the file and increment its ref count
|
|||
|
; appropriately.
|
|||
|
|