/*static char *SCCSID = "@(#)buffer.h   6.2 91/01/14";*/
/*      SCCSID = "@(#)buffer.h  6.2 91/01/14"
 *
 *      IBM/Microsoft Confidential
 *
 *      Copyright (c) IBM Corporation 1987, 1989
 *      Copyright (c) Microsoft Corporation 1987, 1989
 *
 *      All Rights Reserved
 *
 */

/*
 ***    NAME -- buffer.h
 *
 *  DESCRIPTION -- declaration/definition of buffer and other cache memory
 *
 *  QUESTIONS
 *
 *      Need to determine which segments will contain the buffer structures
 *      to decide whether the pointers are 'far' or 'near'.
 *
 *  HISTORY
 *      7/18/89 Initial Definition of BUF, BUF_LIST
 *      7/19/89 Added definitions of SECTOR, RAW_PATH_ISO,
 *          RAW_PATH_HSG, PATH_ENTRY, PATH_TABLE, RAW_DIR_REC,
 *          DIR_ENTRY, RAW_ISO_VTOC, RAW_HSG_VTOC
 *
 *      8/7/89  Added macros to account for differences in ISO/HSG
 *      8/22/89 Modified definition of RAW_PATH to give actual length for
 *              directory.  Needed because used a local raw path in
 *              RecoverPathTable.
 *              -- Brian Andrew
 *
 *      8/24/89 Added DirLen to DIR_ENTRY, length in bytes of this entry
 *              Modified attr, time/date fields to match DOS/OS2 format
 *              -- Brian Andrew
 *
 *      11/16/89    Added MOUNT_PARAMS structure.  Used at mount time
 *              for local parameters in VolMount and RecoverPathTable.
 *
 *      11/16/89    Added FFRST_PARAMS structure.  Used to store the
 *              local variables for FS_FINDFIRST to reduce stack usage.
 *
 *      11/30/89    Added constant RAW_DIR_SIZE for the size of a raw
 *              directory entry without the ID string.
 *
 *      12/14/89    Added 'usVerLen' field to DIR_ENTRY.
 *
 *      3/23/90     Added additional types to deal with pointers to
 *              structures.
 *
 *      4/8/90      Added definition of STRING_BUF and PSTRING_BUF.
 *
 *      4/9/90      Added definition of LIST_SEM_BLK.  Added LIST_SEM_BLK
 *                  blocks to VOL_DEP_DATA.  Added fields to BUF_LIST/
 *                  PATH_TABLE to support semaphore access into lists.
 *
 *      4/19/90     Put pointers to LIST_SEM_BLK in VOL_DEP_DATA instead
 *                  of imbedding them in the VOL_DEP_DATA structure.
 *
 *      5/1/90      Removed deRootDir field from VolDesc structure.
 *
 *      9/26/92     Frank Schroeder.  Added Copyright, Abstract, and
 *                  Bibliographic filenames to VOL_DESC structure. Added
 *                  MSCDEX_DIR_REC structure.
 *
 *      1/19/94     Doug Barra - @DB65536 - Added new field to Search_Dep_Data
 *                  to facilitate restarting searches in FS_FINDFROMNAME
 *      3/09/96     Steve Pratt - add new file dep data for cd readahead
 */

/* ISO vs. May 28th Draft
 *
 * The major differences are:
 *              - Path table entry
 *                      r_XAR_len, r_len_di, and r_loc_dir rearranged
 *              - Directory Record entry
 *                      File flags moved
 *              - VTOC
 *                      Substantial rearrangement
 *
 * The way we get around this is access to the changed fields in the
 * path table and directory record entries is done through a macro which
 * looks at the drive to see which kind of disc is being used and extract
 * values from the appropriate offset.
 * For the vtoc, we have two structures which define the raw vtoc structure -
 * one May 28th, one ISO. Depending on what was read, we use one or the
 * other as the template to copy the fields from.
 */

/*
 ***
 *  SECTOR (s)
 *
 *      This is a block of memory, corresponding to the logical size
 *      of the sectors on the disk.
 */

typedef UCHAR FAR *SECTOR;


/*
 *  LIST_SEM_BLK, PLIST_SEM_BLK, PPLIST_SEM_BLK (lsb, plsb, pplsb)
 *
 *      This structure is used to implement the readers/writers protection
 *      model for access into sector cache.
 *
 *      sBlockSem           --  Semaphore to control access to this block.
 *      sListSem            --  Semaphore to control access to sector list.
 *      usCountRead         --  Number of active readers.
 *      usCountWrite        --  Total number of waiting/active writers.
 */

typedef struct
{
        SEM     sBlockSem;
        SEM     sListSem;
        USHORT  usCountRead;
        USHORT  usCountWrite;

} LIST_SEM_BLK, FAR *PLIST_SEM_BLK, FAR * FAR *PPLIST_SEM_BLK;

/*
 ***
 *  BUF_LIST PBUF_LIST PPBUF_LIST (bl, pbl, ppbl)
 *
 *      This structure is part of a list of BUF_LISTs, each of which
 *      points to a sector from the CDROM, cached in memory.
 *
 *      Each volume maintained by the FSD will have 1 of these contained
 *      in the volume descriptor.
 *
 *      snSectNum   = Sector number of data.
 *      pbBuf       = Pointer to a BUF structure (BUF not declared yet).
 *      pblPrev     = Pointer to previous BUF_LIST on list.
 *      pblNext     = Pointer to next BUF_LIST on list.
 *      plsbSemBlk  = Pointer to semaphore block for this structure.
 *      pblNextHdr  = Pointer to next header added during disk reads.
 *      usCountPend = Number of readers waiting for a disk read.
 *      sHeaderSem  = Semaphore controlling access into header.
 */

