/*static char *SCCSID = "@(#)sft.h      6.12 92/02/20";*/
/* XLATOFF */
#pragma title("Internal file table format")
/* XLATON  */


/*****  System File Table - SFT
 *
 *      As SFT is used by the system to store information about a file or
 *      device that has a handle mapped to it (the handle was obtained
 *      when an OPEN was done). Each open creates an SFT entry, also referred
 *      to as just SFT in the source. SFT entries are identified by SFN
 *      (system file number). SFNs are global; e.g. SFN 206 in process# 882
 *      refers to the same SFT entry as SFN 206 in process# 8080.
 *
 *****  Job File Number - JFN
 *
 *      A JFN is the same as the file handle returned by DOSOPEN. It is an
 *      index into a handle table pointed to by TaskArea:JFN_pTable. The
 *      content of the table is an SFN. A new handle is created with each
 *      open or dup. Each process has its own handle table, so handle 5 in
 *      one process may not refer to the same SFN as handle 5 in its child.
 *
 *****  Fake Handle
 *
 *      In protect mode: JFN_pTable[handle] = SFN
 *
 *      In 3xbox: PDB_JFN_Pointer[fake handle] = fake SFN = real handle
 *                JFN_pTable[real handle] = SFN
 *
 *      A fake handle is a user handle in the 3xbox. It is called a fake
 *      handle because its entry in the PDB handle table contains a fake
 *      SFN. This fake SFN is not an index into the SFT, but an index
 *      into the real handle table in the PTDA. A fake SFN is the same as
 *      a real handle. The w_ file system procedures only understand real
 *      handles (same as protect mode handles).
 *
 *      This extra level of indirection is required because the handle
 *      table in the PTDA is a word table (allows larger range of SFN)
 *      while the 3xbox handle table in the PDB is a byte table (to
 *      maintain compatibility with DOS 3).
 *
 *      If a 3xbox procedure (e.g. $read) wants to call a protect mode
 *      file system procedure (e.g. w_read), first it has to map the
 *      fake handle supplied by the user into a real handle. In some
 *      other procedures, the opposite has to be done (e.g. $open).
 */

/***    Structure of SFT segment
 *
 *      Large model array of SFT entries:
 *        GDT_SFT:[0] = gdt selector to first SFT segment, which contains
 *              entries 0 to SFNPERSEG-1
 *        GDT_SFT:[2] = gdt selector to second SFT segment, which contains
 *              entries SFNPERSEG to 2*SFNPERSEG-1
 *            ...
 *        GDT_SFT:[cAllSFN] = total number of SFT entries
 *
 *        All SFT segments except the last one contains SFNPERSEG sft
 *        entries. cAllSFN contains the total (free + used) number of sft
 *        entries in all the SFT segments. cAllSFN <= MAXSFN.
 *
 *      Structure of Free list:
 *          The start of the free list is SFT_FreeHead. The subsequent free
 *          sfts can be found by chasing down the sf_chain field. The last
 *          free sft contains 0 in sf_chain.
 *
 *      WARNING ** FCB SFTs are now marked by FCB bit set in sf_flags. **
 *              ** sfi_selfsfn now contains the sfn for FCB SFTs.      **
 *
 *
 ***    Structure of SFT
 *
 *      The SFT structure is divided into three parts to support IFSs
 *      (Installable File Systems):
 *
 *                  - A part private to the kernel that is used for
 *                    all types of file systems. This consists of 2
 *                    portions at both ends of the SFT for historical
 *                    reasons.
 *                  - A file system independent part. This is passed
 *                    to an IFS as part of certain FS calls.
 *                  - A file system dependent part. This is used by a
 *                    particular IFS as it likes, and is designated as
 *                    a "work area". This is also passed to the IFS as
 *                    part of certain FS calls.
 *
 *      Since the FAT file system is the default system, we also define
 *      the layout of the FAT file system work area below.
 *
 *   The layout of the SFT is as follows:
 *
 *      -----------------------------
 *      |   Private to Kernel       |
 *      |                           |
 *      |                           |
 *      |                           |
 *      -----------------------------
 *      |   File system dependent   |
 *      |                           |
 *      |         sf_fsd            |
 *      |                           |
 *      -----------------------------
 *      | File system independent   |
 *      |                           |
 *      |         sf_fsi            |
 *      |                           |
 *      -----------------------------
 *      |   Private to Kernel       |
 *      |                           |
 *      |                           |
 *      -----------------------------
 *
 *      The way that the various fields are accessed in the kernel depends
 *      on where they are in the SFT structure. It is possible to specify
 *      "fields into fields" using MASM as follows:
 *
 *      e.g. To access the field sfdFAT_cluspos, you would use something
 *           like
 *                  MOV     AX,ES:[DI].sf_fsd.sfdFAT_cluspos
 */

