diff options
Diffstat (limited to '')
18 files changed, 3889 insertions, 0 deletions
diff --git a/private/ntos/boot/bootcode/hpfs/i386/buf.inc b/private/ntos/boot/bootcode/hpfs/i386/buf.inc new file mode 100644 index 000000000..fe2eb8377 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/buf.inc @@ -0,0 +1,222 @@ +;static char *SCCSID = "@(#)buf.h 12.1 88/11/21"; +;** BUF.H - Buffer definitions +; +; HPFS Utilities +; Peter A. Williams +; Copyright 1988 Microsoft Corporation +; +; Modification history: +; P.A. Williams 08/01/89 Added typedef BUFNODE and PBUFNODE. +; + +;* Buffer Nodes +; +; When the comments talk about "buffer address" they're always +; talking about the buffer header address. If we're talking +; about the address of the data field of the buffer, we say +; "buffer data". +; +; These buffer headers are also used as I/O request blocks for +; the data in the buffer. The B_IOP field contains the +; function. Sometimes we need an I/O request block which +; isn't assocated with a buffer - for example, when we read +; directly into an application's memory area. For this, we keep +; a pool of I/O request blocks which are actually BUFNODE +; structures, but they aren't associated with a buffer and the +; B_ADDR field is used to hold the I/O target address. +; These BUFNODEs have BF_IORQ in the flags field to distinguish +; them from regular buffer headers. +; +; Note that we use the B_SUM field for debugging purposes. This is an +; array of SPB words, each of which holds the CAS (high and low +; 16 bits xored togehter) of one of the sectors. We can then check +; this value to make sure that we're setting the dirty bits +; correctly. +; +; NOTE - see the discussion on holding and locking at the end of +; this file +; + +BUFNODE struc + + B_LRU db (size DCHDR) dup (?) ; LRU chain, if not BF_IORQ + B_LRUH dd ? ; address of LRU chain head if not locked/held + ; if lcoked/held, we're on that chain but + ; this guy points to it's regular chain + B_SEC dd ? ; VSector # + B_ADDR dd ? ; address of data + B_DCHN db (size DCHDR) dup (?) ; doubly linked list of dirty buffers + B_dirt db ? ; 1 bit per dirty sector + ; used to optimize the write. Non dirty + ; marked sectors may still be rewritten + B_iop db ? ; disk driver I/O operation + B_type db ? ; type of info + B_FLAG db ? ; flags + B_HCNT dw ? ; hold count + B_LCNT db ? ; lock count (really a flag, only 0 or 1 + B_BADSEC db ? ; 1 bit per defective sector + B_next dd ? ; advisory address of next buffer content + ; always a buffer header addr, never 0 + B_DADR dd ? ; address of routine to call when I/O is done + + ; The following two fields are redefined + ; if BF_IORQ is set. + B_HASH db (size DCHDR) dup (?) ; sector hash chain + B_HTA dd ? ; address of entry in hash table + + B_WAIT dd ? ; head of wait chain +ifdef DEBUG + B_SUM dw 4 dup (?) ; holds checksum of buffer contents +else + B_XTRA db 8 dup (?) +endif + +; 64 byte boundary + + B_LDTIME dd ? ; time (in ms/512) when buffer was last dirtied + B_FDTIME dd ? ; time (in ms/512) when buffer got first dirtied + B_LWWAIT dd ? ; head of lazy write wait chain + B_XTRA2 db 64-16 dup (?) +BUFNODE ends + +;typedef struct BUFNODE BUFNODE; +;typedef struct BUFNODE *PBUFNODE; + +BUFHDRSHIFT equ 7 + +ifdef MASM + .errnz (size BUFNODE) - (1 SHL BUFHDRSHIFT) +endif + +; Following are alternative offsets if BF_IORQ is set + +B_XFER equ (DWORD PTR B_HTA) ; holds transfer sec cnt +B_NADR equ (DWORD PTR B_HASH) ; addr of client's NOTEREC +B_NMSK equ (DWORD PTR B_HASH+4) ; notification mask +ifdef MASM + .errnz (size DCHDR)-8 ; enough room for double map +endif + +; B_FLAG bits + +BFL_LWLOCK equ 00000001h ; buffer is being lazy written in a block + + +; B_type values + +BF_FREE equ 0 ; buffer is free (not in LRU list) +BF_LRU equ 1 ; buffer in LRU list + + +; Priority values for LRU placement + +BP_KEEP equ 0 ; Buffer contains future-usable data +BP_NOOPINION equ 1 ; Buffer contains marginally useful data +BP_TOSS equ 2 ; Buffer is unlikely to be used + +; NOTEREC - Notification Record +; +; Some callers may post several disk requests in parallel and +; want to keep track of when they're *all* complete. I/O +; request blocks (buffer headers w/o buffers) have fields to +; allow this. The caller stores the address of his NOTEREC, +; and when each request completes it clears it's associated bit. +; When all of the bits clear the block chain in the NOTEREC +; is woken. +; +; Note that there can be only one thread blocked on a NOTEREC +; because the first guy to wakeup will return the NOTEREC to the +; heap or whatever. This occurs naturally; unlike I/O to the +; buffer cache, NOTERECs are used for direct I/O. If someone +; else wants to do I/O to the same location and if record and file +; locking allows that, then they'll get their own NOTEREC or +; cache I/O request and have a horse race. NOTERECs are only used +; to do file data I/O, all "filesystem" structures are manipulated +; via the cache. +; +; The fields are DWORD, but only the low byte of the MSK and FLD +; records are used for normal completion. The 3rd byte of NTR_FLD +; (..FF....h) is used for error posting - these bits are +; set if an irrecoverable error occured in the I/O. +; + +NOTEREC struc + NTR_FLD dd ? ; the mask bit field + NTR_BLC dd ? ; head of the block chain + NTR_MSK dd ? ; next bit to set in NTR_FLD +NOTEREC ends + + +;* Holding and Locking +; +; LOCK means that the buffer contents are inconsistant/incorrect. No body +; is allowed to look at the contents of the buffer. This is done +; when we're reading in from the disk; we'll mark the buffer +; with the VSector # (so that any other folks that want that sector +; won't issue their own reads in parallel) but we mark it LOCKED +; so that nobody looks at it's contents which aren't correct yet. +; +; LOCKed is pretty rare because most folks which are mucking +; with a buffer have it back in a consistant state before they +; allow a context switch. +; +; An important exception to this is directory manipulation - +; directory splitting, etc. In this case, a flag has been set +; on the directory itself (in SBDIR) so that no one will try to +; look at the directory contents. The cache block which has the +; inconsistant DIRBLK might also have sectors belonging to someone +; else and those sectors can be accessed by other folks because +; the buffer isn't locked. (We don't lock the directory and not +; the block for this reason, it's a fallout. We lock the directory +; because it's too mucky for people to "back out" if they're +; searching down into a directory and find out that they've +; reached an area which is being rebuilt. The rebuilding might +; propigate up and change the unlocked higher DIRBLKs that this +; other guy has already accessed... So we lock the whole directory, +; and thus needn't bother locking the cache blocks themselves. +; +; HOLD means that the contents are valid, but the cache block must continue +; to hold that data. Folks use this when they need to access +; two different sectors at the same time. They HOLD one when +; they read the other so that there's no chance that by the +; time the 2nd read finishes the first one has been evicted. +; This is much cheaper than remembering the first one's VSector +; # and calling RDBUF N times as you transfer N words of info +; between the two sectors. +; +; By definition only one guy can lock a buffer (the lock count should +; go to a flag; it's already a flag on directorys) but the hold +; value is a count, since multiple people can hold. (Like the +; electrician's safety plate which allows multiple electricians +; to lock a breaker OPEN so that it can't be closed until ALL are +; done). (SBDIRs have a hold count for the same reason - folks +; may yield while in a directory and don't want it to change out +; from under them) +; +; We also use hold when we set dirty bits. The concern is that +; if we're going to write something to a buffer, yield the CPU, +; then write something else, we don't want to have to make two +; calls to SetDirt, one after each write. This costs time, and +; also it would be a waste if the lazywriter were to write this +; guy anyhow, since he's going to get dirty again ASAP and +; writing him out doesn't free the cache block anyway, since it's +; held. +; +; So my current algorithm is that I won't lazywrite anybody who +; is held, and therefore won't mark them clean. This means, +; in effect, that there is no ordering constraint on dirtying +; a buffer or marking it dirty so long as it is held the entire +; time. I think that the code now always marks it dirty before +; a yield, even if held, because the debug code is a bit hard +; assed about it, but this could be relaxed under the current +; lazywrite rules I've just described. +; +; Both in the case of directorys and cache blocks, the theory is that +; since these buffers are MRU, it's extremely rare that we'd actually try +; to reclaim their buffer slots, and in general it's rare that there's +; a conflict in their use. So in actual execution, these locks are +; very rarely encountered. They're cheap - INC to set and DEC to clear, +; so almost always all we're doing is INCing and DECing a location +; and it's just two wasted instructions. Once in a while, though, +; it's a big bacon save, as they say. +; diff --git a/private/ntos/boot/bootcode/hpfs/i386/chain.inc b/private/ntos/boot/bootcode/hpfs/i386/chain.inc new file mode 100644 index 000000000..b1528c2a1 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/chain.inc @@ -0,0 +1,7 @@ +;static char *SCCSID = "@(#)chain.h 12.1 88/11/21"; +;* Doubly Chained Definitions + +DCHDR struc + FWD dd ? ; forward pointer + BAK dd ? ; backward pointer +DCHDR ends diff --git a/private/ntos/boot/bootcode/hpfs/i386/const.inc b/private/ntos/boot/bootcode/hpfs/i386/const.inc new file mode 100644 index 000000000..5304fabfe --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/const.inc @@ -0,0 +1,201 @@ +;static char *SCCSID = "@(#)const.h 12.3 89/09/19"; +; #define DEBUG 1 + + +;* Constants for File System + +MAXPATH equ 256 ; maximum path length +GROWDELT equ 8 +MVPFXSIZE equ 2 ; Size of the multivolume pathname prefix + +; Sector sizes + +SECSIZE equ 512 ; 512 bytes per sector +SECSHIFT equ 9 ; 2^9 = SECSIZE +SECMSK equ 01ffh ; sector size mask + +ifdef MASM + .errnz SECSIZE-512 ; C code uses 512 as a magic number - grep them out +endif + +; Cache Sizes + +SPB equ 4 ; sectors per buffer +SPB4 equ 1 + +ifdef SPB4 +SPBMASK equ 3 ; mask for SPB +SPBSHIFT equ 2 +SPBBITS equ 0fh ; SPB number of one bits, low order +endif + +ifdef SPB8 +SPBMASK equ 7 ; mask for SPB +SPBSHIFT equ 3 +SPBBITS equ 0ffh ; SPB number of one bits, low order +endif + +ifdef OLD_CACHE +BUFCNT equ 8 +endif + +BMASK equ SPB*SECSIZE-1 ; mask offset in to cache block +BSHIFT equ SECSHIFT+SPBSHIFT + +LWBUFCT equ 16 ; size of reblocking lazy write buffer + +; OFT Hash Table Size (8 bytes each) + +OFTHASHCNT equ 16 ; 16 hash chains for open files +OFTHASHMSK equ 78h ; mask for computing hash offset + + +; Number of I/O command blocks which aren't associated with buffers + +IOBCNT equ 8 ; 8 should be enough BUGBUG + +; # of OS/2 ram semaphores that we can be blocked on, simultaneously. + +SEMCNT equ 32 + + +; Cache Hash +; +; A sector hash is used to locate the start of a chain, the chain +; is then scanned linearly. +; +; For our current size of 256 hash chains, we get: +; +; 1 meg of cache RAM = 256 blocks = 1 blocks per chain (average) +; 2 meg of cache RAM = 512 blocks = 2 blocks per chain (average) +; + +HASHCNT equ 256 ; 1024 bytes of hash header + +; Directory Lookaside record count + +DLCNT equ 10 ; 10 guys for now + +; Maximum DIRBLKs we may need to allocate for any given +; operation. This is in effect the maximum tree depth. +; +; Worst case, with 256 character file names and nearly empty +; DIRBLKs, 10 is enough levels for 60,000 files - about 40 megabytes +; of space just for that directory. Given more practical file length +; names this is enough for 10s of millions of files in a directory. +; + +MAX_DIR_NEED equ 10 + + +;* Heap Definitions + +HHSIZ equ 4 ; size, in bytes, of heap header +GROHEAPCNT equ 50 ; grow heap if we have to compact more + ; than once per 50 allocations + +;* Special Transition Locking Structure size + +TRANCNT equ 4 ; just need 4 spots + + +; Zero offset +; +; MASM won't take 0.BAK, so we use ZERO.BAK +; + +dumy struc + ZERO db ? +dumy ends + + +; Maximum number of volumes that we can mount +; +; The volume ID is kept in the high bits of the sector numbers +; kept in our RAM structures, +; so there is a tradeoff between max volumes and max sectors. +; +; 32 max volumes gives us a 65 billion byte volume limit, +; which should last us for a while. Since sector numbers +; are stored on the disk without their volume upper bits +; this is strictly an implimentation detail; we can adjust +; the number of volumes or eliminate this tradeoff in other +; implimentations which will be 100% media compatable. +; +; We use the term VSector to indicate a vol/sector combination +; and PSector to indicate just the physical absolute sector # +; +; + +VOLMAX equ 32 ; 64 max volumes. + +MAXSEC equ 134217728 ; 2^32/32 max sectors + +SECMASK equ 07FFFFFFh ; mask for sector number + +HSECMASK equ 07h ; high byte sector mask + +HVOLMASK equ 0f8h ; high byte volume mask +SVOLMASK equ 1fh ; shifted right volume mask + +VOLRSHIFT equ (32-5) ; shift right to extract volume index +VOLLSHIFT equ 5 ; shift left to extract volume index + + +;* Signature Values for Disk Structures +; +; These signature values help with debugging and they'll +; be used by the CHKDSK utility to help repair disks. +; +; WARNING - the low byte of all valid signatures must be non-zero, +; since we destroy signatures by clearing the low byte. + +J equ ((('J'-'A')*40+('G'-'A'))*40+'L'-'A') +R equ ((('R'-'A')*40+('P'-'A'))*40+'W'-'A') + +ifdef MASM +ABSIGVAL equ J*40*40*40 + R ; allocation blk +DBSIGVAL equ 40000000h + J*40*40*40 + R ; directory blks +FNSIGVAL equ 0C0000000h + J*40*40*40 + R ; fnodes +else +ABSIGVAL equ (long)J*40*40*40 + (long)R ; allocation blk +DBSIGVAL equ 40000000hL + (long)J*40*40*40 + (long)R ; directory blks +OLDFNSIGVAL equ 80000000hL + (long)J*40*40*40 + (long)R ; fnodes +FNSIGVAL equ 0C0000000hL + (long)J*40*40*40 + (long)R ; fnodes +endif + + + +;* FastFile bitmaps +; +; 0x00000000 all checking disabled +; 0x00000001 FF_FLUSHLAZY DoZap lazy writes are automatically flushed +; 0x00000002 FF_ZAPSEC DoZap blasts sector numbers/sector data +; 0x00000004 FF_LRUCHK vbs verification of LRU/dirty integrity +; 0x00000008 FF_CHKSUM sector checksumming is omitted +; 0x00000010 FF_PLACECHK placebuf verifies location of buffer +; 0x00000020 FF_HEAPCHK verify heap headers +; 0x00000040 FF_DIRMAP produce inram map of directory tree +; 0x00000080 FF_HASHCHN check hash chains +; + +FF_FLUSHLAZY equ 00000001h +FF_ZAPSEC equ 00000002h +FF_LRUCHK equ 00000004h +FF_CHKSUM equ 00000008h +FF_PLACECHK equ 00000010h +FF_HEAPCHK equ 00000020h +FF_DIRMAP equ 00000040h +FF_HASHCHN equ 00000080h + +; Dependency dumys. +; +; The assembler won't to an ".errnz" comparing two external +; addresses, since it doesn't know their address. So we +; put the .errnz in the module which defines the address, +; and we make that location and all folks that rely upon the +; relationship reference that dumy. +; +; If you change a relationship with such a dumy definition, you +; must find and edit all references to this dumy. +; diff --git a/private/ntos/boot/bootcode/hpfs/i386/dir.inc b/private/ntos/boot/bootcode/hpfs/i386/dir.inc new file mode 100644 index 000000000..9e2d44469 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/dir.inc @@ -0,0 +1,286 @@ +;** 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 +
\ No newline at end of file diff --git a/private/ntos/boot/bootcode/hpfs/i386/dirent.inc b/private/ntos/boot/bootcode/hpfs/i386/dirent.inc new file mode 100644 index 000000000..1ba3f82df --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/dirent.inc @@ -0,0 +1,80 @@ +BREAK <Directory entry> + +; SCCSID = @(#)dirent.inc 12.5 89/07/14 +; +; +-----------------------------+ +; | (11 BYTE) filename/ext | 0 0 +; +-----------------------------+ +; | (BYTE) attributes | 11 B +; +-----------------------------+ +; | (8 BYTE) reserved | 12 C +; +-----------------------------+ +; | (WORD) First cluster of EA | 20 14 +; +-----------------------------+ +; | (WORD) time of last write | 22 16 +; +-----------------------------+ +; | (WORD) date of last write | 24 18 +; +-----------------------------+ +; | (WORD) First cluster of file| 26 1A +; +-----------------------------+ +; | (DWORD) file size | 28 1C +; +-----------------------------+ +; +; First byte of filename = E5 -> free directory entry +; = 00 -> end of allocated directory +; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour +; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 +; + +dir_entry STRUC +dir_name DB 11 DUP (?) ; file name +dir_attr DB ? ; attribute bits +dir_pad DB 8 DUP (?) ; reserved for expansion +dir_EAhandle DW ? ; handle to Extended Attributes +dir_time DW ? ; time of last write +dir_date DW ? ; date of last write +dir_firstfile DW ? ; first allocation unit of file +dir_size_l DW ? ; low 16 bits of file size +dir_size_h DW ? ; high 16 bits of file size +dir_entry ENDS + +DIRENT_DELETED EQU 0E5h ; indicator of deleted file +DIRENT_NOFEALIST EQU 0 ; Indicates no extended attributes + + +; +; Values for dir_attr +; +; attr_newfiles is used in the case of IFS to indicate that the type of file +; being requested for findfirst/next is a "new" file i.e. long +; name or a mixed-case name that the FAT FS does not support. +; +attr_read_only EQU 1h +attr_hidden EQU 2h +attr_system EQU 4h +attr_volume_id EQU 8h +attr_directory EQU 10h +attr_archive EQU 20h +attr_device EQU 40h ; This is a VERY special bit. + ; NO directory entry on a disk EVER + ; has this bit set. It is set non-zero + ; when a device is found by GETPATH + +attr_newfiles EQU 40h ; name is non-8.3. never set for FAT FS + +attr_all EQU attr_hidden OR attr_system OR attr_directory + ; OR of hard attributes for FINDENTRY + +attr_ignore EQU attr_read_only OR attr_archive OR attr_device + ; ignore these attributes during + ; search first/next + +attr_changeable EQU attr_read_only OR attr_hidden OR attr_system OR attr_archive + ; changeable via CHMOD + +attr_used EQU attr_read_only OR attr_hidden OR attr_system OR attr_volume_id OR attr_directory OR attr_archive OR attr_newfiles + ; We ignore the rest for $Creat due to LOTUS + ; passing in an attribute of 0x8000!! + +INV_3XBOX_SRCH_ATTRS EQU attr_newfiles ; we should not pass this bit + ; for FSDS from 3xbox. diff --git a/private/ntos/boot/bootcode/hpfs/i386/filemode.inc b/private/ntos/boot/bootcode/hpfs/i386/filemode.inc new file mode 100644 index 000000000..2e9165204 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/filemode.inc @@ -0,0 +1,105 @@ +; SCCSID = @(#)filemode.inc 12.6 89/04/26 + +BREAK <Standard I/O assignments> + +stdin EQU 0 +stdout EQU 1 +stderr EQU 2 +stdaux EQU 3 +stdprn EQU 4 + +BREAK <File modes - passed to open, stored in sf_mode or JFN_Flags> + +; +; The OS/2 api calls DosOpen, DosSetFHandState, and DosQFHandState +; all use a mode word parameter. Some of these values are stored +; in the sft (system file table) in the field sf_mode. Others +; are stored in the JFN flags (JFN_Flg_Ptr). The layout of +; sf_mode and the word parameter for the call is the same. The +; following EQU's are used to get to these values. The layout +; of the word is: +; +; 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +; D W F C R L L L I S S S M A A A +; +; with: +; AAA (2-0): The Access mode (read only, etc.) +; SSS (6-4): Sharing mode (deny write acces to others, etc.) +; LLL (8-10): Locality of reference (sequential, random, etc.) +; M (3) : Monitor open +; I (7) : Not inherited by child +; R (11): Rumored to be used by spooler. API caller must set +; this to zero. +; C (12): Advise device driver not to cache data. This is +; stored in JFN flags. +; F (13): Fail errors +; W (14): write through +; D (15): Direct access open +; +; The DosOpen2 and $Extended_Open2 calls has an additional word for +; openmode. The layout of this word is +; +; 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +; P U U U U U U U U U U U U U U U +; +; with: +; P (15): Open physical disk (used by FDISK program). This bit +; is set by procedure DevReturnHandle. API/INT21h +; caller must set this bit to zero. This bit is stored +; in sft. +; +; U : Unused anywhere. API caller must set these bits to +; zero. +; +; NOTE: Please document all use of the openmode bits including those +; that are internal to the kernel (e.g. the P bit). + +; wwwwxxxxyyyyzzzz +; 5432109876543210 +open_access EQU 0000000000000111B +open_for_read EQU 00h +open_for_write EQU 01h +open_for_both EQU 02h +open_max EQU 02h +open_for_exec EQU 03h ; open via internal exec call + ; (not available to API) + +open_monitor EQU 0000000000001000B + +open_sharing_mode EQU 0000000001110000B +sharing_compat EQU 000H +sharing_deny_both EQU 010H +sharing_deny_write EQU 020H +sharing_deny_read EQU 030H +sharing_deny_none EQU 040H +sharing_max EQU 040H ; max value for check_access_AX + ; (check_access_ax handles + +; these bits are for openmode +open_no_inherit EQU 0000000010000000B ; Child does not inherit handle +open_autofail EQU 0010000000000000B ; hard errors failed +open_write_through EQU 0100000000000000B ; write through to disk +open_direct EQU 1000000000000000B ; open of a device for direct access +open_no_cache EQU 0001000000000000B ; don't cache data + +open_locality EQU 0000011100000000B ; locality of reference +locality_unknown EQU 000H +locality_sequential EQU 100H +locality_random EQU 200H +locality_semirandom EQU 300H + +; these bits are for openmode2 available to DosOpen2/$Extended_Open2 +; +open2_phys_disk EQU 1000000000000000B ; open physical disk + +; Bits carried in SFT mode field (@PhysDisk) +o_mode_in_sft EQU open_direct+open_monitor+open_sharing_mode+open_access+open_locality + +; Bits carried in JFN flags +o_mode_in_flags EQU open_write_through+open_autofail+open_no_inherit+open_no_cache + +; Reserved bits +o_mode_reserved EQU NOT (o_mode_in_sft+o_mode_in_flags) +o_mode2_reserved equ -1 ; all bits are reserved + +SUBTTL diff --git a/private/ntos/boot/bootcode/hpfs/i386/fnode.inc b/private/ntos/boot/bootcode/hpfs/i386/fnode.inc new file mode 100644 index 000000000..af0207520 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/fnode.inc @@ -0,0 +1,214 @@ +;** FNODE.H - Fnode definitions +; +; FILESYS +; Gregory A. Jones +; Copyright 1988 Microsoft Corporation +; +; Modification history: +; P.A. Williams 06/01/89 Added fields FN_ACLBASE and FN_NEACNT +; to fnode. +; P.A. Williams 08/01/89 Added typedef FNODE and PFNODE, ALBLK, PALBLK, +; ALLEAF, PALLEAF, ALSEC, and PALSEC. +; + + +;* File Allocation Tracking +; +; File space is allocated as a list of extents, each extent as +; large as we can make it. This list is kept in a B+TREE format. +; Each B+TREE block consists of a single sector containing an +; ALSEC record, except for the top most block. The topmost block +; consists of just an ALBLK structure, is usually much smaller than +; 512 bytes, and is typically included in another structure. +; +; The leaf block(s) in the tree contain triples which indicate +; the logical to physical mapping for this file. Typically this +; extent list is small enough that it is wholy contained in the +; fnode ALBLK stucture. If more than ALCNT extents are required +; then the tree is split into two levels. Note that when the +; topmost B+TREE block is 'split' no actual split is necessary, +; since the new child block is much bigger than the parent block +; and can contain all of the old records plus the new one. Thus, +; we can have B+TREEs where the root block contains only one +; downpointer. +; +; The following rules apply: +; +; 1) if the file is not empty, there is at least one sector allocated +; to logical offset 0. This simplifys some critical loops. +; +; 2) The last entry in the last node block contains a AN_LOF value of +; FFFFFFFF. This allows us to extend that last leaf block +; without having to update the node block. +; +; 3) For the node records, the AN_SEC points to a node or leaf +; sector which describes extents which occur before that +; record's AN_LOF value. +; + +;* Allocation block structure +; +; Each allocation block consists of one of these. This may be +; a small block imbedded in an FNODE or OFT structure, or it +; may occupy a whole sector and be embedded in an ALSEC structure. +; + +ALBLK struc + AB_FLAG db ? ; flags + AB_FLAG2 db 3 dup (?) ; unused - sometimes copied with AB_FLAG + AB_FCNT db ? ; free count - slots for ALLEAF or ALNODE + AB_OCNT db ? ; occupied count - # of ALLEAF or ALNODEs + AB_FREP dw ? ; offset to last item+1 + ; ALLEAF or ALNODE records go here +ALBLK ends + +ABF_NODE equ 80h ; if not a leaf node +ABF_BIN equ 40h ; suggest using binary search to find +ABF_FNP equ 20h ; parent is an FNODE +ABF_NFG equ 01h ; not a flag, high order bit of AB_FREP + +; Allocation Node Structure +; +; These follow an ALBLK header for a node block + +ALNODE struc + AN_LOF dd ? ; logical offset (sectors + AN_SEC dd ? ; sector for guys < this +ALNODE ends + + +; Allocation Leaf Structure +; +; These follow an ALBLK header in a leaf block + +ALLEAF struc + AL_LOF dd ? ; logical sector offset (sectors) + AL_LEN dd ? ; length of extent (sectors) + AL_POF dd ? ; physical sector offset (sectors) +ALLEAF ends + + +;* Allocation Sector Structure +; +; Root ALBLK structures are contained within other structures, +; such as the FNODE. When the B+TREE is more than one level, +; though, the non-root nodes are each held in a sector. +; +; This structure defines that format +; + +ALSEC struc + AS_SIG dd ? ; signature + AS_SEC dd ? ; sector # of this sector + AS_RENT dd ? ; parent sector # or FNODE # + AS_ALBLK db (size ALBLK) dup (?) ; ALBLK goes here + ; ALNODE or ALLEAF records start here +ALSEC ends + +; # of bytes available for ALLEAF or ALNODE values. Size chosen +; so an integral # of either structure fits + +ifdef MASM +ASSIZ equ ((SECSIZE - size ALSEC)/24*24) + .errnz size ALLEAF-12 + .errnz size ALNODE-8 + .errnz (ASSIZ + AL_LOF + size AL_LOF + size ALBLK) GT 512 ; extra room for an AL_LOF value +else +ASSIZ equ ((SECSIZE - size ALSEC)/24*24) +endif + + +; AuxInfo Structure +; +; The FNODE contains two AuxInfo structures, one for ACLs and +; one for EAs. +; +; These structures point to within FNODE storage and also +; potentially point to an overflow area which is an ALBLK structure. +; The AI_FNL stuff is stored in the FN_FREE area, the ACLs first +; and the EAs second, any free space following. The start of the +; EAs can be found by offseting FN_FREE with FN_ACL.AI_FNL +; + +AUXINFO struc + AI_DAL dd ? ; non-fnode Disk Allocation length + AI_SEC dd ? ; sec # of first sec in extent or of ALSEC + AI_FNL dw ? ; length of fnode info + AI_DAT db ? ; non-zero if AI_SEC points to ALSEC +AUXINFO ends + +;* Fnode block definition +; +; Every file and directory has an FNODE. The file location +; stuff is only used for files; directories are kept in +; a BTREE of DIRBLK records pointed to by FN_SEC[0].RSEC +; + +ALCNT equ 8 ; 8 ALLEAF records in an FN_AT entry +LEAFPERFNODE equ 8 ; 8 ALLEAF records in an FN_AT entry +NODEPERFNODE equ 12 ; 12 ALNODE records in an FNODE. +LEAFPERSEC equ 40 ; ALLEAF records in an allocation sector +NODEPERSEC equ 60 ; ALNODE records in an allocation sector + +FNODE struc + +; The following file location information is copied into the OFT +; and is used there during normal file access. The stuff in the +; fnode record here may in fact be out of date for open files. +; See the OFN_ in the OFT structure THESE TWO AREAS IN THE +; RESPECTIVE RECORDS MUST HAVE IDENTICAL FORMATS. +; +; There are two kinds of location info: FNSCNT SPTR records +; and then a single, double, triple, and quad indirect block pointer. +; The "block threshold" means the first sector number which is +; contained in that indirect block heirarchy. You use this +; to quickly find out where to start looking. +; + + FN_SIG dd ? ; signature value + +; History tracking info for softer software + + FN_SRH dd ? ; sequential read history + FN_FRH dd ? ; fast read history + FN_NAME db 16 dup (?) ; 1st 18 bytes of file name + FN_CONTFN dd ? ; fnode of directory cont. this file/dir + +; stuff not interesting once opened + + FN_ACL db (size AUXINFO) dup (?) ; access ctl list aux info structure + FN_HCNT db ? ; count of valid history bits + FN_EA db (size AUXINFO) dup (?) ; ea aux info structure + FN_FLAG db ? ; FNODE flag byte + + FN_AB db (size ALBLK) dup (?) ; allocation block structure + FN_ALREC db (ALCNT*size ALLEAF) dup (?) ; referenced from FN_AB + FN_VLEN dd ? ; length of valid data in file. if DIR_SIZE + ; is > FN_VLEN then the space inbetween + ; must be zapped before being shown to user + FN_NEACNT dd ? ; # of "need eas" in file + +; The following fields are unused in this release, they're for +; future compatibility. When deleting files, if FN_EEL is non-zero +; then FN_EEL sectors starting at FN_EEP must be released too. +; + + FN_UID db 16 dup (?) ; reserved for UID value + FN_ACLBASE dw ? ; FN_ACLBASE offset of 1st ACE in fnode + FN_SPARE db 10 dup (?); 10 more bytes emergency spares + +; Free pool. ACLs and EAs are stored here via the AUXINFO structure + + FN_FREE db 316 dup (?) ; free space for perm and env list; perm list + ; comes first. +FNODE ends + + +ifdef MASM + .errnz AL_LOF ; verify validity of FN_DMY1 hack above + .errnz size AL_LOF-4 +endif + +; Fnode FN_FLAG bits + +FNF_DIR equ 01h ; is a directory fnode diff --git a/private/ntos/boot/bootcode/hpfs/i386/fsstat.inc b/private/ntos/boot/bootcode/hpfs/i386/fsstat.inc new file mode 100644 index 000000000..074030367 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/fsstat.inc @@ -0,0 +1,66 @@ +;static char *SCCSID = "@(#)fsstat.h 12.2 88/12/19"; +;** fsstat.h - file system statistics +; + +CTHIST equ 10000 + +FSSTAT struc + ST_OPEN dd ? ; count of OPEN calls + ST_CLOSE dd ? ; count of CLOSE calls + ST_READ dd ? ; count of READ calls + ST_WRITE dd ? ; count of WRITE calls + + ST_DEL dd ? ; count of DELETE calls + ST_SEEK dd ? ; count of SEEK calls + ST_FINDF dd ? ; count of FINDF calls + ST_FINDN dd ? ; count of FINDN calls + + ST_RD dd ? ; count of disk reads + ST_WR dd ? ; count of disk writes + ST_CRD dd ? ; count of cache read hits + ST_CWD dd ? ; count of cache write hits + + ST_INVAL dd ? ; invalid LSD hints + ST_VALID dd ? ; valid LSD hints + ST_RDEH dd ? ; directory relocated + ST_RDEM dd ? ; directory adjusted + + ST_SFB dd ? ; count of SFB calls + ST_VBR dd ? ; count of VBR calls + ST_CBR dd ? ; count of CBR calls + ST_AEX dd ? ; count of AddExt calls + + ST_EFA dd ? ; files extended + ST_FLW dd ? ; FLW buffers written + ST_BRV dd ? ; bitmap read valid + ST_BRI dd ? ; bitmap read invalid + + ST_BLSD dd ? ; blocked in LSD + ST_BRDB dd ? ; blcoked in rdb + ST_GFBI dd ? ; GFB interlock + ST_GFBW dd ? ; gfb waits + + ST_LWR dd ? ; long writes + ST_GIB dd ? ; Getinbuf was successful + ST_HMIN dd ? ; heap minimum + ST_LWBW dd ? ; singletons output by lazy IO + + ST_CLN dd ? ; clean blocks found by lazy IO + ST_LWW dd ? ; wakeups caused by lazy IO blocks + ST_QINFO dd ? ; Query info + ST_QIDIR dd ? ; query info on directory + + ST_LWBLK dd SPB*LWBUFCT dup (?) ; Histogram of lazy write blocks + +; performance impact items + + ST_DLRS dd ? ; directory locked forced restart + ST_ALSP dd ? ; count of allocation block splits + pad2 dd 3 dup (?) + + ST_RSIZ dd 64 dup (?) ; Histogram of # sectors in read request + ST_WSIZ dd 64 dup (?) ; Histogram of # sectors in write request +FSSTAT ends + +FS_GETSTAT equ 8004h +FS_CLEAR equ 8005h diff --git a/private/ntos/boot/bootcode/hpfs/i386/macro.inc b/private/ntos/boot/bootcode/hpfs/i386/macro.inc new file mode 100644 index 000000000..153ab4fd9 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/macro.inc @@ -0,0 +1,781 @@ +; SCCSID = @(#)macro.inc 12.1 88/12/19 + +;** Macros + + +;* MASSUME - do an assume +; +; made into a macro to make screwing around during debuuing +; easier +; +; Used by the file system code; not recommended for general +; use. Will be taken out at end of project. BUGBUG + + +MASSUME MACRO + ASSUME CS:CODE,DS:FLAT,ES:FLAT,SS:NOTHING + ENDM + + +;* MENTER - Do an Enter +; +; made into a macro for better code, and to avoid problems +; when USE16 (MASM doesn't generate the override) + +MENTER MACRO arg1,arg2 + push ebp + mov ebp,esp + ifdif <arg1>,<0> + sub esp,arg1 + endif + ENDM + +;* MLEAVE - do a Leave +; +; We need to generate the segment override in USE16, since +; MASM won't do it + +MLEAVE MACRO + ifndef USE32 + DB 66h + endif + leave + ENDM + +;* GetPathBuf - Allocates from the heap memory for the PathBuffer +; +; Enter: (eax) = size of the requested heap block (hvpb not included) +; Exit: C clear: +; (eax) = ptr to the heap block +; C set: error no more heap space +; Uses: eax, flags + +GetPathBuf MACRO + SAVE <EDI, ECX> + add eax, MVPFXSIZE+3+HHSIZ ; for hvpb, rounding and header + and al, 0fch ; round it to quad-boundary +ifndef GHS_ + EXTRN GHS_:near +endif + call GHS_ + RESTORE <ECX, EDI> +ENDM + +;* FreePathBuf - Return PathBuffer to the Heap +; +; +; Enter: (reg) = ptr to PathBuffer (that's (sizeof hvbp) after the +; heap block address) +; Exit: heap block released +; Uses: reg + +FreePathBuf MACRO reg + sub reg, MVPFXSIZE ; (reg) now pts to the heap block + HeapChk reg + add dword ptr -4[reg],80000000h-4 +ENDM + + + +;* Assert - sanity checks (contolled by DEBUG switch) +; +; kind: one of OFT +; +; objs: register/word which contains address +; +; nopush: if non-blank, we don't preserve registers + +IFDEF DEBUG +ASSERT MACRO kind, objs, nopush, arg1 + local a + +a = 0 + + + IFNDEF A_OFT + extrn A_OFT:near,A_SECPTR:near,A_DIRBLK:near,A_FNODE:near + extrn A_AS:near,A_HEAPNAM:near,A_DCHDR:near,A_BUF:near + extrn A_SBDIR:near,A_ALBLK:near + ENDIF + + IFB <nopush> + pushad + pushfd + ENDIF + + IFIDN <kind>,<OFT> + a = 1 + mov eax,objs + call A_OFT ; assert OFT + ENDIF + IFIDN <kind>,<SECPTR> + a = 1 + lea eax,objs + call A_SECPTR ; returns 'C' clear if hint field is valid + ENDIF + IFIDN <kind>,<ALBLK> + a = 1 + mov eax,objs + call A_ALBLK + ENDIF + IFIDN <kind>,<ASREC> + a = 1 + mov eax,objs + call A_AS + ENDIF + IFIDN <kind>,<HEAPNAM> + a = 1 + mov eax,objs + call A_HEAPNAM + ENDIF + IFIDN <kind>,<DCHDR> + a = 1 + mov edx,arg1 + mov eax,objs + call A_DCHDR + ENDIF + IFIDN <kind>,<DIRBLK> + a = 1 + mov eax,objs + call A_DIRBLK + ENDIF + IFIDN <kind>,<BUF> + a = 1 + mov eax,objs + call A_BUF + ENDIF + IFIDN <kind>,<SBDIR> + a = 1 + mov eax,objs + call A_SBDIR + ENDIF + IFIDN <kind>,<FNODE> + a = 1 + mov eax,objs + call A_FNODE + ENDIF + + IFE a + .error illegal option + ENDIF + + + IFB <nopush> + popfd + popad + nop ; errata + ENDIF + ENDM +ELSE + ASSERT Macro a,b,c + ENDM +ENDIF + +;** Heap sanity check macro (controlled by DEBUG flag) +; +; item - make sure this points to a heap allocated block +; (return value from GHS or GHS_) +; if blank, just the arena is checked. + +IFDEF DEBUG +HeapChk Macro item + ifndef A_HEAP + extrn A_HEAP:near + endif + push edx + ifb <item> + mov edx, 0 ;; don't zap the flags + endif + ifdif <edx>, <item> + mov edx, item + endif + call A_HEAP + pop edx +ENDM + +ELSE + HeapChk Macro item + ENDM +ENDIF + + +DPUBLIC MACRO arg + ifdef DEBUG + Public arg + endif +ENDM + + +BREAK MACRO subtitle + SUBTTL subtitle + PAGE +ENDM + +;** CalcGBHShift - calculate the GBH shift factor + +GBHShift = 0 + +CalcGBHShift MACRO + local ?tmp + + if GBHShift NE 0 + EXITM + endif + + ?tmp = (SECSIZE*SPB) / (size BUFNODE) + rept 16 + if ?tmp EQ 1 + exitm + endif + ?tmp = ?tmp / 2 + GBHShift = GBHShift + 1 + endm + + .errnz SECSIZE * SPB - ((size BUFNODE) SHL GBHShift) +ENDM + + +;** GBH - Get Buffer Header +; +; GBH takes the address of a buffer data area and returns the +; address of it's header. +; +; Since the data area is linear in memory and the headers are linear, +; we just do a simple linear mapping. +; +; GBH transforms the address in the register without modifying +; any other registers. +; +; GBH reg + +GBH MACRO reg + CalcGBHShift + sub reg,Bufbase ; (reg) = offset in array of buffers + shr reg,GBHShift ; (reg) = offset in array of bufnotes + +; Get rid of low order stuff. Since reg may be an offset WITHIN +; a buffer and not just a poitner to the header itself, we mask off the +; low order stuff. + + ifidn <reg>,<eax> + and al,100h - (SIZE bufnode) + else + ifidn <reg>,<ebx> + and bl,100h - (SIZE bufnode) + else + ifidn <reg>,<ecx> + and cl,100h - (SIZE bufnode) + else + %out add more code to this macro + .err + endif + endif + endif + add reg, OFFSET DS:Bhbase + ENDM + +;* RetHeap - Return Heap Item +; +; RetHeap address-of-item + +RetHeap MACRO reg + HeapChk reg + add dword ptr -4[reg],80000000h-4 + ENDM + + +;* GetPerm - Get Perminant Memory +; +; Returns a block of memory which will be perminantly +; occupied + +GetPerm Macro reg,len + local l1,l2 +l1: mov reg,PermPtr + add PermPtr,len + cmp reg,PermLim + jb short l2 + push len + call aapm ; allocate additional perm memory + jmp l1 + align 4 +l2: + ENDM + + + BREAK <Double Chain Manipulation Macros> + +;** The following macros manipulate double-linked lists. +; +; All macros take as their first argument the offset to +; the pointer pair. + +;** DCADDB - Add Item to Back of List +; +; DCADDB offset,listreg,itemreg,scrreg +; +; offset = offset into structure of links to edit +; listreg = address of list head node +; itemreg = address of item to insert +; scrreg = scratch register to roach + +DCADDB MACRO o,LR,IR,SR + mov SR,o.BAK[LR] + mov o.FWD[SR],IR + mov o.FWD[IR],LR + mov o.BAK[IR],SR + mov o.BAK[LR],IR + ENDM + + +;** DCADDF - Add Item to Front of List +; +; DCADDF offset,listreg,itemreg,scrreg +; +; offset = offset into structure of links to edit +; listreg = address of list head node +; itemreg = address of item to insert +; scrreg = scratch register to roach + +DCADDF MACRO o,LR,IR,SR + mov SR,o.FWD[LR] + mov o.FWD[IR],SR + mov o.BAK[IR],LR + mov o.BAK[SR],IR + mov o.FWD[LR],IR + ENDM + + + +;** DCREM - Remove Item from Double Link Chain +; +; DCREM offset,adrreg,scrreg1,scrreg2 +; +; offset = offset into structure of links to edit +; adrreg = address of item to remove +; scrreg? = two registers to scratch + +DCREM MACRO o,ir,r2,r3 + mov r2,o.FWD[ir] + mov r3,o.BAK[ir] + mov o.BAK[r2],r3 + mov o.FWD[r3],r2 + ENDM + + +;** DCMOVF - Move Item to the Front of the Chain +; +; DCMOVF offset,listreg,itemreg,scrreg,[scrreg2] +; +; offset = offset into structure of links to edit +; listreg = address of list head node +; itemreg = address of item to insert +; scrreg = scratch register to roach +; scrreg2 = optional additional register to roach +; +; BUGBUG - check users for supply of scratch registers + +DCMOVF MACRO o,lr,ir,sr,sr2 + IFNB <sr2> + DCREM o,ir,sr,sr2 + else + push lr + DCREM o,ir,lr,sr + pop lr + endif + DCADDF o,lr,ir,sr + ENDM + + +;** DCMOVB - Move Item to the Back of the Chain +; +; DCMOVB offset,listreg,itemreg,scrreg +; +; offset = offset into structure of links to edit +; listreg = address of list head node +; itemreg = address of item to insert +; scrreg = scratch register to roach + +DCMOVB MACRO o,lr,ir,sr + push lr + DCREM o,ir,lr,sr + pop lr + DCADDB o,lr,ir,sr + ENDM + + +;** ADDHASH - add a buffer to hash list +; +; ADDHASH lsn,buf,sr1,sr2,sr3 +; +; lsn = Vsector or Psector number of beginning of buffer +; may be any of the arg registers +; buf = address of buffer header +; sr1 = scratch register +; sr2 = 'nother scratch register +; sr3 = last scratch register + +ADDHASH MACRO lsn,buf,sr1,sr2,sr3 + local l1,l2 + + mov sr1,lsn + and sr1,(HASHCNT-1)*4 ; (sr1) = hash index + add sr1,offset DGROUP:HashTab + mov B_HTA[buf],sr1 ; save hash ptr for later use by DCADDF + mov sr2,[sr1] +ifidn <sr2>,<ecx> + jecxz l1 +else + and sr2,sr2 + jz short l1 ; nobody on list yet +endif + DCADDF B_HASH,sr2,buf,sr3 ; add to hash list + jmp short l2 + + align 4 +l1: mov B_HASH.FWD[buf],buf ; empty list, make self-linked + mov B_HASH.BAK[buf],buf +l2: mov [sr1],buf ; put our guy at front of chain + ENDM + + +;** HASHFIND - find a sector in the hash +; +; HASHFIND lsn,buf,sr1,fnd +; +; lsn = logical sector number to find. HASHFIND presumes it +; has already been rounded to a multiple of SPB +; buf = register where buffer is returned +; sr1 = scratch register +; fnd = where to go if found +; NOTE: falls through if not found + + +HASHFIND MACRO lsn,buf,sr1,fnd + local l1,l2 + + mov sr1,lsn + and sr1,(HASHCNT-1)*4 ; (sr1) = hash index + mov buf,Hashtab[sr1] +ifidn <buf>,<ecx> + jecxz l2 +else + and buf,buf + jz short l2 ; no entries in chain, block not there +endif + mov sr1,buf ; save address of first guy + +; Run through circular chain, looking for a match. +; +; (buf) = next guy to check out +; (lsn) = sector value to match +; (sr1) = address of first guy in chain + + align 4 +l1: cmp lsn,B_SEC[buf] + je fnd ; got him + mov buf,B_HASH.FWD[buf] ; go to next buffer + cmp buf,sr1 ; have we gone around yet? + jne l1 ; no, go examine buffer +l2: + ENDM + + + +;** FALLTHRU - Verifies Fallthrough Validity + +FALLTHRU MACRO labl + align 4 ; don't have errnz fail due to alignment + IF2 ; of following label + .errnz labl-$ + ENDIF + ENDM + + +;** INTERR - Internal Error +; INTERRnz - Internal error iff 'Z' clear +; INTERRzr - Internal error iff 'Z' set +; INTERRc - Internal error if 'C' set + +ifdef DEBUG +INTERR MACRO + local l +l: int 3 + jmp l + ENDM + +INTERRzr MACRO + local l + jnz short l + int 3 + jmp $-1 +l: + ENDM + +INTERRc MACRO + local l + jnc short l + int 3 + jmp $-1 +l: + ENDM + +INTERRnz MACRO + local l + jz short l + int 3 + jmp $-1 +l: + ENDM +else +INTERR MACRO + ENDM +INTERRzr MACRO + ENDM +INTERRc MACRO + ENDM +INTERRnz MACRO + ENDM +endif + +;* Debug Traps +; +; These are removed as the code is exercised + +TRAPC macro + local l + jnc short l + int 3 +l: + ENDM + +TRAPZ macro + local l + jnz short l + int 3 +l: + ENDM + +TRAPNZ macro + local l + jz short l + int 3 +l: + ENDM + + +;** PANIC - Panic File System +; +; BUGBUG - fix me to do something besides trap + +PANIC macro + local l +l: int 3 + jmp l + ENDM + +;** Bulk Register Save/Restore +; + +SAVE MACRO reglist +IRP reg,<reglist> + PUSH reg +ENDM +ENDM +.xcref SAVE + +RESTORE MACRO reglist ;; pop those registers +IRP reg,<reglist> + POP reg +ENDM +ENDM +.xcref RESTORE + + +;* ret16 - perform a 16bit return +; +; If we are in a use32 segment then we must put out an operand size +; override before the ret. + +ret16 macro stkfix + ife @WordSize - 4 + db 66h ;; operand size override + endif + retf stkfix + endm +.xcref ret16 + + +;* call1616 - perform an indirect 16bit far call +; +; If we are in a use32 segment then we must put out an operand size +; override before the call and then cast the target to "FWORD" so that +; MASM will generate the correct instruction. +; +; The target must be indirect. + +call1616 macro target + .errnz (type target) - 4 + ife @WordSize - 4 + db 66h ;; operand size override + call fword ptr target ;; force indirect far call + else + call target + endif + endm +.xcref call1616 + + +;** Dpush - Push 32-bit constant +; +; MASM has no way of expressing this in USE16 mode. + +DPUSH macro a +ifdef USE32 + push a +else + push a ; low order + push 0 +endif + ENDM + +;** Push16 - generate a 16bit push in a 32-bit code segment. This is +; needed when pushing segment regs and immediate values as arguments +; to 16bit procedures. + +push16 macro operand + db 66h + push operand + endm + + +;** STATINC - Do an INC if STAT gathering is enabled +; +; Preserves 'C' + +STATINC macro a +ifdef STATS + inc a +endif + ENDM + +;** STATDEC - Do an DEC if STAT gathering is enabled +; +; Preserves 'C' + +STATDEC macro a +ifdef STATS + dec a +endif + ENDM + + +;** LogHCNT - Log OFT holding/unholding +; + +ifdef DEBUG + +LOGHCNT MACRO reg +ifndef DoLogHcnt + EXTRN DoLogHcnt:near +endif + pushfd + push eax + mov eax,reg + call DoLogHcnt + pop eax + popfd + ENDM + +;** LogSCNT - Lock SBDIR holding/unholding +; + +LOGSCNT MACRO REG +ifndef DoLogScnt + EXTRN DoLogScnt:near +endif + pushfd + push eax +ifdif <REG>,<eax> + mov eax,reg +endif + call DoLogScnt + pop eax + popfd + ENDM +else +LOGHCNT MACRO + ENDM +LOGSCNT MACRO + ENDM +endif + +ifdef DEBUG + CALLVBS MACRO + ifndef VBS + EXTRN VBS:NEAR + endif + call VBS + ENDM +else + CALLVBS MACRO + ENDM +endif + +;** cBUFZAP - Call DoZap iff debug mode set +; + +cBUFZAP Macro +ifdef DEBUG +ifndef DoZap + EXTRN DoZap:near +endif + call DoZap +endif + endm + + +;** Stack Frame Macros +; +; These macros are used to allow a stack frame to be setup by +; simple PUSHES and yet guarantee that the pushes won't drift +; out of sync with the frame declaration. + +LASTEL MACRO struc,elem + .errnz size struc - elem - size elem +?frof = elem + ENDM + +NEXTEL MACRO elem + .errnz ?frof - elem - size elem +?frof = elem + ENDM + +DUMYEL MACRO si +?frof = ?frof - si + ENDM + +FIRSTEL MACRO elem + .errnz ?frof - size elem +?frof = elem + .errnz elem + ENDM + + +;** CHKSECNUM - Check Sector number +; +; CHKSECNUM reg +; +; Make sure that reg has a sector number in it without the high order +; volume ID bits + + +CHKSECNUM MACRO reg + local l1 +ifdef DEBUG + test reg,NOT SECMASK + jz l1 + INTERR +l1: +endif + ENDM diff --git a/private/ntos/boot/bootcode/hpfs/i386/makefile b/private/ntos/boot/bootcode/hpfs/i386/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ntos/boot/bootcode/hpfs/i386/misc.inc b/private/ntos/boot/bootcode/hpfs/i386/misc.inc new file mode 100644 index 000000000..7135cf542 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/misc.inc @@ -0,0 +1,64 @@ +;static char *SCCSID = "@(#)misc.h 12.2 88/12/19"; +; #define DEBUG 1 + +ifdef MASM + + include filemode.inc + + BREAK <Misc. Definitions> + +endif + +ERROR_OPLOCKED equ 0eeh + + +;* MISC.INC - Miscelaneous structure definitions. +; +; These need to be included first because other structures +; make use of them. +; + + +;* SecPtr - Sector Pointer Structure +; +; Structures which contain a sector number usually use the +; SecPtr structure, which contains an advisory pointer. The +; pointer points to a buffer header, which is *probably* the +; header for the sector named in SecPtr, but the user must check. +; + +SECPTR struc + SNUM dd ? ; VSector number + SHINT dw ? ; hint address, 0 if none +SECPTR ends + + + + +;* Write type flags for SDW +; + +WT_CACH equ 01h ; write via cache +WT_DIR equ 02h ; write direct as much as possible +WT_EXT equ 04h ; write is extending the file + + +;* Bit Map Sets + +BITMAPL equ -4 ; bit map length preceeds table +BITMAPC equ -8 ; count of sectors left in bitmap + + +;* conditional short value + +ifdef MASM +ifdef USE16 +SHRT EQU < > +else +ifdef DEBUG +SHRT EQU < > +else +SHRT EQU <short> +endif +endif +endif diff --git a/private/ntos/boot/bootcode/hpfs/i386/pinboot.asm b/private/ntos/boot/bootcode/hpfs/i386/pinboot.asm new file mode 100644 index 000000000..412280f14 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/pinboot.asm @@ -0,0 +1,727 @@ + page ,132 + title pinboot - Pinball boot loader + name pinboot + +; The ROM in the IBM PC starts the boot process by performing a hardware +; initialization and a verification of all external devices. If all goes +; well, it will then load from the boot drive the sector from track 0, head 0, +; sector 1. This sector is placed at physical address 07C00h. +; +; The boot code's sole resposiblity is to find NTLDR, load it at +; address 2000:0000, and then jump to it. +; +; The boot code understands the structure of the Pinball root directory, +; and is capable of reading files. There is no contiguity restriction. +; +; The boot sector does not understand the Pinball file system's hotfixing -- +; there isn't enough room. So if NTLDR is hotfixed, we're out of luck. +; + +MASM equ 1 + .xlist + .286 + include macro.inc +; +A_DEFINED equ 1 ; don't "extrn" A_xxxx functions + + .386 + include const.inc ;get the file system's headers. + include chain.inc + include misc.inc + include fnode.inc + include dir.inc + include superb.inc + .286 + .list + +DoubleWord struc +lsw dw ? +msw dw ? +DoubleWord ends + +; +; The following are various segments used by the boot loader. The first +; two are the segments where the boot sector is initially loaded and where +; the boot sector is relocated to. The others are the static locations +; where the mini-FSD and OS2KRNL are loaded. There is no segment definition +; for where OS2LDR is loaded, since its position is variable (it comes right +; after the end of OS2KRNL). +; + +BootSeg segment at 07c0h ; this is where the ROM loads us initially. +BootSeg ends + +NewSeg segment at 0d00h ; this is where we'll relocate to. +NewSeg ends ; enough for 16 boot sectors + + ; 4-sector scratch + ; below where we'll load OS2KRNL. + +LdrSeg segment at 2000h ; we want to load the loader at 2000:0000 +LdrSeg ends + +ScrOfs equ 0f800h - 0d000h ; offset of 2K scratch area. + +MOVEDD macro dest, src ; macro to copy a doubleword memory variable. + mov ax, src.lsw + mov dest.lsw, ax + mov ax, src.msw + mov dest.msw, ax + ENDM + +;/********************** START OF SPECIFICATIONS ************************/ +;/* */ +;/* SUBROUTINE NAME: pinboot */ +;/* */ +;/* DESCRIPTIVE NAME: Bootstrap loader */ +;/* */ +;/* FUNCTION: To load NTLDR into memory. */ +;/* */ +;/* NOTES: pinboot is loaded by the ROM BIOS (Int 19H) at */ +;/* physical memory location 0000:7C00H. */ +;/* pinboot runs in real mode. */ +;/* This boot record is for Pinball file systems only. */ +;/* Allocation information for NTLDR may not */ +;/* exceed an FNODE. */ +;/* */ +;/* ENTRY POINT: pinboot */ +;/* LINKAGE: Jump (far) from Int 19H */ +;/* */ +;/* INPUT: CS:IP = 0000:7C00H */ +;/* SS:SP = 0030:00FAH (CBIOS dependent) */ +;/* */ +;/* EXIT-NORMAL: */ +;/* DL = INT 13 drive number we booted from */ +;/* Jmp to main in OS2LDR */ +;/* */ +;/* EXIT-ERROR: None */ +;/* */ +;/* EFFECTS: Pinball mini-FSD is loaded into the physical */ +;/* memory location 000007C0H */ +;/* NTLDR is loaded into the physical memory */ +;/* location 00020000H */ +;/* */ +;/* MESSAGES: */ +;/* A disk read error occurred. */ +;/* The file NTLDR cannot be found. */ +;/* Insert a system diskette and restart the system. */ +;/* */ +;/*********************** END OF SPECIFICATIONS *************************/ +BootCode segment ;would like to use BootSeg here, but LINK flips its lid + assume cs:BootCode,ds:nothing,es:nothing,ss:nothing + + org 0 ; start at beginning of segment, not 0100h. + + public _pinboot +_pinboot proc far + jmp start +; +; The following is the default BPB for Pinball hard disks. It may +; be modified by FORMAT or SYS before being installed on the disk. +; +; Parameters such as Heads, SectorsPerTrack, and SectorsLong are +; set up for a 20MB hard disk, so that a binary image of this boot +; record may be written directly to a test hard disk without having +; to reformat the drive. +; +; Note that this is really just a place-holder--anyone who writes +; the boot code should preserve the volume's existing BPB. +; +Version db "IBM 10.2" +BPB label byte +BytesPerSector dw SECSIZE ; Size of a physical sector +SectorsPerCluster db 4 ; Sectors per allocation unit +ReservedSectors dw 1 ; Number of reserved sectors +Fats db 2 ; Number of fats +DirectoryEntries dw 0200h ; Number of directory entries +Sectors dw 0 ; No. of sectors - no. of hidden sectors +Media db 0f8h ; Media byte +FatSectors dw 0029h ; Number of fat sectors +SectorsPerTrack dw 17 ; Sectors per track +Heads dw 4 ; Number of surfaces +HiddenSectors dd 0011h ; Number of hidden sectors +SectorsLong dd 0a2c3h ; Number of sectors iff Sectors = 0 +; +; The following is the rest of the Extended BPB for the volume. +; The position and order of DriveNumber and CurrentHead are especially +; important, since those two variables are loaded into a single 16-bit +; register for the BIOS with one instruction. +; +DriveNumber db 80h ; Physical drive number (0 or 80h) +CurrentHead db ? ; Variable to store current head number + +Signature db 28h ; Signature Byte for bootsector +BootID dd 64d59c15h ; Boot ID field. +Boot_Vol_Label db 'C-DRIVE',0,0,0,0 ;volume label. +Boot_System_ID db 'HPFS ' ; Identifies the IFS that owns the vol. +; +; The following variables are not part of the Extended BPB; they're just +; scratch variables for the boot code. +; +SectorBase dd ? ; next sector to read +CurrentTrack dw ? ; current track +CurrentSector db ? ; current sector +SectorCount dw ? ; number of sectors to read +lsnSaveChild dd ? ; sector to continue directory search + +;**************************************************************************** +start: +; +; First of all, set up the segments we need (stack and data). +; + cli + xor ax, ax ; Set up the stack to just before + mov ss, ax ; this code. It'll be moved after + mov sp, 7c00h ; we relocate. + sti + + mov ax, Bootseg ; Address our BPB with DS. + mov ds, ax + assume ds:BootCode +; +; Now read the 16-sector boot block into memory. Then jump to that +; new version of the boot block, starting in the second sector +; (after the bootrecord sig). +; + mov SectorBase.lsw, 0 ; read sector zero. + mov SectorBase.msw, 0 + mov word ptr [SectorCount], SEC_SUPERB+4 ; read boot/superblock. + mov ax, NewSeg ; read it at NewSeg. + mov es, ax + sub bx, bx ; at NewSeg:0000. + call DoReadLL ; Call low-level DoRead routine +; + push NewSeg ; we'll jump to NewSeg:0200h. + push offset mainboot ; (the second sector). + ret ; "return" to the second sector. +_pinboot endp + +;******************************************************************************* +; +; Low-level read routine that doesn't work across a 64k addr boundary. +; +; Read SectorCount sectors (starting at SectorBase) to es:bx. +; +; As a side effect, SectorBase is updated (but es:bx are not) +; and SectorCount is reduced to zero. +; +DoReadLL proc + push ax ; save important registers + push bx + push cx + push dx + push es + +DoRead$Loop: + mov ax, SectorBase.lsw ; (DX:AX) = start sector of next track + mov dx, SectorBase.msw + add ax, HiddenSectors.lsw ; adjust for partition's base sector + adc dx, HiddenSectors.msw + div SectorsPerTrack ; (DX) = sector within track, (AX)=track + inc dl ; sector numbers are 1-based, not 0 + mov CurrentSector, dl + xor dx, dx ; prepare for 32-bit divide + div Heads ; (DX) = head no., (AX) = cylinder + mov CurrentHead, dl + mov CurrentTrack, ax + +; CurrentHead is the head for this next disk request +; CurrentTrack is the track for this next request +; CurrentSector is the beginning sector number for this request +; +; Compute the number of sectors that we may be able to read in a single ROM +; request. +; + mov ax, SectorsPerTrack ; could read up to this much + sub al, CurrentSector ; offset within this track + inc ax ; CurrentSector was 1-based +; +; AX is the number of sectors that we may read. +; + cmp ax, SectorCount ; do we need to read whole trk? + jbe DoRead$FullTrack ; yes we do. + mov ax, SectorCount ; no, read a partial track. +; +; AX is now the number of sectors that we SHOULD read. +; +DoRead$FullTrack: + push ax ; save sector count for later calc. + mov ah, 2 ; "read sectors" + mov dx, CurrentTrack ; at this cylinder + mov cl, 6 + shl dh, cl ; high 2 bits of DH = bits 8,9 of DX + or dh, CurrentSector ; (DH)=cyl bits | 6-bit sector no. + mov cx, dx ; (CX)=cylinder/sector no. combination + xchg ch, cl ; in the right order + mov dx, word ptr DriveNumber ; drive to read from, head no. + int 13h ; call BIOS. + + pop ax + jb BootErr$he ; If errors report + add SectorBase.lsw, ax ; increment logical sector position + adc SectorBase.msw, 0 + sub SectorCount, ax ; exhausted entire sector run? + jbe DoRead$Exit ; yes, we're all done. + shl ax, 9 - 4 ; (AX)=paragraphs read from last track + mov dx, es ; (DX)=segment we last read at + add dx, ax ; (DX)=segment right after last read + mov es, dx ; (ES)=segment to read next track at + jmp DoRead$Loop +; +DoRead$Exit: + pop es + pop dx + pop cx + pop bx + pop ax + ret + +DoReadLL endp + +;**************************************************************************** +; +; BootErr - print error message and hang the system. +; +BootErr proc +BootErr$fnf: + mov si,offset TXT_MSG_SYSINIT_FILE_NOT_FD +2 + jmp short BootErr2 +BootErr$he: + mov si,offset TXT_MSG_SYSINIT_BOOT_ERROR +2 +BootErr2: + call BootErr$print + mov si,offset TXT_MSG_SYSINIT_INSER_DK +2 + call BootErr$print + sti + jmp $ ;Wait forever +BootErr$print: + lodsb ; Get next character + cmp al, 0 + je BootErr$Done + mov ah,14 ; Write teletype + mov bx,7 ; Attribute + int 10h ; Print it + jmp BootErr$print +BootErr$Done: + ret +BootErr endp + +;**************************************************************************** + include pinboot.inc ;suck in the message text +; +; Names of the files we look for. Each consists of a length byte +; followed by the filename as it should appear in a directory entry. +; +ntldr db 5, "NTLDR" + + +ReservedForFuture DB 22 dup(?) ;reserve remaining bytes to prevent NLS + ;messages from using them + + .errnz ($-_pinboot) GT (SECSIZE-2),<FATAL PROBLEM: first sector is too large> + + org SECSIZE-2 + db 55h,0aah + +;**************************************************************************** +; +; mainboot - +; +mainboot proc far + mov ax, cs ; get the new DS. + mov ds, ax + add ax, ((SEC_SUPERB + 4) * SECSIZE) / 16 ; address of scratch. + mov es, ax + mov ax, ds ; get DS again. + shl ax, 4 ; convert to an offset. + cli + mov sp, ax ; load new stack, just before boot code. + sti +; +; First find the root FNODE on disk and read it in. +; + mov bx, SEC_SUPERB * SECSIZE + SB_ROOT + MOVEDD SectorBase, [bx] ; SectorBase = sblk.SB_ROOT. + mov SectorCount, 1 ; it's one sector long. + sub bx, bx ; read at scratch segment:0. + call DoRead +; +; Now find the root DIRBLK on disk and save its address. +; + MOVEDD RootDB, es:[bx].FN_ALREC.AL_POF ; RootDB = f.FN_ALREC.AL_POF. +; +; Load NTLDR at 20000h. +; + mov si, offset ntldr ; point to name of NTLDR. + MOVEDD SectorBase, RootDB ; start at root dirblk + call FindFile + mov ax, LdrSeg ; load at this segment. + call LoadFile ; find it and load it. +; +; We've loaded NTLDR--jump to it. Jump to NTLDR. Note that NTLDR's segment +; address was stored on the stack above, so all we need to push is the offset. +; +; Before we go to NTLDR, set up the registers the way it wants them: +; DL = INT 13 drive number we booted from +; + + mov dl, DriveNumber + mov ax,1000 + mov es, ax ; we don't really need this + lea si, BPB + sub ax,ax + push LdrSeg + push ax + ret ; "return" to OS2LDR. +mainboot endp + +;**************************************************************************** +; +; DoRead - read SectorCount sectors into ES:BX starting from sector +; SectorBase. +; +; NOTE: This code WILL NOT WORK if ES:BX does not point to an address whose +; physical address (ES * 16 + BX) MOD 512 != 0. +; +; DoRead adds to ES rather than BX in the main loop so that runs longer than +; 64K can be read with a single call to DoRead. +; +; Note that DoRead (unlike DoReadLL) saves and restores SectorCount +; and SectorBase +; +DoRead proc + push ax ; save important registers + push bx + push cx + push dx + push es + push SectorCount ; save state variables too + push SectorBase.lsw + push SectorBase.msw +; +; Calculate how much we can read into what's left of the current 64k +; physical address block, and read it. +; +; + mov ax,bx + + shr ax,4 + mov cx,es + add ax,cx ; ax = paragraph addr + +; +; Now calc maximum number of paragraphs that we can read safely: +; 4k - ( ax mod 4k ) +; + + and ax,0fffh + sub ax,1000h + neg ax + +; +; Calc CX = number of paragraphs to be read +; + mov cx,SectorCount ; convert SectorCount to paragraph cnt + shl cx,9-4 + +DoRead$Loop64: + push cx ; save cpRead + + cmp ax,cx ; ax = min(cpReadSafely, cpRead) + jbe @F + mov ax,cx +@@: + push ax +; +; Calculate new SectorCount from amount we can read +; + shr ax,9-4 + mov SectorCount,ax + + call DoReadLL + + pop ax ; ax = cpActuallyRead + pop cx ; cx = cpRead + + sub cx,ax ; Any more to read? + jbe DoRead$Exit64 ; Nope. +; +; Adjust ES:BX by amount read +; + mov dx,es + add dx,ax + mov es,dx +; +; Since we're now reading on a 64k byte boundary, cpReadSafely == 4k. +; + mov ax,01000h ; 16k paragraphs per 64k segment + jmp short DoRead$Loop64 ; and go read some more. + +DoRead$Exit64: + pop SectorBase.msw ; restore all this crap + pop SectorBase.lsw + pop SectorCount + pop es + pop dx + pop cx + pop bx + pop ax + ret +DoRead endp +;**************************************************************************** +; +; ReadScratch - reads a block of 4 sectors into the scratch area. +; +; ENTRY: SectorBase = LSN to read. +; +; EXIT: 4 sectors at AX read at BootSeg:ScrOfs +; +; USES: all +; +ReadScratch proc near + push es + push bx + mov word ptr SectorCount, 4 ; read 4 sectors. + push ds ; address scratch area. + pop es + mov bx, ScrOfs ; with ES:BX. + call DoRead + pop bx + pop es + ret +ReadScratch endp +;**************************************************************************** +; +; FindFile - finds a file in the root directory +; +; ENTRY: DS:SI -> name of file to find. +; SectorBase = LSN of first DirBlk to read +; +; EXIT: ES:BX -> dirent of file +; SectorBase = lsn of current DirBlk (for next directory search) +; +; USES: all +; +FindFile proc near + push ds + pop es ; address data with ES too. + call ReadScratch ; read DirBlk (SectorBase already set) + sub cx, cx ; prepare to store name length. + mov cl, [si] ; fetch the length byte. + inc si ; and skip to the name. + mov dx, cx ; save a copy of it. + +ff1: mov bx, DB_START + ScrOfs ; point to first DIRENT, in scratch. + jmp short ff12 +; +; bx -> last entry examined +; cx = length of the name we're looking for +; si -> name we're looking for, without the count byte ("search name") +; +ff10: add bx, [bx].DIR_ELEN ; move to next entry. + call UpcaseName + +ff12: mov ax, si ; save search name address. + mov cx, dx ; reload search name length. + lea di, [bx].DIR_NAMA ; point to current DIRENT name. + repe cmpsb ; compare bytes while equal. + mov si, ax ; restore search name address. + jne ff20 ; not equal, search on +; +; Looks like the names match, as far as we compared them. But if +; the current name was longer than the search name, we didn't compare +; them completely. Check the lengths. +; + cmp dl, [bx].DIR_NAML + jne ff20 ; not equal, try downpointer if any + + ret ; equal - Found the file + + +; Names don't match. If the current entry has a downpointer, +; search it. +; +ff20: test byte ptr [bx].DIR_FLAG, DF_BTP + jz ff30 ; no downpointer, check for end + +; Follow the DownPointer. +; Load the child DIRBLK and search it. +; + add bx, [bx].DIR_ELEN ; move to next entry. + MOVEDD SectorBase, [bx-4] ; fetch last 4 bytes of prev entry. + call ReadScratch ; read child DIRBLK + jmp short ff1 ; search this dirblk + +; +; We don't have a downpointer. +; If this is the end entry in the dirblk, then we have to go up to the parent, +; if any. + +ff30: test byte ptr [bx].DIR_FLAG, DF_END + jz ff10 ; not end of dirblk - check next DirEnt +; +; Check to see if we have a parent (not the top block). If so, read +; the parent dirblk and find the downpointer that matches the current +; sector. Then continue searching after that point. +; + mov bx, ScrOfs ; point to dirblk header + test byte ptr [bx].DB_CCNT, 1 ; 1 means top block + jz ff40 ; not top, continue with parent + jmp FileNotFound ; top block - not found + +; +; read in parent dirblk and find the dirent with this downpointer - +; then continue after that point +; +ff40: MOVEDD lsnSaveChild, SectorBase ; save this sector number + MOVEDD SectorBase, [bx].DB_PAR + call ReadScratch ; read the parent + + mov bx, DB_START + ScrOfs ; start at first entry of child + jmp short ff44 + +; find our current downpointer + +ff42: add bx, di ; move to the next dirent + +ff44: mov di, [bx].DIR_ELEN ; downptr is 4 bytes from end of dirent + mov ax, [bx+di-4].lsw + cmp ax, lsnSaveChild.lsw ; compare low 2 bytes + jne ff42 ; not equal, try next DirEnt + mov ax, [bx+di-4].msw + cmp ax, lsnSaveChild.msw ; compare high 2 bytes + jne ff42 ; not equal, try next DirEnt + + jmp ff30 ; continue from here + +FindFile endp +;**************************************************************************** +; +; LoadFile - reads file in at the specified segment. +; +; ENTRY: ES:BX -> fnode of file to load +; AX = segment address to load at. +; +; USES: all +; +LoadFile proc near + push ax ; save segment to load at. +; +; Here, we have found the file we want to read. Fetch relevant info +; out of the DIRENT: the file's FNODE number and its size in bytes. +; + sub bp, bp ; a zero register is handy. + MOVEDD FileSize, [bx].DIR_SIZE ; get file size + MOVEDD SectorBase, [bx].DIR_FN ; prepare to read FNODE + call ReadScratch ; read in the FNODE +; + pop es ; restore segment to read at. + mov si, ScrOfs + FN_ALREC ; address the FNODE's array. + mov bx, ScrOfs + FN_AB ; address the FNODE's ALBLK. + +lf_go: + test byte ptr [bx].AB_FLAG, ABF_NODE ; are records nodes? + jnz lf_donode ; yes, go get a child. +; +; Here, we have a leaf block. Loop through the ALLEAF records, +; reading each one's data run. +; + mov cl, [bx].AB_OCNT ; get count of leaf records. + mov ch, 0 ; zero-extend. +lf_loop: + MOVEDD SectorBase, [si].AL_POF ; load run start. + mov ax, word ptr [si].AL_LEN ; load run length. + mov SectorCount, ax + push bx ; save ALBLK pointer. + sub bx, bx ; read at ES:0000. + call DoRead + pop bx ; restore ALBLK pointer. + mov ax, es ; get segment we just used + shl SectorCount, 9 - 4 ; cvt sectors to paragraphs + add ax, SectorCount ; get new segment address + mov es, ax ; store new segadr in ES + add si, size ALLEAF ; point to next leaf + loop lf_loop ; go get another run +; +; Here, we've exhausted an array of records. If we exhausted the +; FNODE, we're done. Otherwise, we re-read our parent block, restore +; where we were in it, and advance to the next record. +; +lf_blockdone: + cmp word ptr ds:[ScrOfs+FN_SIG+2], FNSIGVAL shr 16 ; in FNODE? + je lf_alldone ; yes, we've read the whole file. + MOVEDD SectorBase, ds:[ScrOfs+AS_RENT] ; fetch parent sector pointer. + call ReadScratch ; read in our parent. + pop si ; restore where we left off. + pop bx ; restore ALBLK pointer. + add si, size ALNODE ; move to next node. +; +; Here the block contains downpointers. Read in the next child +; block and process it as a node or leaf block, saving where we were +; in the current block. +; +lf_donode: + mov al, [bx].AB_OCNT ; get number of records. + mov ah, 0 ; zero-extend. + shl ax, 3 ; (AX)=size of array. + add ax, bx + add ax, size ALBLK ; (AX)->after end of array. + cmp si, ax ; are we done? + jae lf_blockdone ; yes, we've exhausted this blk. + push bx ; save ALBLK offset. + push si ; save current record offset. + MOVEDD SectorBase, [si].AN_SEC ; get child downpointer. + call ReadScratch ; read the child ALSEC. + mov si, size ALSEC + ScrOfs ; address the ALSEC's array. + mov bx, AS_ALBLK + ScrOfs ; address the ALSEC's ALBLK. + jmp short lf_go +; +; All done, return to caller. +; +lf_alldone: + ret +LoadFile endp + +;**************************************************************************** +; +; UpcaseName - Converts the name of the file to all upper-case +; +; ENTRY: ES:BX -> dirent of file +; +; USES: CX, DI +; +UpcaseName proc near + mov cl,[bx].DIR_NAML + xor ch,ch ; (cx) = # of bytes in name + lea di, [bx].DIR_NAMA ; (es:di) = pointer to start of name +UN10: + cmp byte ptr es:[di], 'Z' ; Is letter lowercase? + jbe UN20 + + sub byte ptr es:[di], 'a'-'A' ; Yes, convert to uppercase +UN20: + inc di + loop UN10 + + ret +UpcaseName endp + +FileNotFound: + jmp BootErr$fnf + +;****************************************************************************** +RootDB dd ? ; LSN of root DIRBLK. + +Flag db ? ; used to store AB_FLAG. + +AllocInfo db size ALLEAF * ALCNT dup (0) ; copy of FNODE alloc info. + +FileSize dd ? ; size of file that was read. + + + .errnz ($-_pinboot) GT (SEC_SUPERB*SECSIZE),<FATAL PROBLEM: main boot record exceeds available space> + + org SEC_SUPERB*SECSIZE + +BootCode ends + + end _pinboot diff --git a/private/ntos/boot/bootcode/hpfs/i386/sources b/private/ntos/boot/bootcode/hpfs/i386/sources new file mode 100644 index 000000000..e877d5d35 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/sources @@ -0,0 +1,38 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=utils +MINORCOMP=pinboot + +TARGETNAME=pinboot +TARGETPATH=obj +TARGETTYPE=LIBRARY + +SOURCES=pinboot.asm + +INCLUDES=\nt\public\sdk\inc +C_DEFINES=-DDBG -DMEMLEAK -DCONDITION_HANDLING=1 -DNOMINMAX +UMLIBS=obj\*\chkdsk.lib + +UMTYPE=console diff --git a/private/ntos/boot/bootcode/hpfs/i386/superb.inc b/private/ntos/boot/bootcode/hpfs/i386/superb.inc new file mode 100644 index 000000000..e670b800b --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/superb.inc @@ -0,0 +1,242 @@ +;** SUPERB.H - Super Block and Spare Block definitions +; +; FILESYS +; Gregory A. Jones +; Copyright 1988 Microsoft Corporation +; +; Modification history: +; P.A. Williams 06/01/89 Added fields SPB_CPSEC and SPB_CPCNT to +; the spare block. +; P.A. Williams 06/05/89 Changed base and functional version no. to 1. +; + +SEC_SUPERB equ 16 ; superblock is after 8K boot block +SEC_SPAREB equ 17 ; spareblock is after superblock +SEC_BOOT equ 0 ; boot sector + + +;* SUPERB.INC - Super Block Definition +; +; The Superblock is the first block of the file system. +; It starts at sector #4, leaving 2K for boot sectors. +; +; Pointer to the root directory +; Pointer to the bit map +; Clean pointer +; Pointer to the bad list +; + +RSP struc + P dd ? ; main psector pointer + P2 dd ? ; spare pointer +RSP ends + + +SuperB struc + SB_SIG1 dd ? ; signature value 1 + SB_SIG2 dd ? ; signature value 2 + + SB_VER db ? ; version # of filesystem structures + SB_FVER db ? ; functional version number - the smallest/ + ; oldest version of the filesystem that can + ; understand this disk - some version + ; enhancements may define fields which can be + ; ignored by earlier versions + + SB_DUMY dw ? ; free + + SB_ROOT dd ? ; Psector # of root fnode + + SB_SEC dd ? ; # of sectors on volume + SB_BSEC dd ? ; # of bad sectors on volume + + SB_BII db (size RSP) dup (?) ; Bitmap Indirect Block + SB_BBL db (size RSP) dup (?) ; badblock list chain #1 + + SB_CDDAT dd ? ; date of last CHKDSK + SB_DODAT dd ? ; date of last Disk Optimize + + SB_DBSIZE dd ? ; # of sectors in dirblk band + SB_DBLOW dd ? ; first Psector in DIRBLK band + SB_DBHIGH dd ? ; last Psector in DIRBLK band + SB_DBMAP dd ? ; first Psector of DIRBLK band bit map. Starts + ; on a 2K boundary, 2K bytes maximum + + SB_VOLNAME db 32 dup (?) ; Volume name + + SB_SIDSEC dd ? ; sector # of first sector in SIDTAB + ; ID map is 4K - 8 contiguous sectors + + SB_FILL db 512-100 dup (?) ; fill definition out to 512 bytes + ; MUST BE ZERO + +SuperB ends + + + +;* SpareB - Spare Block Definitions +; +; SpareB contains various emergency supplies and fixup information. +; This stuff isn't in the superblock in order for the superblock +; to be read only and decrease the liklihood that a flakey write +; will cause the superblock to become unreadable. +; +; This sector is located directly after the superblock - sector 5. +; +; Note that the number of spare DIRBLKs is a format option, given +; that they all have to fit into the SpareB, giving us a max of +; 101 of them. +; +; Access to the SpareB is complicated by the fact that we can't +; access it via the cache, since the cache may be unavailable. +; If every cache buffer is dirty, we could get a HotFix error when +; writing the first one, which would deadlock us if we needed to +; read this stuff via the cache. Instead, we read it directly into +; a private buffer via RdHF. +; +; This means that the disk layout must be such that each cache cluster +; that contains the SpareB or the hotfix list must not contain any +; other writable sector, to prevent us from having a modified +; direct-written sector overwritten by an earlier unmodified copy +; which was in a cache block. It's ok for the SuperB to be in the +; same cache group as the SpareB since the SuperB is RO to the filesys. +; +; Checksums. Done on both Super Block and the Spare Block. +; Both checksums are stored in the Spare Block. The checksum +; field for the Super Block (SPB_SUPERBSUM) must be set when +; calculating the checksum for the Spare Block. The checksum +; field for the Spare Block (SPB_SPAREBSUM) must be zero when +; calculating the checksum for the Spare Block. +; If both checksum fields are zero, the checksums have not been +; calculated for the volume. +; + +SPAREDB equ 20 ; 20 spare DIRBLKs + +SpareB struc + + SPB_SIG1 dd ? ; signature value 1 + SPB_SIG2 dd ? ; signature value 2 + + SPB_FLAG db ? ; cleanliness flag + SPB_ALIGN db 3 dup (?) ; alignment + + SPB_HFSEC dd ? ; first hotfix list P sector + SPB_HFUSE dd ? ; # of hot fixes in effect + SPB_HFMAX dd ? ; max size of hot fix list + + SPB_SDBCNT dd ? ; # of spare dirblks + SPB_SDBMAX dd ? ; maximum number of spare DB values. + SPB_CPSEC dd ? ; code page sector + SPB_CPCNT dd ? ; number of code pages + SPB_SUPERBSUM dd ? ; Checksum of Super Block + SPB_SPAREBSUM dd ? ; Checksum of Spare Block + SPB_DUMY dd 15 dup (?) ; some extra space for future use + SPB_SPARDB dd 101 dup (?) ; Psector #s of spare dirblks +SpareB ends + + +; Super Block Signature + +SBSIG1 equ 0f995e849h ; two signatures cause we got lotsa +SBSIG2 equ 0FA53E9C5h ; space +SPSIG1 equ 0f9911849h ; two signatures cause we got lotsa +SPSIG2 equ 0FA5229C5h ; space + + + +; Superblock Versions + +SBBASEV equ 2 ; base version +SBBASEFV equ 2 ; base functional version + +; Spare Block Flags +; + +SPF_DIRT equ 0001h ; file system is dirty +SPF_SPARE equ 0002h ; spare DIRBLKs have been used +SPF_HFUSED equ 0004h ; hot fix sectors have been used +SPF_BADSEC equ 0008h ; bad sector, corrupt disk +SPF_BADBM equ 0010h ; bad bitmap block +SPF_VER equ 0080h ; file system was written by a version + ; < SB_VER, so some of the new fields + ; may have not been updated + + +;* Bit maps +; +; PFS keeps track of free space in a series of bit maps. +; Currently, each bit map is 2048 bytes, which covers about +; 8 megabytes of disk space. We could rearrange these to be +; more cylinder sensitive... +; +; The superblock has the address of a section of contiguous sectors +; that contains a double word sector # for each bit map block. This +; will be a maximum of 2048 bytes (4 sectors) +; +; Max # of size RAM (K) size 2nd lvl +; bitmaps (meg) to reside bitmap +; bitmap (bytes) +; +; 1 8.39 2 256 +; 2 16.78 4 512 +; 3 25.17 6 768 +; 4 33.55 8 1024 +; 5 41.94 10 1280 +; 6 50.33 12 1536 +; 7 58.72 14 1792 +; 8 67.11 16 2048 +; 9 75.50 18 2304 +; 10 83.89 20 2560 +; 15 125.83 30 3840 +; 20 167.77 40 5120 +; 30 251.66 60 7680 +; 40 335.54 80 10240 +; 50 419.43 100 12800 +; 100 838.86 200 25600 +; 200 1677.72 400 51200 +; 300 2516.58 600 76800 +; 400 3355.44 800 102400 +; 500 4194.30 1000 128000 +; + + + +;* Hot Fixing +; +; Each file system maintains a structure listing N "hot fix" +; disk clusters of HOTFIXSIZ sectors each, each starting on +; a multiple of HOTFIXSIZ. Whenever the file system discovers +; that it's trying to write to a bad spot on the disk it will +; instead select a free hot fix cluster and write there, instead. +; The substitution will be recorded in the hot fix list, and the +; SBF_SPARE bit will be set. The file system sill describes the +; data as being in the bad old sectors; the disk interface will +; do a mapping between the `believed' location and the true location. +; +; CHKDSK will be run as soon as possible; it will move the +; hot fixed data from the hot fix cluster to somewhere else, +; freeing that hot fix cluster, and adjusting the disk structure +; to point to the new location of the data. As a result, entrys +; on the hot fix list should be transient and few. +; +; The superblock contains the first sector of the hot fix list +; which takes the following format: +; +; long oldsec[SB_HFMAX]; sector # of start of bad clusters +; long newsec[SB_HFMAX]; sector # of start of subst. cluster +; long fnode [SB_HFMAX]; fnode sector of file/directory +; involved with bad cluster. May be +; 0 (don't know) or invalid. The +; repair program must verify that it +; *is* an FNODE and must see if other +; structures might also involve this +; bad cluster. +; +; the SB_HFUSE field describes the number of these records which is +; in use - unused ones should have oldsec[i] = 0. The list will +; be 'dense' - no oldsec[i] will be 0 where i < SB_HFUSE. +; +; The sector(s) which contain the hot fix list must be contiguous +; and may not themselves be defective. +; diff --git a/private/ntos/boot/bootcode/hpfs/i386/tables.inc b/private/ntos/boot/bootcode/hpfs/i386/tables.inc new file mode 100644 index 000000000..07cf61244 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/tables.inc @@ -0,0 +1,201 @@ +;static char *SCCSID = "@(#)tables.h 12.2 88/12/19"; +ifdef MASM + BREAK <OFT - Open File Table> +endif + +;* OFT - Open File Table +; +; The OFT contains file specific information which is independent +; of an instance of use of the file. +; +; If the file is open for write access, we keep a pointer to +; it's directory entry, not just it's +; FNODE, so that we can update the length and modification time when it's +; written. +; +; We store the directory's FNODE number and the file name, with these +; we can find the directory entry again even if the directory has +; been shuffled by creates or deletes of other files. Two advisorys +; are kept - the Vsector number, cache block address, and cache block +; offset of the actual directory entry. This information has three +; levels of validity: +; +; 1) Vsector, header address, and offset are valid +; you can find the dir entry easily +; 2) the header address is invalid due to cache flushing. +; Vsector # and offset are still valid, so read the +; cache block and go directly to the entry +; In this case the header address points to the wrong +; Vsector +; 3) the directory has been altered since we opened the file, +; so none of this info is accurate. In this case the +; directory alteration routines located this OFT +; entry and zeroed the Vsector number. Go to the directory +; and search the name again. +; + +OFT struc + OFT_P db (size DCHDR) dup (?) ; double chain of OFT structures, rooted in OFTHead[i] + OFT_FHT db (size DCHDR) dup (?) ; double chain of FHT structures + OFT_RLCK db (size DCHDR) dup (?) ; double chain of RECLOCK structures + OFT_FN db (size SECPTR) dup (?) ; pointer to file FNODE + OFT_SBD dw ? ; pointer to SBDIR structure + OFT_DIRE db (size SECPTR) dup (?) ; pointer to directory block + + OFT_CCNT dd ? ; DB_CCNT value for OFT_DIRE to check OFT_DIRO validity + OFT_FREEDCNT dd ? ; SD_FREEDCNT value for DIRE to be valid + +; +; These length fields are used when writing the file. +; The OFN_ entries will reflect the OFT_ALEN value. These +; aren't updated in the FNODE until the file closes, whereup +; they are trimmed back to OFT_LEN which is itself propigated +; to the file's DIR entry. If write-through is set then the +; OFN_ entries below will be propigated to the FNODE and +; then to the disk, but if we crash the cleanup program +; will deallocate the "extra" sectors. +; + + OFT_LEN dd ? ; file actual length + OFT_ALEN dd ? ; file allocated length (SECSIZE multiple) + OFT_WLEN dd ? ; last byte+1 of valid data in the file + ; (optimization for writing into extended areas + OFT_LAST dd ? ; Psector # of last sector in file, or 0 + OFT_LRP db (size SECPTR) dup (?) ; last run pointer. Valid if OFT_LAST !=0 + ; if OFN_AB.ABF_NODE ==0 this is the address of + ; an OFN_SEC record in this OFT + ; else this is a SECPTR to the SIB + ; containing the last run record + + OFT_VOL dd ? ; pointer to VOLTAB for this guy + + OFT_NAME dd ? ; address of name string len byte + ; followed by name string itself + ; len doesn't include len byte + + OFT_DIRO dw ? ; offset into directory block for entry + OFT_FILL dw ? ; unused, fill + + OFT_LCKCNT dw ? ; count of guys in OFT_RLCK + + OFT_WCNT dw ? ; # of threads blocked on this OFT + + ; the following three fields are used to + ; control access. They're identical in use + ; to the equivalent fields in SBDIR. The + ; Flag byte only contains locking/holding + ; flags, so if DWORD PTR OFT_HCNT is 0 then + ; the OFT is known to be free and clear + + OFT_HCNT dw ? ; held count, has OTF_PND bit also + OFT_DMY db ? ; unused, must be 0 + OFT_FLAG db ? ; flag byte, high order in OFT_HCNT dword + + OFT_WAITC dd ? ; head of wait chain if locked + + OFT_OPLOCK dd ? ; Oplock value, 0 if none + + OFT_BANDP dd ? ; pointer to BandTab structure in BandList + ; for our last allocation. =0 if unused + +; The following 5 fields hold the accumulation of all FHTs for this OFT. +; This saves us from having to scan the FHTs to do a sharing check upon +; open. An OFT is unused when OFT_RD and OFT_WT and OFT_FIND are zero + + OFT_RD dw ? ; # of opens for read + OFT_WT dw ? ; # of opens for write + OFT_DR dw ? ; # of opens with deny read + OFT_DW dw ? ; # of opens with deny write + OFT_COMPAT dw ? ; # of opens for compatibility mode + OFT_FIND dw ? ; count of active FINDs using this OFT + + OFT_REALLYBAD db ? ; non-zero if file is unusable due to + ; corrupt disk BUGBUG - FOLD INTO BITS + OFT_SFLAG db ? ; special flag byte + OFT_DMY2 dw ? ; unused + + +; BUGBUG - rearrange these fields for er offsets dw ? +; +; Info copied from the file's FNODE +; +; The ALLEAF blocks must follow the ALBLK value +; + + OFN_AB db (size ALBLK) dup (?) ; allocation block structure + OFN_ALREC db (8*size ALLEAF) dup (?) ; referenced from FN_AB + +OFT ends + +; flag bits for OFT_FLAG + +OTF_LCK equ 01h ; file is locked against access +OTF_PLK equ 02h ; pending lock +OTF_PSO equ 04h ; pending solo +OTF_PND equ 80h ; lock pending bit + +; flag bits for OFT_SFLAG + +OFS_OPLK equ 01h ; oplocked +OFS_OPBA equ 02h ; oplock BATCH flag set +OFS_DASD equ 04h ; DASD file +ifdef DEBUG +OFS_SAC equ 08h ; supress OFT_ALEN debug check +endif + +; The file storage information from the fnode is replicated +; in the OFT. This saves us from having to blow a cache block +; keeping the FNODE in ram for every open file. The FNODE +; is only accessed when a file is open, and when it's closed. +; (If write-through is set, it's accessed for every growth) +; +; These statements are to keep the FNODE and the OFT in sync. + +ifdef MASM + .errnz (size OFN_ALREC - size FN_ALREC) +endif + + +;* FHT - File Handle Table +; +; The FHT contains per-handle informatiuon + +FHT struc + FHT_SEEK dd ? ; seek pointer + FHT_OFT dd ? ; pointer to OFT + FHT_CHN db (size DCHDR) dup (?) ; chain of FHTs for an OFT + FHT_UID dd ? ; UID and Session ID + FHT_MODE dw ? ; mode bits from OPEN + FHT_RAA dw ? ; read ahead advisory + FHT_HINT dd ? ; hint flags +FHT ends + +ifdef MASM + .errnz FHT_CHN-OFT_FHT ; same offset used for both +endif + +;* FHT_HINT flags + +FHH_SEQ equ 01 ; sequential file + + +;* RecLock - Record Locking Records +; +; One record per lock, chained to the OFT. These are chained +; in order RL_BEG +; + +RECLOCK struc + RL_BEG dd ? ; begining byte of locked range + RL_END dd ? ; end byte of locked range + RL_TYPE db ? ; =1 if read allowed, =0 if full lock + RL_MEM db ? ; =0 if from heap, =1 if from special list + RL_DMY dw ? ; padding + RL_SPID dd ? ; Session/Pid + RL_CHN db (size DCHDR) dup (?) ; double chain of RECLOCK structures +RECLOCK ends + +ifdef MASM + .errnz RL_CHN-OFT_RLCK ; must have same offset to work +endif +
\ No newline at end of file diff --git a/private/ntos/boot/bootcode/hpfs/i386/usa/boothpfs.h b/private/ntos/boot/bootcode/hpfs/i386/usa/boothpfs.h new file mode 100644 index 000000000..b9ff8c722 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/usa/boothpfs.h @@ -0,0 +1,517 @@ +#define HPFSBOOTCODE_SIZE 8192 + + +unsigned char HpfsBootCode[] = { +235,73,144,73,66,77,32,49,48,46,50,0,2,4,1,0, +2,0,2,0,0,248,41,0,17,0,4,0,17,0,0,0, +195,162,0,0,128,0,40,21,156,213,100,67,45,68,82,73, +86,69,0,0,0,0,72,80,70,83,32,32,32,32,0,0, +0,0,0,0,0,0,0,0,0,0,0,250,51,192,142,208, +188,0,124,251,184,192,7,142,216,199,6,62,0,0,0,199, +6,64,0,0,0,199,6,69,0,20,0,184,0,13,142,192, +43,219,232,7,0,104,0,13,104,0,2,203,80,83,81,82, +6,161,62,0,139,22,64,0,3,6,28,0,19,22,30,0, +247,54,24,0,254,194,136,22,68,0,51,210,247,54,26,0, +136,22,37,0,163,66,0,161,24,0,42,6,68,0,64,59, +6,69,0,118,3,161,69,0,80,180,2,139,22,66,0,177, +6,210,230,10,54,68,0,139,202,134,233,139,22,36,0,205, +19,88,114,37,1,6,62,0,131,22,64,0,0,41,6,69, +0,118,11,193,224,5,140,194,3,208,142,194,235,147,7,90, +89,91,88,195,190,57,1,235,3,190,25,1,232,9,0,190, +141,1,232,3,0,251,235,254,172,60,0,116,9,180,14,187, +7,0,205,16,235,242,195,29,0,65,32,100,105,115,107,32, +114,101,97,100,32,101,114,114,111,114,32,111,99,99,117,114, +114,101,100,46,13,10,0,41,0,65,32,107,101,114,110,101, +108,32,102,105,108,101,32,105,115,32,109,105,115,115,105,110, +103,32,102,114,111,109,32,116,104,101,32,100,105,115,107,46, +13,10,0,37,0,65,32,107,101,114,110,101,108,32,102,105, +108,101,32,105,115,32,116,111,111,32,100,105,115,99,111,110, +116,105,103,117,111,117,115,46,13,10,0,51,0,73,110,115, +101,114,116,32,97,32,115,121,115,116,101,109,32,100,105,115, +107,101,116,116,101,32,97,110,100,32,114,101,115,116,97,114, +116,13,10,116,104,101,32,115,121,115,116,101,109,46,13,10, +0,5,78,84,76,68,82,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,170, +140,200,142,216,5,128,2,142,192,140,216,193,224,4,250,139, +224,251,187,12,32,139,7,163,62,0,139,71,2,163,64,0, +199,6,69,0,1,0,43,219,232,58,0,38,139,71,72,163, +27,4,38,139,71,74,163,29,4,190,193,1,161,27,4,163, +62,0,161,29,4,163,64,0,232,138,0,184,0,32,232,16, +1,138,22,36,0,184,232,3,142,192,141,54,11,0,43,192, +104,0,32,80,203,80,83,81,82,6,255,54,69,0,255,54, +62,0,255,54,64,0,139,195,193,232,4,140,193,3,193,37, +255,15,45,0,16,247,216,139,14,69,0,193,225,5,81,59, +193,118,2,139,193,80,193,232,5,163,69,0,232,221,253,88, +89,43,200,118,11,140,194,3,208,142,194,184,0,16,235,222, +143,6,64,0,143,6,62,0,143,6,69,0,7,90,89,91, +88,195,6,83,199,6,69,0,4,0,30,7,187,0,40,232, +147,255,91,7,195,30,7,232,232,255,43,201,138,12,70,139, +209,187,20,40,235,5,3,31,232,23,1,139,198,139,202,141, +127,31,243,166,139,240,117,6,58,87,30,117,1,195,246,71, +2,4,116,19,3,31,139,71,252,163,62,0,139,71,254,163, +64,0,232,173,255,235,202,246,71,2,8,116,201,187,0,40, +246,71,8,1,116,3,233,239,0,161,62,0,163,71,0,161, +64,0,163,73,0,139,71,12,163,62,0,139,71,14,163,64, +0,232,126,255,187,20,40,235,2,3,223,139,63,139,65,252, +59,6,71,0,117,243,139,65,254,59,6,73,0,117,234,235, +182,80,43,237,139,71,12,163,128,4,139,71,14,163,130,4, +139,71,4,163,62,0,139,71,6,163,64,0,232,67,255,7, +190,64,40,187,56,40,246,7,128,117,76,138,79,5,181,0, +139,68,8,163,62,0,139,68,10,163,64,0,139,68,4,163, +69,0,83,43,219,232,189,254,91,140,192,193,38,69,0,5, +3,6,69,0,142,192,131,198,12,226,213,129,62,2,40,228, +247,116,62,161,8,40,163,62,0,161,10,40,163,64,0,232, +240,254,94,91,131,198,8,138,71,5,180,0,193,224,3,3, +195,5,8,0,59,240,115,211,83,86,139,68,4,163,62,0, +139,68,6,163,64,0,232,201,254,190,20,40,187,12,40,235, +133,195,138,79,30,50,237,141,127,31,38,128,61,90,118,4, +38,128,45,32,71,226,243,195,233,217,252,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; diff --git a/private/ntos/boot/bootcode/hpfs/i386/usa/pinboot.inc b/private/ntos/boot/bootcode/hpfs/i386/usa/pinboot.inc new file mode 100644 index 000000000..6a2925984 --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/usa/pinboot.inc @@ -0,0 +1,30 @@ +; SCCSID = @(#)pinboot.inc 12.1 88/12/19 +; Message data area +TXT_MSG_SYSINIT_BOOT_ERROR LABEL WORD + DW END_MSG_SYSINIT_BOOT_ERROR - TXT_MSG_SYSINIT_BOOT_ERROR - 2 + DB 'A disk read erro' + DB 'r occurred.',0DH,0AH +END_MSG_SYSINIT_BOOT_ERROR LABEL WORD + DB 0 +TXT_MSG_SYSINIT_FILE_NOT_FD LABEL WORD + DW END_MSG_SYSINIT_FILE_NOT_FD - TXT_MSG_SYSINIT_FILE_NOT_FD - 2 + DB 'A kernel file is' + DB ' missing from th' + DB 'e disk.', 0DH, 0AH +END_MSG_SYSINIT_FILE_NOT_FD LABEL WORD + DB 0 +TXT_MSG_SYSINIT_NODE LABEL WORD + DW END_MSG_SYSINIT_NODE - TXT_MSG_SYSINIT_NODE - 2 + DB 'A kernel file is' + DB ' too discontiguo' + DB 'us.', 0DH, 0AH +END_MSG_SYSINIT_NODE LABEL WORD + DB 0 +TXT_MSG_SYSINIT_INSER_DK LABEL WORD + DW END_MSG_SYSINIT_INSER_DK - TXT_MSG_SYSINIT_INSER_DK - 2 + DB 'Insert a system ' + DB 'diskette and res' + DB 'tart',0DH,0AH + DB 'the system.',0DH,0AH +END_MSG_SYSINIT_INSER_DK LABEL WORD + DB 0 diff --git a/private/ntos/boot/bootcode/hpfs/i386/volume.inc b/private/ntos/boot/bootcode/hpfs/i386/volume.inc new file mode 100644 index 000000000..dbeba1b9d --- /dev/null +++ b/private/ntos/boot/bootcode/hpfs/i386/volume.inc @@ -0,0 +1,102 @@ +;static char *SCCSID = "@(#)volume.h 12.2 89/09/19"; +; Maximum number of volumes that we can mount +; +; The volume ID is kept in the high bits of the sector numbers +; kept in our RAM structures, +; so there is a tradeoff between max volumes and max sectors. +; +; 32 max volumes gives us a 65 billion byte volume limit, +; which should last us for a while. Since sector numbers +; are stored on the disk without their volume upper bits +; this is strictly an implimentation detail; we can adjust +; the number of volumes or eliminate this tradeoff in other +; implimentations which will be 100% media compatable. +; +; We use the term VSector to indicate a vol/sector combination +; and PSector to indicate just the physical absolute sector # +; +; + + +; Bitmap related numbers + +BANDSHIFT equ BSHIFT+3 ; right shift sector # to band index +BANDMASK equ SPB*SECSIZE*8L-1 ; mask for within band bits +BANDSIZE equ SPB*SECSIZE*8L ; # of sectors in a full band + + +;* BandTab - Disk Band Table +; +; The disk is broken up into logical bands, each band being +; the amount of space that is addressed in 2K of bitmap. +; +; This structure tracks the bands: the location of their respective +; bit maps, the amount of free space, etc. +; + +BANDTAB struc + BT_MAP db (size SECPTR) dup (?) ; Vsector # and hint pointer for map + BT_FREE dw ? ; # of free sectors in this band + BT_OFC dw ? ; # of files allocating from this band + BT_BASE dd ? ; Psector # of first sector in map + BT_LEN dd ? ; byte length of this map + BT_HWO dd ? ; high water offset to 1st non-zero byte + ; BUGBUG - use BT_HWO +BANDTAB ends + + +;* VolTab - Volume Table +; +; VolPtr[i] points to the VolTab structure for that volume. +; This table contains volume specific information. +; +; Nearly all file system API refers to a single particular volume. +; The proper volume is determined when the file system is entered +; and the TDB structure contains a pointer to it. Most code ignores +; volumes and deals with 32 bit physical sector #'s. When we're about +; to interface with the device driver we then peek at the "global" +; volume value pointed to by TDB. +; +; There are two exceptions to this, where per-volume structures are +; pooled, the buffer pool and the OFT pool. In these two cases the +; sector number has the volume index set in it's high order VOLLSHIFT +; bits so that a single DWORD compare will qualify a sector on both +; a volume and sector basis. +; + +VOLTAB struc + VOL_FFLAG db ? ; Fault flags - checked on most calls + VOL_SFLAG db ? ; status flags + VOL_PAD dw ? ; unused - bugbug + VOL_SECVAL dd ? ; value to set on high order part of sector # + VOL_BCNT dw ? ; # of bitmap bands in this volume + VOL_VDBCnt dw ? ; count of outstanding VerifyDB calls *. + VOL_SDBcnt dd ? ; count of spare DIRBLKs left for volume, if + ; all are unused, else 0 + VOL_SBSEC dd ? ; SB_SEC value from superblock + VOL_DB db (size BANDTAB) dup (?) ; DIRBLK bandtab + VOL_ROOT dw ? ; Root SBDIR pointer + VOL_SPACE dd ? ; alloctable space limit + VOL_DBSIZE dd ? ; copy of SP_DBSIZE value + VOL_HFUSE dd ? ; # of hot fixes in effect + VOL_HFMAX dd ? + VOL_HFPTR dd ? ; address of hotfix heap array - bad sectors + VOL_HFNEW dd ? ; address of substitute list - replacement sectors + VOL_BPTR dw 1 dup (?) ; first of VOL_BCNT pointers + ; one per band. The BANDTABs that they + ; point to must be physically contiguous +VOLTAB ends + +; VOL_FFLAG fault flags +; +; these represent conditions that we're trying to repair, +; we check these on most major file system calls +; + +VF_NEEDHOT equ 01h ; hotfix list is partially used +VF_NEEDDIR equ 02h ; dirblk reserved list is partially used + +; VOL_SFLAG status flags +; + +VS_BADSEC equ 01h ; we have at least one bad sector on there |