typedef struct BUF_LIST
{
        SECT_NUM            snSectNum;
        VOID            FAR *pbBuf;
        struct BUF_LIST FAR *pblPrev;
        struct BUF_LIST FAR *pblNext;
        PLIST_SEM_BLK       plsbSemBlk;
        struct BUF_LIST FAR *pblNextHdr;
        USHORT              usCountPend;
        SEM                 sHeaderSem;

} BUF_LIST, FAR *PBUF_LIST, FAR * FAR *PPBUF_LIST;


/*
 ***
 *  BUF PBUF PPBUF (b, pb, ppb)
 *
 *      This structure actually accesses the sector in memory.
 *      It contains a pointer to whatever volume/path table is
 *      accessing this sector.  It also contains flags indicating
 *      how is the sector used, which indicates when it can be
 *      forcibly recovered, and what the current status is
 *      (locked, in use or free).
 *
 *      pblBufOwner = Pointer to structure which owns this BUF.
 *                      (May be cast to a PATH_TABLE if necessary).
 *      fBLOwns     = Is a BUF_LIST the owner.
 *      csUsers     = How many operations are reading this sector now.
 *      sSector     = Pointer to start of sector data.
 *      pbPrevBUF   = Pointer to previous buffer in memory pool.
 *      pbNextBUF   = Pointer to next buffer in memory pool.
 *
 */


typedef struct BUF
{
        PBUF_LIST           pblBufOwner;
        BOOL                fBLOwns;
        SHORT               cUsers;
        SECTOR              sSector;
        struct BUF      FAR *pbPrevBUF;
        struct BUF      FAR *pbNextBUF;
} BUF, FAR *PBUF, FAR * FAR *PPBUF;


#define MAX_SYS_USE 220                   /* size of system use area */

/*
 ***
 *  MSCDEX_DIR_REC PMSCDEX_DIR_REC PPMSCDEX_DIR_REC (mde, pmde, ppmde)
 *
 *      This structure is used to remove any ISO or HSG differences
 *      from their directory records.  This structure is used primarily
 *      when called from MSCDEX int 2f.
 *
 *      clbXARLen       = Length of XAR in LBN.
 *      lbFileLoc       = LBN of file start.
 *      uslbsize        = Logical block size of disc.
 *      cbFileIDLen     = Length of file.
 *      abRecordTime[7] = Date and Time.
 *      afFlags         = 8 flags.
 *      clbIntLeaveSize = Interleave size.
 *      clbIntLeaveSkip = Interleave skip factor.
 *      vsnVSSN         = Volume set sequence number.
 *      sFileID[38]     = Length of the file name.
 *      usFileVer       = Version number of file.
 *      ucLenSU         = Length of valid system use bytes.
 *      ucsu_data[220]  = Up to 220 bytes of system use data.
 */

typedef struct MSCDEX_DIR_REC
{
        UCHAR       clbXARLen;
        LOGICAL_BLK lbFileLoc;
        USHORT      uslbsize;
        ULONG       cbDataLen;
        UCHAR       abRecordTime[7];
        UCHAR       afFlags;
        UCHAR       clbIntLeaveSize;
        UCHAR       clbIntLeaveSkip;
        VOL_SEQ_NUM vsnVSSN;
        UCHAR       cbFileIDLen;
        UCHAR       sFileID[MAX_FILE_ID_LEN];
        USHORT      usFileVer;
        UCHAR       ucLenSU;
        UCHAR       ucsu_data[MAX_SYS_USE];
} MSCDEX_DIR_REC, FAR *PMSCDEX_DIR_REC, FAR * FAR *PPMSCDEX_DIR_REC;

/* Take the size of the structure including all fields except ucsu_data */
#define MSCDEX_DIR_LEN  (sizeof (MSCDEX_DIR_REC) - MAX_SYS_USE)

/*
 ***
 *  RAW_DIR_REC PRAW_DIR_REC PPRAW_DIR_REC (rde, prde, pprde)
 *
 *      This structure is used to overlay a region of a disk sector
 *      to retrieve a single directory entry.  There is a difference
 *      in the file flags between the ISO and HSG version and a
 *      additional byte in the ISO for the offset from Greenwich time.
 *
 *      cbDirLen        = Length of this directory entry.
 *      clbXARLen       = Length of XAR in LBN.
 *      lbFileLoc       = LBN of data Intel.
 *      lbFileLocMot    = LBN of data Molorola.
 *      cbDataLen       = Length of file Intel.
 *      cbDataLenMot    = Length of file Motorola.
 *      abRecordTime    = Date and time.
 *      afFlagsHSG      = 8 flags.
 *      afFlagsISO      = 8 flags.
 *      clbIntLeaveSize = Interleave size in logical blocks.
 *      clbIntLeaveSkip = Interleave skip factor in logical blocks.
 *      vsnVSSN         = Volume set sequence number Intel.
 *      vsnVSSNMot      = Volume set sequence number Motorola.
 *      cbFileIDLen     = Length of name.
 *      sFileID         = Variable length name upto 32 chars.
 */