/**  RESIOSFN - number of reserved SFNs in IOSFN mapping
 *
 * bugbug 14-mar-88 peterwu - unknown purpose for RESIOSFN equ
 *   We know this is for reserving 16 SFNs at the high end of IOSFN, but
 *   nobody knows what they are for. This constant was originally named
 *   N_3XBOX_VIRTUAL_DEVICES.
 */

#define RESIOSFN              16

/**     MAXSFN is the maximum number of SFNs we allow GrowSFT to
 *      allocate. The reasons for not allowing 65536 are 1) reserve last one
 *      (65535) as invalid sfn, 2) forced by IOSFN mapping to reduce by
 *      another (RESIOSFN-1 + 256 + 256).
 *
 * bugbug 27-Jan-88 peterwu - masm 16-bit arithmatic limitation
 *      We actually want to say 65536-256-256-N, but masm won't let us
 *      (unless we bracket it with .386p and .286p, which triggers masm
 *      bugs -- assembly errors all over the place), so we have to say
 *      65535-256-256-N+1. Fix this when we have a working masm.
 */

#define MAXSFN          (65535L - 256 - 256 - RESIOSFN + 1)

#define SFN_NULL          (-1)          /* Distinguished SFN value, used to */
                                        /* mark end of free chain, non-set */
                                        /* JFN entries, etc. */

#define SFN_BUSY          (-2)          /* Distinguished "SFN" value, used */
                                        /* to indicate in a JFN entry that */
                                        /* the JFN has been allocated, but */
                                        /* the SFT entry is not completely */
                                        /* initialized yet.                */
                                        /* Added for defect 72417 since we */
                                        /* no longer serialize the open    */
                                        /* sequence and we don't want JFNs */
                                        /* allocated twice                 */

/**     MAXJFN is the maximum number of JFNs (handles) that any one process
 *      can have at once. It is 32768 because one segment is allocated for
 *      each handle table and each entry is 2 bytes.
 */

#define MAXJFN          32768L


/**     MAX3XJFN is the number of real handles for each 3xbox. This should be
 *      fixed at 256 because that's the maximum range for a fake SFN (same as
 *      real handle) plus we want to use the last entry to map invalid fake
 *      handle into invalid fake SFN.
 */

#define MAX3XJFN        256


/**     SF_DEFAULT_NUMBER controls # of sf entries msinit initially allocates
 */

#define SF_DEFAULT_NUMBER         80


/**     SFTIncr controls the number of SFTs we add when we grow the table
 */

#define SFTINCR         8

#define SFNAMELEN       11            /* Length of name saved in SFT */

/**  Size of work area in the SFT file system dependent area
 *
 * NOTE: The spec states a certain size, but if it turns out that the FAT file
 *       system specific data requires more space than stated in the spec,
 *       we allocate more space in the structure and use ERRNZs to ensure
 *       that we don't make it smaller than what is in the spec AND smaller
 *       than that required for the FAT file system.
 *
 */
#define SPECSFDWORKAREASIZE       30          /* Work area size in spec */
#define SFDWORKAREASIZE           50         /* Size of file system dependent work area */
/* XLATOFF */
#if (SFDWORKAREASIZE < SPECSFDWORKAREASIZE)
#error  System area work area size < size in specification
#endif
/* XLATON */
/* ASM
.errnz        (not (SFDWORKAREASIZE ge SPECSFDWORKAREASIZE))
 */