typedef struct RAW_DIR_REC
{
        UCHAR       cbDirLen;
        UCHAR       clbXARLen;
        LOGICAL_BLK lbFileLoc;
        LOGICAL_BLK lbFileLocMot;
        ULONG       cbDataLen;
        ULONG       cbDataLenMot;
        UCHAR       abRecordTime[6];
        UCHAR       afFlagsHSG;
        UCHAR       afFlagsISO;
        UCHAR       clbIntLeaveSize;
        UCHAR       clbIntLeaveSkip;
        VOL_SEQ_NUM vsnVSSN;
        VOL_SEQ_NUM vsnVSSNMot;
        UCHAR       cbFileIDLen;
        UCHAR       sFileID[MAX_FILE_ID_LEN];
} RAW_DIR_REC, FAR *PRAW_DIR_REC, FAR * FAR *PPRAW_DIR_REC;

/* Take the size of the structure including all fields except the ID */
#define RAW_DIR_LEN     (sizeof (RAW_DIR_REC) - MAX_FILE_ID_LEN)

/* r_file_flags_hsg is the offset from Greenwich mean time on ISO discs
 * r_file_flags_iso is a reserved field and 0 on May 28th discs
 */
#define R_FILE_FLAGS(iso, de) (iso ? de->afFlagsISO : de->afFlagsHSG)


/*
 ***
 *  DIR_ENTRY PDIR_ENTRY PPDIR_ENTRY (de, pde, ppde)
 *
 *      This structure is used to store the important data in
 *      a directory entry.  It also contains the sector and
 *      sector offset (needed to simplify finding the next
 *      directory record in the chain.
 *
 *      snLastSectorFile= Last sector for this file.
 *      snLastSectorDE  = Last sector for this directory.
 *      cbStartOffset   = Byte offset in file of first data byte.
 *      snSectNum       = Sector containing this directory.
 *      soSectOff       = Offset in sector of record start for this entry.
 *      rsnRecSeq       = For multi-extent, postion of this record (first 0).
 *      cbDirLen        = Length in bytes of this entry.
 *      clbXARLen       = Length of XAR in logical blocks.
 *      lbFileLoc       = LBN of data Intel.
 *      cbDataLen       = Length of file Intel.
 *      abDirDate       = Recording date.
 *      abDirTime       = Recording time.
 *      afFileAttr      = File attribute flags.
 *      fMultiExt       = Flag is TRUE if this is not last extent for file.
 *      cbFileSize      = Size of file in bytes.
 *      clbIntLeaveSize = Interleave size.
 *      clbIntLeaveSkip = Interleave skip factor.
 *      vsnVSSN         = Volume sequence number.
 *      cbFileIDLen     = Length of name.
 *      szFileID        = Variable length name upto 32 chars.
 *      sFileVer        = Binary version from file.ext;version.
 *      sRecentVer      = Most recent version of this file name.
 *      cbVerLen        = Number of digits in the version number.
 */

typedef struct DIR_ENTRY
{
        SECT_NUM    snLastSectorFile;
        SECT_NUM    snLastSectorDE;
        ULONG       cbStartOffset;
        SECT_NUM    snSectNum;
        SECT_OFFSET soSectOff;
        REC_SEQ_NUM rsnRecSeq;
        USHORT      cbDirLen;
        UCHAR       clbXARLen;
        LOGICAL_BLK lbFileLoc;
        ULONG       cbDataLen;
        USHORT      abDirDate;
        USHORT      abDirTime;
        USHORT      afFileAttr;
        BOOL        fMultiExt;
        ULONG       cbFileSize;
        UCHAR       clbIntLeaveSize;
        UCHAR       clbIntLeaveSkip;
        VOL_SEQ_NUM vsnVSSN;
        USHORT      cbFileIDLen;
        UCHAR       szFileID[MAX_FILE_ID_LEN];
        SHORT       sFileVer;
        SHORT       sRecentVer;
        USHORT      cbVerLen;
} DIR_ENTRY, FAR *PDIR_ENTRY, FAR * FAR *PPDIR_ENTRY;


/*
 ***
 *  RAW_PATH_ISO PRAW_PATH_ISO PPRAW_PATH_ISO (rpi, prpi, pprpi)
 *  RAW_PATH_HSG PRAW_PATH_HSG PPRAW_PATH_HSG (rph, prph, pprph)
 *
 *      The following structures can be used to overlay Path Table
 *      entries in memory.  The fields are slighted reordered.
 *
 *      cbLenDirID  = Length in bytes of directory ID (without NULL
 *                      terminator.
 *      clbXARLen   = Length in logical blocks of XAR associated with
 *                      directory.
 *      lbDirLoc    = LBN of start of directory.
 *      pnParentNum = Parent directory ID number.
 *      sDirID      = Start of id string (or 00 byte for root).
 *
 */

typedef struct RAW_PATH_ISO
{
        UCHAR       cbLenDirID;
        UCHAR       clbXARLen;
        LOGICAL_BLK lbLocDir;
        PATH_NUMBER pnParentNum;
        UCHAR       sDirID[MAX_DIRID_LEN + 1];
} RAW_PATH_ISO, FAR *PRAW_PATH_ISO, FAR * FAR *PPRAW_PATH_ISO;

typedef struct RAW_PATH_HSG
{
        LOGICAL_BLK lbLocDir;
        UCHAR       clbXARLen;
        UCHAR       cbLenDirID;
        PATH_NUMBER pnParentNum;
        UCHAR       sDirID[MAX_DIRID_LEN + 1];
} RAW_PATH_HSG, FAR *PRAW_PATH_HSG, FAR * FAR *PPRAW_PATH_HSG;


#define R_LEN_DI(iso, rp) (iso ? rp->cbLenDirID  : \
                                                  ((PRAW_PATH_HSG) rp)->cbLenDirID)
#define R_XAR_LEN(iso, rp) (iso ? rp->clbXARLen : \
                                                   ((PRAW_PATH_HSG) rp)->clbXARLen)
#define R_LOC_DIR(iso, rp) (iso ? rp->lbLocDir : \
                                                   ((PRAW_PATH_HSG) rp)->lbLocDir)


/*
 ***
 *  PATH_ENTRY PPATH_ENTRY PPPATH_ENTRY (pe, ppe, pppe)
 *
 *      This structure stores the key entries in a Path Table record.
 *      It is also used to permanently store a path table entry which
 *      straddles a sector.
 *
 *      lbLocDir        = LBN of first logical block in the directory.
 *      clbXAR_Len      = XAR record length in logical blocks.
 *      pnParentDirNum  = Number in Path Table for parent directory.
 *      sDirID          = Identifier for this directory.
 *      pdeDirEntry     = Pointer to DirEntry for current directory.
 *
 */

typedef struct PATH_ENTRY
{
        LOGICAL_BLK     lbLocDir;
        UCHAR           clbXAR_Len;
        PATH_NUMBER     pnParentNum;
        PATH_NUMBER     pnThisEntry;
        PDIR_ENTRY      pdeDirEntry;
        UCHAR           sDirID[MAX_DIRID_LEN + 1];

} PATH_ENTRY, FAR * PPATH_ENTRY, FAR * FAR *PPPATH_ENTRY;


/*
 ***
 *  PATH_TABLE PPATH_TABLE PPPATH_TABLE (pt, ppt, pppt)
 *
 *      This structure contains the information needed to reference
 *      a sector containing a Path Table.  It also provides pointers
 *      for the previous and next sectors in the path table.
 *
 *      NOTE: if the FSD needs to pre-empt the sector containing
 *      the sector data, the pointer to that data will be NULL.
 *
 *      snSectNum   = The sector number this PTS_ENTRY refers to. It's
 *                      used to compare with the sector number in the
 *                      buffer we point to to see if the buffer has
 *                      been preempted and we need to reread the path
 *                      sector in again.
 *
 *      pbBuf       = Points to the buffer with the data for this path sector.
 *
 *      pptPrevPTSect = Pointer to the previous path table sector.
 *
 *      pptNextPTSect = Pointer to the next path table sector.
 *
 *      plsbSemBlk  = Pointer to semaphore block for this structure.
 *
 *      pblNextHdr  = Pointer to next header added during disk reads.
 *
 *      usCountPend = Number of readers waiting for a disk read.
 *
 *      sHeaderSem  = Semaphore controlling access into header.
 *
 *      soPTOffset1 = The offset into the sector for that path table
 *                      sector that the first path entry begins at.
 *                      In the first sector, the offset is 0 but
 *                      since entries may straddle sector boundaries,
 *                      we keep around this offset to point to just after
 *                      where the straddling entry ends.
 *
 *      pnDirNum1   = The directory number of the first whole path entry
 *                      in this sector. Whatever piece that straddles
 *                      the beginning of the sector is handled in the
 *                      previous sector.
 *
 *      pnDirNum2   = The directory number of the last path entry in
 *                      this sector, which may or may not straddle
 *                      the sector boundary.  There are thus
 *                      UsDirNum2 - usDirNum1 + 1 directories in this
 *                      sector.
 *
 *      pePathEntry = Saves the last path table entry in the sector
 *                      so that we don't need to worry about entries
 *                      straddling sector boundaries when scanning the
 *                      path table, we can use this one.
 *
 */

typedef struct PATH_TABLE
{
        SECT_NUM                snSectNum;
        PBUF                    pbBuf;
        struct PATH_TABLE   FAR *pptPrevPTSect;
        struct PATH_TABLE   FAR *pptNextPTSect;
        PLIST_SEM_BLK           plsbSemBlk;
        struct BUF_LIST     FAR *pblNextHdr;
        USHORT                  usCountPend;
        SEM                     sHeaderSem;
        SECT_OFFSET             soPTOffset1;
        PATH_NUMBER             pnDirNum1;
        PATH_NUMBER             pnDirNum2;
        PATH_ENTRY              pePathEntry;
} PATH_TABLE, FAR * PPATH_TABLE, FAR * FAR *PPPATH_TABLE;


/*
 ***
 *  RAW_ISO_VTOC PRAW_ISO_VTOC (riv, priv)
 *  RAW_HSG_VTOC PRAW_HSG_VTOC (rhv, prhv)
 *
 *      There is a substantial rearrangement of the fields between
 *      the ISO and HSG volume descriptors.  The data is read in
 *      by overlaying one of these structures over a sector and
 *      then copying the data into a common structure for
 *      the data not contained in the vpfsi structure maintained
 *      by the system.
 *
 *      These are drawn directly from the MSCDEX code.
 *
 */