/** File system independent area in the SFT
 *
 *  WARNING:  If this structure changes, be sure to propagate the changes to
 *            FSD.H (and be sure the spec is correct!).
 *
 */
typedef struct sftsfi { /*sfi*/
    ushort_t    sfi_mode;       /* mode of access (see FILEMODE.INC)
                                 * or high bit on if FCB */
    ushort_t    sfi_mode2;      /* additional openmode bits for DosOpen2 */
    ushort_t    sfi_hVPB ;      /* handle of volume */
    ushort_t    sfi_ctime;      /* Creation time of file */
    ushort_t    sfi_cdate;      /* Creation date of file */
    ushort_t    sfi_atime;      /* Time of last access of file */
    ushort_t    sfi_adate;      /* Date of last access of file */
    ushort_t    sfi_mtime;      /* Time of last modification of file */
    ushort_t    sfi_mdate;      /* Date of last modification of file */
    ulong_t     sfi_size ;      /* Size associated with file */
    ulong_t     sfi_position;   /* Read/Write pointer or LRU count for FCBs */

        /* SHARING information */
        /* The following three fields represent a unique ID for the sharer. */

    ushort_t    sfi_UID;        /* User ID */
    ushort_t    sfi_PID;        /* Process ID */
    ushort_t    sfi_PDB;        /* Process Data Block */
    ushort_t    sfi_selfsfn;    /* SFN of this sf_entry, used to speed */
                                /*      up free list management. */
    uchar_t     sfi_tstamp;     /* update time stamp flags; see ST_ equs */
    ushort_t    sfi_type;       /* file/device/named-pipe/FCB */
    ulong_t     pPVDBFil;       /* performance counter data block pointer */
    uchar_t     sfi_DOSattr;    /* DOS attributes of file(sys,hid,r/o,arch */
} sftsfi;


/** File system dependent area in the SFT */

typedef struct sftfsd { /*sfd*/
    uchar_t sfd_work [SFDWORKAREASIZE];
} sftfsd;


/** The following structure defines the file system dependent part of the
 *  SFT for the FAT file system. It is used by the internal FAT file system
 *  in the kernel.
 */
typedef struct sfdFATFS { /*sfdFAT*/
    ushort_t    sfdFAT_firFILEclus;     /* First cluster of file (bit 15 = 0) */
    /*
     * Starting here, the next 9 bytes may be used by the file system to
     * store an ID
     */
    ushort_t    sfdFAT_cluspos; /* Position of last cluster accessed */
    ushort_t    sfdFAT_lstclus; /* Last cluster accessed */
    ulong_t     sfdFAT_dirsec;  /* Sector # of directory sector for this file */
    uchar_t     sfdFAT_dirpos;  /* Offset of this entry in the above */
    /*
     * End of 9 bytes of file-system specific info.
     */
    ushort_t    sfdFAT_EAHandle;        /* starting cluster of EAs */
    uchar_t     sfdFAT_name[SFNAMELEN]; /* 11 character name that is in the */
                                        /* directory entry.  This is used by */
                                        /* close to detect file deleted and */
                                        /* disk changed errors. */
    ulong_t     sfdFAT_bRAReads;        /* # of consecutive reads within range */
    ulong_t     sfdFAT_bRABigReads;     /* # of consecutive big reads */
    ulong_t     sfdFAT_fldMask;         /* Unique File Dirty Mask */
    ulong_t     sfdFAT_pSFT;            /* Linear address of SFT */
    ulong_t     sfdFAT_ulNextRA;        /* Position where next rahead starts */
    ulong_t     sfdFAT_bBufRun;         /* Number of sectors in rahead run */
    ushort_t    sfdFAT_LastFATSec;      /* last FAT sector added to chain */
} sfdFATFS;

/*
 * The size of the file system dependent area reserved in the SFT should be AT
 * LEAST as big as the largest area that we will need. For now, we set it to be
 * at least as big as that used by the FAT file system - this may change.
 */