typedef struct RAW_ISO_VTOC
{
        UCHAR   ri_desc_type;   /* volume type: 1 = standard, 2 = coded     */
        UCHAR   ri_std_id[5];   /* volume structure standard id = CDROM     */
        UCHAR   ri_version;     /* volume structure version number = 1      */
        UCHAR   ri_vol_flags;   /* volume flags                             */
        UCHAR   ri_sys_id[32];  /* system identifier                        */
        UCHAR   ri_vol_id[32];  /* volume identifier                        */
        UCHAR   ri_res2[8];     /* reserved 8 = 0                           */
        ULONG   ri_vol_spaceI;  /* size of the volume in LBN's Intel        */
        ULONG   ri_vol_spaceM;  /* size of the volume in LBN's Motorola     */
        UCHAR   ri_charset[32]; /* character set bytes 0 = ASCII            */
        USHORT  ri_vs_sizeI;    /* volume set size Intel                    */
        USHORT  ri_vs_sizeM;    /* volume set size Motorola                 */
        USHORT  ri_vs_snumI;    /* volume set sequence number Intel         */
        USHORT  ri_vs_snumM;    /* volume set sequence number Motorola      */
        USHORT  ri_lb_sizeI;    /* logical block size Intel                 */
        USHORT  ri_lb_sizeM;    /* logical block size Motorola              */
        ULONG   ri_path_sizeI;  /* path table size in bytes Intel           */
        ULONG   ri_path_sizeM;  /* path table size in bytes Motorola        */
        ULONG   ri_path_locI[2];/* LBN of 4 path tables Intel               */
        ULONG   ri_path_locM[2];/* LBN of 4 path tables Motorola            */
        UCHAR   ri_root_de[LEN_ROOT_DE];/* dir entry of the root directory  */
        UCHAR   ri_vs_id[128];  /* volume set identifier                    */
        UCHAR   ri_pub_id[128]; /* publisher identifier                     */
        UCHAR   ri_prep_id[128];/* data preparer identifier                 */
        UCHAR   ri_app_id[128]; /* application identifier                   */
        UCHAR   ri_cpyr_id[37]; /* file name of copyright notice            */
        UCHAR   ri_abst_id[37]; /* file name of abstract                    */
        UCHAR   ri_bibl_id[37]; /* file name of bibliography                */
        UCHAR   ri_creat[17];   /* volume creation date and time            */
        UCHAR   ri_mod[17];     /* volume modification date and time        */
        UCHAR   ri_exp[17];     /* volume expiration date and time          */
        UCHAR   ri_eff[17];     /* volume effective date and time           */
        UCHAR   ri_fs_version;  /* file structure version number            */
        UCHAR   ri_res3;        /* reserved 3                               */
        UCHAR   ri_res_app[512];/* reserved for application                 */
        UCHAR   ri_res4[653];   /* remainder of 2048 bytes reserved         */
} RAW_ISO_VTOC, FAR *PRAW_ISO_VTOC;

typedef struct RAW_HSG_VTOC {
        ULONG   rh_lbnI;        /* logical block number Intel               */
        ULONG   rh_lbnM;        /* logical block number Motorola            */
        UCHAR   rh_desc_type;   /* volume type: 1 = standard, 2 = coded     */
        UCHAR   rh_std_id[5];   /* volume structure standard id = CDROM     */
        UCHAR   rh_version;     /* volume structure version number = 1      */
        UCHAR   rh_vol_flags;   /* volume flags                             */
        UCHAR   rh_sys_id[32];  /* system identifier                        */
        UCHAR   rh_vol_id[32];  /* volume identifier                        */
        UCHAR   rh_res2[8];     /* reserved 8 = 0                           */
        ULONG   rh_vol_spaceI;  /* size of the volume in LBN's Intel        */
        ULONG   rh_vol_spaceM;  /* size of the volume in LBN's Motorola     */
        UCHAR   rh_charset[32]; /* character set bytes 0 = ASCII            */
        USHORT  rh_vs_sizeI;    /* volume set size Intel                    */
        USHORT  rh_vs_sizeM;    /* volume set size Motorola                 */
        USHORT  rh_vs_snumI;    /* volume set sequence number Intel         */
        USHORT  rh_vs_snumM;    /* volume set sequence number Motorola      */
        USHORT  rh_lb_sizeI;    /* logical block size Intel                 */
        USHORT  rh_lb_sizeM;    /* logical block size Motorola              */
        ULONG   rh_path_sizeI;  /* path table size in bytes Intel           */
        ULONG   rh_path_sizeM;  /* path table size in bytes Motorola        */
        ULONG   rh_path_locI[4];/* LBN of 4 path tables Intel               */
        ULONG   rh_path_locM[4];/* LBN of 4 path tables Motorola            */
        UCHAR   rh_root_de[LEN_ROOT_DE];/* dir entry of the root directory  */
        UCHAR   rh_vs_id[128];  /* volume set identifier                    */
        UCHAR   rh_pub_id[128]; /* publisher identifier                     */
        UCHAR   rh_prep_id[128];/* data preparer identifier                 */
        UCHAR   rh_app_id[128]; /* application identifier                   */
        UCHAR   rh_cpyr_id[32]; /* file name of copyright notice            */
        UCHAR   rh_abst_id[32]; /* file name of abstract                    */
        UCHAR   rh_creat[16];   /* volume creation date and time            */
        UCHAR   rh_mod[16];     /* volume modification date and time        */
        UCHAR   rh_exp[16];     /* volume expiration date and time          */
        UCHAR   rh_eff[16];     /* volume effective date and time           */
        UCHAR   rh_fs_version;  /* file structure version number            */
        UCHAR   rh_res3;        /* reserved 3                               */
        UCHAR   rh_res_app[512];/* reserved for application                 */
        UCHAR   rh_res4[680];   /* remainder of 2048 bytes reserved         */
} RAW_HSG_VTOC, FAR *PRAW_HSG_VTOC;


#define RV_DESC_TYPE(r, i)      (i ? r->ri_desc_type    : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_desc_type)
#define RV_STD_ID(r, i)         (i ? r->ri_std_id       : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_std_id)
#define RV_VERSION(r, i)        (i ? r->ri_version      : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_version)
#define RV_VOL_FLAGS(r, i)      (i ? r->ri_vol_flags    : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_vol_flags)
#define RV_VOL_ID(r, i)         (i ? r->ri_vol_id       : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_vol_id)
#define RV_CPYR_ID(r, i)        (i ? r->ri_cpyr_id      : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_cpyr_id)
#define RV_ABST_ID(r, i)        (i ? r->ri_abst_id      : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_abst_id)
#define RV_BIBL_ID(r, i)        (i ? r->ri_bibl_id      : NULL)

#define RV_VOL_SPACE(r, i)      (i ? r->ri_vol_spaceI   : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_vol_spaceI)
#define RV_CHARSET(r, i)        (i ? r->ri_charset      : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_charset)
#define RV_VS_SIZE(r, i)        (i ? r->ri_vs_sizeI     : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_vs_sizeI)
#define RV_VS_SNUM(r, i)        (i ? r->ri_vs_snumI     : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_vs_snumI)
#define RV_LB_SIZE(r, i)        (i ? r->ri_lb_sizeI     : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_lb_sizeI)
#define RV_PATH_SIZE(r, i)      (i ? r->ri_path_sizeI   : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_path_sizeI)
#define RV_PATH_LOC(r, i, j)    (i ? r->ri_path_locI[j] : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_path_locI[j])
#define RV_CR_DATE(r, i, j)     (i ? r->ri_creat[j]     : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_creat[j])
#define RV_ROOT_DE_ADD(r, i)    (i ? (r->ri_root_de)   : \
                                                                         ((PRAW_HSG_VTOC) r)->rh_root_de)

/*
 ***
 *  VOL_DESC PVOL_DESC PPVOL_DESC (vd, pvd, ppvd)
 *
 *      The data gleaned from the above structures is stored into
 *      a common VTOC structure.  Additional information about
 *      the volume is added as well.
 *
                        */


typedef struct VOL_DESC
{
        BOOL        fISOVol;        /* TRUE if ISO volume                   */
        VD_TYPE     vdtVolType;     /* volume type: 1 = standard, 2 = coded */
        UCHAR       szVolID[38];    /* volume identifier                    */
        ULONG       clbVolSpace;    /* size of the volume in LBN's Intel    */
        VOL_SEQ_NUM vsnSNum;        /* volume set sequence number Intel     */
        USHORT      cbLogBlk;       /* logical block size Intel             */
        ULONG       cbPTSize;       /* path table size in bytes Intel       */
        LOGICAL_BLK lbPathLoc;      /* LBN of Path Table                    */
        UCHAR       szCpyr_ID[38];  /* copyright notice file name           */
        UCHAR       szAbst_ID[38];  /* abstract file name                   */
        UCHAR       szBibl_ID[38];  /* bibliographic file name              */
        UCHAR       acVolCrDate[16];/* volume creation date                 */
} VOL_DESC, FAR *PVOL_DESC, FAR * FAR *PPVOL_DESC;

/* Declare a type for a pointer to a vpfsi/vpfsd */
typedef struct vpfsi FAR *PVPFSI, FAR * FAR *PPVPFSI;
typedef struct vpfsd FAR *PVPFSD, FAR * FAR *PPVPFSD;

/*
 ***
 *  VOL_DEP_DATA PVOL_DEP_DATA (vdd, pvdd)
 *
 *      This structure is superimposed over the vpsfd bytes for
 *      volume specific information.  It contains pointers to
 *      the volume descriptor, the root directory and the path
 *      table.
 *
 *      pvdVolDesc      = Pointer to the volume data.
 *      pdeRootDir      = Pointer to the root directory (in the VTOC).
 *      pptPathTable    = Pointer to the Path Table.
 *      pblSectorList   = Pointer to start of sectors in memory,.
 *      cbSectorSize    = Size of physical sector (may be FAT, PINBALL etc).
 *      usSectorBase    = Number of physical sectors per SECTOR_SIZE.
 *      plsbPathTable   = Semaphore block for Path Table sectors.
 *      plsbBufList     = Semaphore block for Buf List sectors.
 */

typedef struct VOL_DEP_DATA
{
        PVOL_DESC       pvdVolDesc;
        PDIR_ENTRY      pdeRootDir;
        PPATH_TABLE     pptPathTable;
        PBUF_LIST       pblSectorList;
        USHORT          cbSectorSize;
        USHORT          usSectorBase;
        PLIST_SEM_BLK   plsbPathTable;
        PLIST_SEM_BLK   plsbBufList;

} VOL_DEP_DATA, FAR *PVOL_DEP_DATA;