/* ASM
.errnz        (SFDWORKAREASIZE lt size sfdFATFS)
 */

/** Structure layout of the header in the System File Table segment(s)
 */
typedef struct SFT { /*sft*/
    ushort_t sft_link;          /* selector for next chunk of table */
                                /* (sft_link = 0 for end-of-table) */
    ushort_t sft_count;         /* number of entries in this block */
    ushort_t sft_handle;        /* handle of segment holding this block */
    ushort_t sft_inshutdown;    /* flags for shutdown */
} SFT;


/** Structure layout of the System File Table entry (SFT)
 *
 *  !!! NOTE:
 *
 *      Some people (LANMAN) rely on sf_fsd and sf_fsi being at particular
 *      offsets within this structures. Since this situation won't be
 *      fixed, any new fields have to be added at the END of the structure.
 *      This also means that sf_flags cannot be aligned!
 */
typedef struct sf_entry { /*sf*/
    ushort_t sf_ref_count;      /* number of processes sharing entry */
                                /*   if FCB then ref count */
    ushort_t sf_usercnt;        /* For files: number of threads waiting
                                   for access to sf_entry.

                                   For devices: number of threads using
                                   this sf_entry. */
    uchar_t  reserved;          /* Used to be attr of file - moved to
                                 * independent part of the SFT for general
                                 * access
                                 */
    ushort_t sf_flags;          /* Bits 8-15
                                 *  Bit 15 = 1 if remote file
                                 *         = 0 if local file or device
                                 *  Bit 14 = not used
                                 *  Bit 13 = Pipe bit
                                 *  Bit 12 = FCB bit
                                 *         = 1 if fcb sft
                                 *         = 0 if normal sft
                                 *  Bit 11 = if Pipe,
                                 *         = 0 if anonymous pipe
                                 *         = 1 if named pipe
                                 *  Bit 10 == sf_inuse = sf_entry is in
                                 *            use by some thread, ie busy
                                 *  Bit  9 == sf_want = some thrd blocked
                                 *            waiting to use the sf_entry
                                 *  Bit  8 == sf_noJFN, no handle alloced
                                 *            for sft
                                 *  Bits 0-7 (old FCB_devid bits)
                                 *  If remote file or local file, bit
                                 *  6=0 if dirty Device ID number, bits
                                 *  0-5 if local file.
                                 *  bit 7=0 for local file
                                 *       =1 for local I/O device
                                 *  If local I/O device, bit 6=0 if EOF (input)
                                 *            Bit 5=1 if Raw mode
                                 *            Bit 0=1 if console input device
                                 *            Bit 1=1 if console output device
                                 *            Bit 2=1 if null device
                                 *            Bit 3=1 if clock device
                                 */

    ushort_t sf_flags2;
    /* *** NOTE  virtual address of sf_flags2 is being used as the block id,
     *           in conjunction with the binary semaphore in BIT 13.
     *                              Bit 15   = sf_format_mount indicates
     *                                         that a format_mount was done
     *                              Bit 14   = sf_beginformat_failed
     *                                         indicates that a beginformat
     *                                         failed, and this SFT is not
     *                                         usable (except for close)
     *                              Bit 13   = is used as a binary semaphore
     *                                         for getting exclusive access
     *                                         to the SFT from the loader
     *                              Bit 12   = serving pipe redir in effect
     *                              Bit 11   = drive locked, DASD open
     *                              Bit 10   = indicates spooled file
     *                              Bit  9   = Data-written-to-file flag
     *                              Bits 7-8 = Consistency parameters
     *                              Bit  6   = Spool job canceled           ;whs
     *                              Bit  5   = Non-spooled sent to printer  ;whs
     *                              Bit  4   = is  unused
     *                              Bit  3   = Read-Ahead started for this file
     *                              Bit  2   = SFT is for a UNC obj. we
     *                                         don't add UNC objects to sharer
     *                              Bit  1   = SFT is on the free list
     *                              Bit  0   = Doing Large readahead for file
     */

    ulong_t sf_devptr;          /* Not used if local file, points */
                                /* to device header if local device, */
                                /* points to net device header if remote */
    ulong_t sf_FSC;             /* Pointer to the file system control */
                                /* block (FSC). */
    ulong_t sf_cookie;          /* server's per-file id (for oplock support) */
    /* SHARING INFO */
    ulong_t sf_chain;           /* 16:16 Link to next SFT */
                                /* Used for both sharing and free list */
    ulong_t sf_MFT;             /* 32 bit FLAT pointer to MFT entry */

    /* Fields used for file system dependent work */
    sftfsd sf_fsd;

    /* Fields used for file system independent work */
    sftsfi sf_fsi;

    /* Fields used for spooling */
    ushort_t sf_plock;          /* 16 bit offset to first pending LOCK record */
    ushort_t sf_NmPipeSfn;      /* SFN of named pipe for spooled files */
    ushort_t sf_codepage;       /* current codepage (font) for data in file */

    /* Fields used for protected file-handle access */
    ulong_t sf_LockID;      /* lock-id for protected file-handle access */

} sf_entry;