/* Declare a type for a pointer to a cdfsi/cdfsd */
typedef struct cdfsi FAR *PCDFSI, FAR * FAR *PPCDFSI;
typedef struct cdfsd FAR *PCDFSD, FAR * FAR *PPCDFSD;

/*
 ***
 *  DIR_DEP_DATA PDIR_DEP_DATA (ddd, pddd)
 *
 *      This structure is superimposed over the cdfsd structure for
 *      directory dependent data.  It will contain a semaphore byte
 *      to control access into the structure as well as Path Table
 *      information about the directory.
 *
 *      ppePathEntry    = Pointer to Path Entry record for current direct.
 *      sDirSem         = Semaphore controlling access to this structure.
 *
 */


typedef struct DIR_DEP_DATA
{
        PPATH_ENTRY ppePathEntry;
        SEM         sDirSem;
} DIR_DEP_DATA, FAR *PDIR_DEP_DATA;

/* Declare a type for a pointer to a sffsi/sffsd */
typedef struct sffsi FAR *PSFFSI, FAR * FAR *PPSFFSI;
typedef struct sffsd FAR *PSFFSD, FAR * FAR *PPSFFSD;

/*
 ***
 *  FILE_DEP_DATA PFILE_DEP_DATA (fdd, pfdd)
 *
 *      This structure is superimposed over the sffsd bytes for
 *      file specific information.  It contains pointers to
 *      the first directory record and the directory record for
 *      the most recently accessed extent.  It also contains
 *      a field for file attributes in OS/2 form and a flag
 *      indicating if this is a direct access 'file'.  There are
 *      two flags used as semaphores to control access to a file.
 *      One controls access when an operation which changes the
 *      file position is underway, the other controls access when
 *      a close operation is underway.
 *
 *      pdeFirstDirRec  = Pointer to first directory record.
 *      pdeLastDirRec   = Pointer to record most recently accessed.
 *      sFileSem        = Semaphore for repositioning file pointer.
 *      usCountRead     = Count of number of file readers.
 *      fCloseFlag      = Flag indicating that close has started.
 *      fDirAccess      = Flag indicating if direct access.
 */

typedef struct FILE_DEP_DATA
{
        PDIR_ENTRY  pdeFirstDirRec;
        PDIR_ENTRY  pdeLastDirRec;
        SEM         sFileSem;
        USHORT      usCountRead;
        BOOL        fCloseFlag;
        BOOL        fDirAccess;
        USHORT      usSqntlCount;
        SECT_NUM    snNextSqntl;
        SECT_NUM    snNextReadAhead;
} FILE_DEP_DATA, FAR *PFILE_DEP_DATA;


/*
 ***
 *  SEARCH_STRING PSEARCH_STRING PPSEARCH_STRING (ss, pss, ppss)
 *
 *      This structure is a file identifier string.  It will contain
 *      a null terminated string.
 *
 *      cbSearchString  =   Length of search string.
 *      szName          = this identifier stored into memory.
 *
 */

typedef struct SEARCH_STRING
{
        USHORT  cbSearchString;
        CHAR    szName[MAX_FILE_ID_LEN];
} SEARCH_STRING, FAR *PSEARCH_STRING, FAR * FAR * PPSEARCH_STRING;


/* Declare a type for a pointer to a fsfsi/fsfsd */
typedef struct fsfsi FAR *PFSFSI, FAR * FAR *PPFSFSI;
typedef struct fsfsd FAR *PFSFSD, FAR * FAR *PPFSFSD;


/*
 ***
 *  SEARCH_DEP_DATA PSEARCH_DEP_DATA (sdd, psdd)
 *
 *      This structure is superimposed over the sffsd bytes for
 *      file search dependent data.  It contains the directory record
 *      for the parent directory for this search and the last
 *      directory record found in the search.  There is also a semaphore
 *      used to control access to this structure.
 *
 *      pdeParentDir      = Parent Directory Entry (to restart search)
 *      pdeLastDir        = Last directory record examined.
 *      pssSearchString   = Last search string.
 *      fSearchClose    = Flag used to indicate that close has started.
 *      fFirstSearch    = Flag indicating if this is the first search.
 *      fRootDir        = Flag indicating if the search is for the root dir.
 *      fRetRootDir     = Flag indicating if returned the root dir.
 *      usCountSearch   = Number of active searchers on this handle.
 *      afAttr          = Attributes for search.
 *      cSearchSem      = Semaphore to control access to search structure.
 */

typedef struct SEARCH_DEP_DATA
{
        PDIR_ENTRY      pdeParentDir;                         /* @DB65536 */
        PDIR_ENTRY      pdeLastDir;
        PSEARCH_STRING  pssSearchString;
        BOOL            fSearchClose;
        BOOL            fFirstSearch;
        BOOL            fRootDir;
        BOOL            fRetRootDir;
        USHORT          afAttr;
        USHORT          usCountSearch;
        SEM             sSearchSem;
} SEARCH_DEP_DATA, FAR *PSEARCH_DEP_DATA;