/* ASM
.errnz        (sf_fsd - sf_MFT - (size sf_MFT))
.errnz        (sf_fsd - sf_ref_count - 29)
 */

/**      MAXSFNPERSEG is the maximum number of SFT entries that fit in a 64K
 *       segment. It is not used by any procedure, but for verifying that
 *       SFNPERSEG does not exceed MAXSFNPERSEG.
 * bugbug 7-Jan-88 peterwu - assembler 16 bit arithmatic limitation
 * What we really want is MAXSFNPERSEG = 65536/(size sf_entry)
 */

/* XLATEOFF */
#define MAXSFNPERSEG ((65535L - (sizeof(SFT)))/(sizeof(sf_entry)))
#define SFNPERSEG ((65535L - (sizeof(SFT)))/(sizeof(sf_entry)))
/* XLATEON */
/* ASM
MAXSFNPERSEG    EQU ((65535 - (size SFT)) / (size sf_entry))
SFNPERSEG       EQU ((65535 - (size SFT)) / (size sf_entry))
 */

/** SFNPERSEG is the actual number of SFT entries we allocate per SFT
 *       segment. It is chosen to be a power of 2 so we can optimize
 *       SFFromSFN to use shift instead of division. If you change SFNPERSEG,
 *       be sure to fix SFFromSFN (it contains hard-coded shift count).
 */
/** Changed SFFromSFN to use division instead of shift in order to
 * grow the sf_entry to support file handle lockID's.
 * F. Miro' 9/1/92
 */

/* ASM
        .erre   SFNPERSEG le MAXSFNPERSEG       ; sanity check
 */

/* sizeGDTSFT is the number of bytes to allocate for GDT_SFT segment.
 *
 * bugbug 3 feb 88 peterwu - masm 16-bit arithmetic limitation
 * we want sizeIndex = (MAXSFN+SFNPERSEG-1)/SFNPERSEG, but this will
 * cause overflow if MAXSFN+SFNPERSEG > 65535.
 */

/* #define SFNPERSEG    512 */

/* ASM
sizeGDTSFT = MAXSFN / SFNPERSEG
;IF     (MAXSFN MOD SFNPERSEG) gt 0  ; commented out for protected filehandle work
  sizeGDTSFT = sizeGDTSFT + 1
;ENDIF                             ; commented out for protected filehandle work
sizeGDTSFT = (sizeGDTSFT * 2)+2         ; adjust for word size
 */

/* XLATOFF */
// #if   ( MAXSFN % SFNPERSEG ) > 0
    #define sizeGDTSFT ((((MAXSFN / SFNPERSEG) + 1)*2)+2)
//#else
//    #define sizeGDTSFT (((MAXSFN / SFNPERSEG )*2)+2)
//#endif
/* XLATON */

/* GDT_SFT:[cAllSFN] contains the total number of SFT entries (used + free)
 * it is stored at the very end of GDT_SFT segment after all the SFT segment
 * selectors.
 */

#define CALLSFN (sizeGDTSFT-2)      /* put cAllSFN at end of GDT_SFT segment */

/** FCB support
 *
 *  Used by the system to set up SFTs from FCBs
 */
/* ASM

sf_OpenAge            EQU WORD PTR (sf_fsi + sfi_position+2)
sf_LRU                EQU WORD PTR (sf_fsi + sfi_position)

 */



/**** These are the flag bits that refer to the sf_flags field in the SFT
 *
 * BUGBUG We should really change the names to be more meaningful and uniform
 *        rajens - Oct 14, 1987
 *
 ** mode mask for FCB detection
 *  See filemode.inc for other values.
 */

#define SF_ISNET                0x8000  /* True if SFT is for remote */

#define SF_PIPE                 0x2000  /* Reserved */
#define SF_FCB                  0x1000  /* True if SFT is for an FCB */
#define SF_NMPIPE               0x0800  /* true if name pipe */
#define SF_INUSE                0x0400  /* True if sf entry is in use by some */
                                        /* thread, i.e. busy */
#define SF_BLOCKED              0x0200  /* True if some thread is blocked waiting */
                                        /* to use the sf entry */
#define SF_NOJFN                0x0100  /* True if no handle alloc'ed for SFT */


/**** These are the flag bits that refer to the sf_flags2 field in the SFT
 *
 */

#define SF_FORMAT_MOUNT         0x8000  /* True if a format mount was done,
                                         * and still in effect */
#define SF_BEGINFORMAT_FAILED   0x4000  /* True if a beginformat ioctl failed */
                                        /* See DEVIOCTL.ASM, SFFromSFN, & */
                                        /* w_Close */
#define SSF2_LDRBINARYSEM       0x2000  /* 'ON' if SFT owned by some thread */
#define SF_SRVRDR               0x1000  /* serving pipe redirection in effect */
#define SFF2_LOCKED_DRIVE       0x0800  /* A LOCK was issued on this direct */
                                        /* access handle to lock the drive. */
#define SFF2_SPOOLED            0x0400  /* File is spooled */
#define SFF2_DATAWRITTEN        0x0200  /* Data written to file */
#define SFF2_Consistency        0x0180  /* consistency bits */
#define SFF2_CANCELJOB          0x0040  /* spool job has been canceled*/  ;whs
#define SFF2_NONSPOOLED         0x0020  /* File is nonspooled; going to printer */
#define SFF2_STPTHINFDN         0x0010  /* SetPathInfo done, don't set archive */
#define sff2_RA_ON              0x0008  /* Readahead started */
#define sff2_UNC                0x0004  /* UNC object */
#define sff2_isfree             0x0002  /* this SFT is on free list (unused) */
#define sff2_RA_BIG             0x0001  /* Big Readahead */


/* flags for sfi_type */

#define STYPE_FILE      0x0000          /* file */
#define STYPE_DEVICE    0x0001          /* device */
#define STYPE_NMPIPE    0x0002          /* named pipe */
#define STYPE_FCB       0x0004          /* SFT is for an FCB */
#define STYPE_USED      (STYPE_FILE | STYPE_DEVICE | STYPE_NMPIPE | STYPE_FCB)
#define STYPE_RESERVED  (~ STYPE_USED)  /* Reserved bits */
#define STYPE_MASK      (STYPE_FILE | STYPE_DEVICE | STYPE_NMPIPE)

/* Local file/device flag masks
 */
#define DEVID_FILE_CLEAN        0x0040  /* true if file and not written */
#define DEVID_FILE_MASK_DRIVE   0x003F  /* mask for drive number */
#define DEVID_DEVICE            0x0080  /* true if a device */
#define DEVID_DEVICE_EOF        0x0040  /* true if end of file reached */
#define DEVID_DEVICE_RAW        0x0020  /* true if in raw mode */
#define DEVID_DEVICE_SPECIAL    0x0010  /* true if special device */
#define DEVID_DEVICE_CLOCK      0x0008  /* true if clock device */
#define DEVID_DEVICE_NULL       0x0004  /* true if null device */
#define DEVID_DEVICE_CON_OUT    0x0002  /* true if console output */
#define DEVID_DEVICE_CON_IN     0x0001  /* true if console input */