/*
 *  STRING_BUF PSTRING_BUF PPSTRING_BUF (sb, psb, ppsb)
 *
 *      Buffer used to store filenames while performing non-case sensitive
 *      comparisons.
 */
typedef UCHAR   STRING_BUF[MAX_OS2_PATH_LEN + 1];
typedef PCHAR   PSTRING_BUF, FAR * PPSTRING_BUF;

/*
 *  GEN_LLIST PGEN_LLIST    (gl, pgl)
 *
 *      Generic linked list.  All the allocated structures handled in
 *      in the FSD are cast to this type when maintaining them in
 *      linked lists when not being used.
 */

/*
 *  GEN_LLIST PGEN_LLIST    (gl, pgl)
 *
 *      Generic linked list.  All the allocated structures handled in
 *      in the FSD are cast to this type when maintaining them in
 *      linked lists when not being used.
 */

typedef struct GEN_LLIST
{
        struct  GEN_LLIST   FAR *pglNextGenLList;
} GEN_LLIST, FAR *PGEN_LLIST;


/*
 *  MOUNT_PARAMS PMOUNT_PARAMS PPMOUNT_PARAMS (mp, pmp, ppmp)
 *
 *  The following structure is used for the functions which perform
 *  the mount operation.  It is used to reduce the size of the stack.
 */

typedef struct MOUNT_PARAMS
{
        /* Local parameters for VolMount */

        PBUF            pbBuf;
        BOOL            fISOVol;
        SECT_NUM        snSectorNumber;
        PRAW_ISO_VTOC   privRawISO;
        SHANDLE         hOldHVPB;

        /* Formal arguements passed to RecoverPathTable */
        PVOL_DEP_DATA   pvddVolData;
        SHANDLE         hVPB;
        LONG            cbPathTableSize;

        /* Local parameters for RecoverPathTable */
        BOOL            fNoSplit;
        PPATH_TABLE     pptPathTable;
        SECT_NUM        snThisSector;
        USHORT          cbOffset;
        PATH_NUMBER     pnDirNum;
        PRAW_PATH_ISO   prpiRawISO;
        PRAW_PATH_ISO   prpiISOCopy;
        PBUF            pbThisBuf;
        PBUF            pbNextBuf;
        USHORT          cbBufEnd;
        USHORT          cbThisLen;
        LOGICAL_BLK             lbLastLBN;
        SECT_NUM                snLastSector;
        PRAW_PATH_ISO   prpiLastRawPE;

} MOUNT_PARAMS, FAR *PMOUNT_PARAMS, FAR * FAR *PPMOUNT_PARAMS;


/*
 *  FFRST_PARAMS PFFRST_PARAMS PPFFRST_PARAMS (ffp, pffp, ppffp)
 *
 *  The following structure is used in FS_FINDFIRST to reduce the stack
 *  usage.
 */

typedef struct FFRST_PARAMS
{
        PVPFSI          pvpfsi;
        PVOL_DEP_DATA   pvddVolData;
        USHORT          cbNameLen;
        USHORT          cbBaseOffset;
        USHORT          usTempMatch;

}   FFRST_PARAMS, FAR *PFFRST_PARAMS, FAR * FAR *PPFFRST_PARAMS;


/*
 *  FIND_BUF_LOC, PFIND_BUF_LOC, PPFIND_BUF_LOC (fbl, pfbl, ppfbl)
 *
 *  The following is a structure which contains the local structures
 *  for the function FindBuf.
 *
 *      pblPrevHdr      --  Pointer to header to attach the new header to.
 *      fBLOwns         --  Is this a BUF_LIST header.
 *      fLocked         --  Indicates if a buffer is locked.
 *      snStartSector   --  Starting sector number.
 *      snAdjStartSect  --  Start sector based on physical sector size.
 *      csSectorCount   --  Offset of last sector from starting sector.
 *      pblAddedHdrs    --  Linked list of added (or assumed) headers.
 *      pbBufChain      --  Linked chain of BUF structures.
 *      pbEndBufChain   --  End of linked chain of BUF structures.
 *      csReadSectors   --  Number of device specific sectors to read.
 *      pvddVolData     --  Pointer to volume dependent data.
 *      pSeg            --  Pointer to buffer to read disk sectors into.
 *      sSel            --  Selector for allocation.
 *      hVPB            --  Handle for VPB.
 *      fMulti          --  Flag indicating if this was multi-sector read.
 *      usErrCode       --  Error code passed through 'ResearchList'.
 *      plsbThisSemBlk  --  Pointer to LIST_SEM_BLK for this list.
 */

typedef struct FIND_BUF_LOC
{
        PBUF_LIST       pblPrevHdr;
        BOOL            fBLOwns;
        BOOL            fLocked;
        SECT_NUM        snStartSector;
        SECT_NUM        snAdjStartSect;
        USHORT          csSectorCount;
        PBUF_LIST       pblAddedHdrs;
        PBUF            pbBufChain;
        PBUF            pbEndBufChain;
        USHORT          csReadSectors;
        PVOL_DEP_DATA   pvddVolData;
        PCHAR           pSeg;
        SEL             sSel;
        USHORT          hVPB;
        BOOL            fMulti;
        USHORT          usErrCode;
        PLIST_SEM_BLK   plsbThisSemBlk;

} FIND_BUF_LOC, FAR *PFIND_BUF_LOC, FAR * FAR *PPFIND_BUF_LOC;