/***
 * structure of devid field as returned by IOCTL is:
 *
 *       BIT     7   6   5   4   3   2   1   0
 *             |---|---|---|---|---|---|---|---|
 *             | I | E | R | S | I | I | I | I |
 *             | S | O | A | P | S | S | S | S |
 *             | D | F | W | E | C | N | C | C |
 *             | E |   |   | C | L | U | O | I |
 *             | V |   |   | L | K | L | T | N |
 *             |---|---|---|---|---|---|---|---|
 *       ISDEV = 1 if this channel is a device
 *             = 0 if this channel is a disk file
 *
 *       If ISDEV = 1
 *
 *             EOF = 0 if End Of File on input
 *             RAW = 1 if this device is in Raw mode
 *                 = 0 if this device is cooked
 *             ISCLK = 1 if this device is the clock device
 *             ISNUL = 1 if this device is the null device
 *             ISCOT = 1 if this device is the console output
 *             ISCIN = 1 if this device is the console input
 *
 *       If ISDEV = 0
 *             EOF = 0 if channel has been written
 *             Bits 0-5  are  the  block  device  number  for
 *                 the channel (0 = A, 1 = B, ...)
 */
#define DEVID_ISDEV             0x80
#define DEVID_EOF               0x40
#define DEVID_RAW               0x20
#define DEVID_SPECIAL           0x10
#define DEVID_ISCLK             0x08
#define DEVID_ISNUL             0x04
#define DEVID_ISCOT             0x02
#define DEVID_ISCIN             0x01

#define DEVID_BLOCK_DEV         0x1F    /* mask for block device number */


/**      bit definitions for per-file-descriptor flags stored in JFN_Flags
 */

#define JFN_DIH         0x01    /* don't inherit */
#define JFN_FLUSH       0x02    /* DosResetBuffer called, always flush */
#define JFN_FAIL        0x40    /* don't generate hard errors */
#define JFN_WRTTHR      0x80    /* don't return from write till on disk */
#define JFN_NCACHE      0x20    /* don't cache data */
#define JFN_RAWIO       0x10    /* for CON only - if set, raw IO  */
#define JFN_ISCON       0x08    /* this handle is for CONsole */

#define JFN_USED        (JFN_DIH | JFN_FAIL | JFN_WRTTHR | JFN_NCACHE )

/** Constant to represent no MFT entry
 *
 *  Must be invalid MFT value
 */

#define SF_MFT_NULL     0xFFFFFFFF


/**      Flags for sfi_tstamp field. These values are used in combination.
 *       If ST_SWRITE is cleared and ST_PWRITE is set, then SetSFTTimes
 *       will not time stamp the last write field but will propagate the
 *       value that's already in it (useful for FileTimes).
 *       When DOS_Write has successfully written something to
 *       a file, it sets both ST_SWRITE and ST_PWRITE to tell the kernel
 *       to stamp and propagate the last write time (sfi_mtime/date) when
 *       that file is being closed or commited. DOS_Commit simply copies
 *       sfi_mtime/date, which are already stamped by the kernel, into the
 *       disk directory entry.
 */

#define ST_SCREAT       0x01    /* stamp creation time */
#define ST_PCREAT       0x02    /* propagate creation time */
#define ST_SWRITE       0x04    /* stamp last write time */
#define ST_PWRITE       0x08    /* propagate last write time */
#define ST_SREAD        0x10    /* stamp last read time */
#define ST_PREAD        0x20    /* propagate last read time */

/*       Flags for read-ahead */

#define MIN_READLEN        32   /* Must be < SECSIZE/2        */
#define MID_READLEN       512   /* SECSIZE                    */
#define MAX_READLEN      8192   /* BLOCK * 4                  */

