text: /*
       File:       HFSVolumes.h
   
       Contains:   On-disk data structures for HFS and HFS Plus volumes.
   
       Version:    QuickTime 7.3
   
       Copyright:  (c) 2007 (c) 1984-2001 by Apple Computer, Inc.  All rights reserved.
   
       Bugs?:      For bug reports, consult the following page on
                   the World Wide Web:
   
                       http://developer.apple.com/bugreporter/
   
  */
  #ifndef __HFSVOLUMES__
  #define __HFSVOLUMES__
  
  #ifndef __MACTYPES__
  #include <MacTypes.h>
  #endif
  
  #ifndef __FILES__
  #include <Files.h>
  #endif
  
  #ifndef __FINDER__
  #include <Finder.h>
  #endif
  
  
  
  
  #if PRAGMA_ONCE
  #pragma once
  #endif
  
  #if PRAGMA_IMPORT
  #pragma import on
  #endif
  
  #if PRAGMA_STRUCT_ALIGN
      #pragma options align=mac68k
  #elif PRAGMA_STRUCT_PACKPUSH
      #pragma pack(push, 2)
  #elif PRAGMA_STRUCT_PACK
      #pragma pack(2)
  #endif
  
  /* Signatures used to differentiate between HFS and HFS Plus volumes */
  enum {
    kHFSSigWord                   = 0x4244, /* 'BD' in ASCII */
    kHFSPlusSigWord               = 0x482B, /* 'H+' in ASCII */
    kHFSPlusVersion               = 0x0004, /* will change as format changes (version 4 shipped with Mac OS 8.1) */
    kHFSPlusMountVersion          = FOUR_CHAR_CODE('8.10') /* will change as implementations change ('8.10' in Mac OS 8.1) */
  };
  
  
  /* CatalogNodeID is used to track catalog objects */
  typedef UInt32                          HFSCatalogNodeID;
  enum {
    kHFSMaxVolumeNameChars        = 27,
    kHFSMaxFileNameChars          = 31,
    kHFSPlusMaxFileNameChars      = 255
  };
  
  
  /* Extent overflow file data structures */
  /* HFS Extent key */
  struct HFSExtentKey {
    UInt8               keyLength;              /* length of key, excluding this field */
    UInt8               forkType;               /* 0 = data fork, FF = resource fork */
    HFSCatalogNodeID    fileID;                 /* file ID */
    UInt16              startBlock;             /* first file allocation block number in this extent */
  };
  typedef struct HFSExtentKey             HFSExtentKey;
  /* HFS Plus Extent key */
  struct HFSPlusExtentKey {
    UInt16              keyLength;              /* length of key, excluding this field */
    UInt8               forkType;               /* 0 = data fork, FF = resource fork */
    UInt8               pad;                    /* make the other fields align on 32-bit boundary */
    HFSCatalogNodeID    fileID;                 /* file ID */
    UInt32              startBlock;             /* first file allocation block number in this extent */
  };
  typedef struct HFSPlusExtentKey         HFSPlusExtentKey;
  /* Number of extent descriptors per extent record */
  enum {
    kHFSExtentDensity             = 3,
    kHFSPlusExtentDensity         = 8
  };
  
  /* HFS extent descriptor */
  struct HFSExtentDescriptor {
    UInt16              startBlock;             /* first allocation block */
    UInt16              blockCount;             /* number of allocation blocks */
  };
  typedef struct HFSExtentDescriptor      HFSExtentDescriptor;
  /* HFS Plus extent descriptor */
  struct HFSPlusExtentDescriptor {
    UInt32              startBlock;             /* first allocation block */
    UInt32              blockCount;             /* number of allocation blocks */
  };
  typedef struct HFSPlusExtentDescriptor  HFSPlusExtentDescriptor;
  /* HFS extent record */
  
  typedef HFSExtentDescriptor             HFSExtentRecord[3];
  /* HFS Plus extent record */
  typedef HFSPlusExtentDescriptor         HFSPlusExtentRecord[8];
  
  /* Fork data info (HFS Plus only) - 80 bytes */
  struct HFSPlusForkData {
    UInt64              logicalSize;            /* fork's logical size in bytes */
    UInt32              clumpSize;              /* fork's clump size in bytes */
    UInt32              totalBlocks;            /* total blocks used by this fork */
    HFSPlusExtentRecord  extents;               /* initial set of extents */
  };
  typedef struct HFSPlusForkData          HFSPlusForkData;
  /* Permissions info (HFS Plus only) - 16 bytes */
  struct HFSPlusPermissions {
    UInt32              ownerID;                /* user or group ID of file/folder owner */
    UInt32              groupID;                /* additional user of group ID */
    UInt32              permissions;            /* permissions (bytes: unused, owner, group, everyone) */
    UInt32              specialDevice;          /* UNIX: device for character or block special file */
  };
  typedef struct HFSPlusPermissions       HFSPlusPermissions;
  /* Catalog file data structures */
  enum {
    kHFSRootParentID              = 1,    /* Parent ID of the root folder */
    kHFSRootFolderID              = 2,    /* Folder ID of the root folder */
    kHFSExtentsFileID             = 3,    /* File ID of the extents file */
    kHFSCatalogFileID             = 4,    /* File ID of the catalog file */
    kHFSBadBlockFileID            = 5,    /* File ID of the bad allocation block file */
    kHFSAllocationFileID          = 6,    /* File ID of the allocation file (HFS Plus only) */
    kHFSStartupFileID             = 7,    /* File ID of the startup file (HFS Plus only) */
    kHFSAttributesFileID          = 8,    /* File ID of the attribute file (HFS Plus only) */
    kHFSBogusExtentFileID         = 15,   /* Used for exchanging extents in extents file */
    kHFSFirstUserCatalogNodeID    = 16
  };
  
  
  /* HFS catalog key */
  struct HFSCatalogKey {
    UInt8               keyLength;              /* key length (in bytes) */
    UInt8               reserved;               /* reserved (set to zero) */
    HFSCatalogNodeID    parentID;               /* parent folder ID */
    Str31               nodeName;               /* catalog node name */
  };
  typedef struct HFSCatalogKey            HFSCatalogKey;
  /* HFS Plus catalog key */
  struct HFSPlusCatalogKey {
    UInt16              keyLength;              /* key length (in bytes) */
    HFSCatalogNodeID    parentID;               /* parent folder ID */
    HFSUniStr255        nodeName;               /* catalog node name */
  };
  typedef struct HFSPlusCatalogKey        HFSPlusCatalogKey;
  
  /* Catalog record types */
  enum {
                                          /* HFS Catalog Records */
    kHFSFolderRecord              = 0x0100, /* Folder record */
    kHFSFileRecord                = 0x0200, /* File record */
    kHFSFolderThreadRecord        = 0x0300, /* Folder thread record */
    kHFSFileThreadRecord          = 0x0400, /* File thread record */
                                          /* HFS Plus Catalog Records */
    kHFSPlusFolderRecord          = 1,    /* Folder record */
    kHFSPlusFileRecord            = 2,    /* File record */
    kHFSPlusFolderThreadRecord    = 3,    /* Folder thread record */
    kHFSPlusFileThreadRecord      = 4     /* File thread record */
  };
  
  
  /* Catalog file record flags */
  enum {
    kHFSFileLockedBit             = 0x0000, /* file is locked and cannot be written to */
    kHFSFileLockedMask            = 0x0001,
    kHFSThreadExistsBit           = 0x0001, /* a file thread record exists for this file */
    kHFSThreadExistsMask          = 0x0002
  };
  
  
  /* HFS catalog folder record - 70 bytes */
  struct HFSCatalogFolder {
    SInt16              recordType;             /* record type */
    UInt16              flags;                  /* folder flags */
    UInt16              valence;                /* folder valence */
    HFSCatalogNodeID    folderID;               /* folder ID */
    UInt32              createDate;             /* date and time of creation */
    UInt32              modifyDate;             /* date and time of last modification */
    UInt32              backupDate;             /* date and time of last backup */
    DInfo               userInfo;               /* Finder information */
    DXInfo              finderInfo;             /* additional Finder information */
    UInt32              reserved[4];            /* reserved - set to zero */
  };
  typedef struct HFSCatalogFolder         HFSCatalogFolder;
  /* HFS Plus catalog folder record - 88 bytes */
  struct HFSPlusCatalogFolder {
    SInt16              recordType;             /* record type = HFS Plus folder record */
    UInt16              flags;                  /* file flags */
    UInt32              valence;                /* folder's valence (limited to 2^16 in Mac OS) */
    HFSCatalogNodeID    folderID;               /* folder ID */
    UInt32              createDate;             /* date and time of creation */
    UInt32              contentModDate;         /* date and time of last content modification */
    UInt32              attributeModDate;       /* date and time of last attribute modification */
    UInt32              accessDate;             /* date and time of last access (Rhapsody only) */
    UInt32              backupDate;             /* date and time of last backup */
    HFSPlusPermissions  permissions;            /* permissions (for Rhapsody) */
    DInfo               userInfo;               /* Finder information */
    DXInfo              finderInfo;             /* additional Finder information */
    UInt32              textEncoding;           /* hint for name conversions */
    UInt32              reserved;               /* reserved - set to zero */
  };
  typedef struct HFSPlusCatalogFolder     HFSPlusCatalogFolder;
  /* HFS catalog file record - 102 bytes */
  struct HFSCatalogFile {
    SInt16              recordType;             /* record type */
    UInt8               flags;                  /* file flags */
    SInt8               fileType;               /* file type (unused ?) */
    FInfo               userInfo;               /* Finder information */
    HFSCatalogNodeID    fileID;                 /* file ID */
    UInt16              dataStartBlock;         /* not used - set to zero */
    SInt32              dataLogicalSize;        /* logical EOF of data fork */
    SInt32              dataPhysicalSize;       /* physical EOF of data fork */
    UInt16              rsrcStartBlock;         /* not used - set to zero */
    SInt32              rsrcLogicalSize;        /* logical EOF of resource fork */
    SInt32              rsrcPhysicalSize;       /* physical EOF of resource fork */
    UInt32              createDate;             /* date and time of creation */
    UInt32              modifyDate;             /* date and time of last modification */
    UInt32              backupDate;             /* date and time of last backup */
    FXInfo              finderInfo;             /* additional Finder information */
    UInt16              clumpSize;              /* file clump size (not used) */
    HFSExtentRecord     dataExtents;            /* first data fork extent record */
    HFSExtentRecord     rsrcExtents;            /* first resource fork extent record */
    UInt32              reserved;               /* reserved - set to zero */
  };
  typedef struct HFSCatalogFile           HFSCatalogFile;
  /* HFS Plus catalog file record - 248 bytes */
  struct HFSPlusCatalogFile {
    SInt16              recordType;             /* record type = HFS Plus file record */
    UInt16              flags;                  /* file flags */
    UInt32              reserved1;              /* reserved - set to zero */
    HFSCatalogNodeID    fileID;                 /* file ID */
    UInt32              createDate;             /* date and time of creation */
    UInt32              contentModDate;         /* date and time of last content modification */
    UInt32              attributeModDate;       /* date and time of last attribute modification */
    UInt32              accessDate;             /* date and time of last access (Rhapsody only) */
    UInt32              backupDate;             /* date and time of last backup */
    HFSPlusPermissions  permissions;            /* permissions (for Rhapsody) */
    FInfo               userInfo;               /* Finder information */
    FXInfo              finderInfo;             /* additional Finder information */
    UInt32              textEncoding;           /* hint for name conversions */
    UInt32              reserved2;              /* reserved - set to zero */
  
                                                /* start on double long (64 bit) boundry */
    HFSPlusForkData     dataFork;               /* size and block data for data fork */
    HFSPlusForkData     resourceFork;           /* size and block data for resource fork */
  };
  typedef struct HFSPlusCatalogFile       HFSPlusCatalogFile;
  /* HFS catalog thread record - 46 bytes */
  struct HFSCatalogThread {
    SInt16              recordType;             /* record type */
    SInt32              reserved[2];            /* reserved - set to zero */
    HFSCatalogNodeID    parentID;               /* parent ID for this catalog node */
    Str31               nodeName;               /* name of this catalog node */
  };
  typedef struct HFSCatalogThread         HFSCatalogThread;
  /* HFS Plus catalog thread record -- 264 bytes */
  struct HFSPlusCatalogThread {
    SInt16              recordType;             /* record type */
    SInt16              reserved;               /* reserved - set to zero */
    HFSCatalogNodeID    parentID;               /* parent ID for this catalog node */
    HFSUniStr255        nodeName;               /* name of this catalog node (variable length) */
  };
  typedef struct HFSPlusCatalogThread     HFSPlusCatalogThread;
  
  /*
      These are the types of records in the attribute B-tree.  The values were chosen
      so that they wouldn't conflict with the catalog record types.
  */
  enum {
    kHFSPlusAttrInlineData        = 0x10, /* if size <  kAttrOverflowSize */
    kHFSPlusAttrForkData          = 0x20, /* if size >= kAttrOverflowSize */
    kHFSPlusAttrExtents           = 0x30  /* overflow extents for large attributes */
  };
  
  
  /*
      HFSPlusAttrInlineData
      For small attributes, whose entire value is stored within this one
      B-tree record.
      There would not be any other records for this attribute.
  */
  struct HFSPlusAttrInlineData {
    UInt32              recordType;             /*    = kHFSPlusAttrInlineData*/
    UInt32              reserved;
    UInt32              logicalSize;            /*    size in bytes of userData*/
    UInt8               userData[2];            /*    variable length; space allocated is a multiple of 2 bytes*/
  };
  typedef struct HFSPlusAttrInlineData    HFSPlusAttrInlineData;
  /*
      HFSPlusAttrForkData
      For larger attributes, whose value is stored in allocation blocks.
      If the attribute has more than 8 extents, there will be additonal
      records (of type HFSPlusAttrExtents) for this attribute.
  */
  struct HFSPlusAttrForkData {
    UInt32              recordType;             /*    = kHFSPlusAttrForkData*/
    UInt32              reserved;
    HFSPlusForkData     theFork;                /*    size and first extents of value*/
  };
  typedef struct HFSPlusAttrForkData      HFSPlusAttrForkData;
  /*
      HFSPlusAttrExtents
      This record contains information about overflow extents for large,
      fragmented attributes.
  */
  struct HFSPlusAttrExtents {
    UInt32              recordType;             /*    = kHFSPlusAttrExtents*/
    UInt32              reserved;
    HFSPlusExtentRecord  extents;               /*    additional extents*/
  };
  typedef struct HFSPlusAttrExtents       HFSPlusAttrExtents;
  /*  A generic Attribute Record*/
  union HFSPlusAttrRecord {
    UInt32              recordType;
    HFSPlusAttrInlineData  inlineData;
    HFSPlusAttrForkData  forkData;
    HFSPlusAttrExtents  overflowExtents;
  };
  typedef union HFSPlusAttrRecord         HFSPlusAttrRecord;
  /* Key and node lengths */
  enum {
    kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(UInt16),
    kHFSExtentKeyMaximumLength    = sizeof(HFSExtentKey) - sizeof(UInt8),
    kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(UInt16),
    kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(UInt16),
    kHFSCatalogKeyMaximumLength   = sizeof(HFSCatalogKey) - sizeof(UInt8),
    kHFSCatalogKeyMinimumLength   = kHFSCatalogKeyMaximumLength - sizeof(Str31) + sizeof(UInt8),
    kHFSPlusCatalogMinNodeSize    = 4096,
    kHFSPlusExtentMinNodeSize     = 512,
    kHFSPlusAttrMinNodeSize       = 4096
  };
  
  
  /* HFS and HFS Plus volume attribute bits */
  enum {
                                          /* Bits 0-6 are reserved (always cleared by MountVol call) */
    kHFSVolumeHardwareLockBit     = 7,    /* volume is locked by hardware */
    kHFSVolumeUnmountedBit        = 8,    /* volume was successfully unmounted */
    kHFSVolumeSparedBlocksBit     = 9,    /* volume has bad blocks spared */
    kHFSVolumeNoCacheRequiredBit  = 10,   /* don't cache volume blocks (i.e. RAM or ROM disk) */
    kHFSBootVolumeInconsistentBit = 11,   /* boot volume is inconsistent (System 7.6 and later) */
                                          /* Bits 12-14 are reserved for future use */
    kHFSVolumeSoftwareLockBit     = 15,   /* volume is locked by software */
    kHFSVolumeHardwareLockMask    = 1 << kHFSVolumeHardwareLockBit,
    kHFSVolumeUnmountedMask       = 1 << kHFSVolumeUnmountedBit,
    kHFSVolumeSparedBlocksMask    = 1 << kHFSVolumeSparedBlocksBit,
    kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit,
    kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit,
    kHFSVolumeSoftwareLockMask    = 1 << kHFSVolumeSoftwareLockBit,
    kHFSMDBAttributesMask         = 0x8380
  };
  
  /* Master Directory Block (HFS only) - 162 bytes */
  /* Stored at sector #2 (3rd sector) */
  struct HFSMasterDirectoryBlock {
  
                                                /* These first fields are also used by MFS */
  
    UInt16              drSigWord;              /* volume signature */
    UInt32              drCrDate;               /* date and time of volume creation */
    UInt32              drLsMod;                /* date and time of last modification */
    UInt16              drAtrb;                 /* volume attributes */
    UInt16              drNmFls;                /* number of files in root folder */
    UInt16              drVBMSt;                /* first block of volume bitmap */
    UInt16              drAllocPtr;             /* start of next allocation search */
    UInt16              drNmAlBlks;             /* number of allocation blocks in volume */
    UInt32              drAlBlkSiz;             /* size (in bytes) of allocation blocks */
    UInt32              drClpSiz;               /* default clump size */
    UInt16              drAlBlSt;               /* first allocation block in volume */
    UInt32              drNxtCNID;              /* next unused catalog node ID */
    UInt16              drFreeBks;              /* number of unused allocation blocks */
    Str27               drVN;                   /* volume name */
  
                                                /* Master Directory Block extensions for HFS */
  
    UInt32              drVolBkUp;              /* date and time of last backup */
    UInt16              drVSeqNum;              /* volume backup sequence number */
    UInt32              drWrCnt;                /* volume write count */
    UInt32              drXTClpSiz;             /* clump size for extents overflow file */
    UInt32              drCTClpSiz;             /* clump size for catalog file */
    UInt16              drNmRtDirs;             /* number of directories in root folder */
    UInt32              drFilCnt;               /* number of files in volume */
    UInt32              drDirCnt;               /* number of directories in volume */
    SInt32              drFndrInfo[8];          /* information used by the Finder */
    UInt16              drEmbedSigWord;         /* embedded volume signature (formerly drVCSize) */
    HFSExtentDescriptor  drEmbedExtent;         /* embedded volume location and size (formerly drVBMCSize and drCtlCSize) */
    UInt32              drXTFlSize;             /* size of extents overflow file */
    HFSExtentRecord     drXTExtRec;             /* extent record for extents overflow file */
    UInt32              drCTFlSize;             /* size of catalog file */
    HFSExtentRecord     drCTExtRec;             /* extent record for catalog file */
  };
  typedef struct HFSMasterDirectoryBlock  HFSMasterDirectoryBlock;
  /* HFSPlusVolumeHeader (HFS Plus only) - 512 bytes */
  /* Stored at sector #2 (3rd sector) and second-to-last sector. */
  struct HFSPlusVolumeHeader {
    UInt16              signature;              /* volume signature == 'H+' */
    UInt16              version;                /* current version is kHFSPlusVersion */
    UInt32              attributes;             /* volume attributes */
    UInt32              lastMountedVersion;     /* implementation version which last mounted volume */
    UInt32              reserved;               /* reserved - set to zero */
  
    UInt32              createDate;             /* date and time of volume creation */
    UInt32              modifyDate;             /* date and time of last modification */
    UInt32              backupDate;             /* date and time of last backup */
    UInt32              checkedDate;            /* date and time of last disk check */
  
    UInt32              fileCount;              /* number of files in volume */
    UInt32              folderCount;            /* number of directories in volume */
  
    UInt32              blockSize;              /* size (in bytes) of allocation blocks */
    UInt32              totalBlocks;            /* number of allocation blocks in volume (includes this header and VBM*/
    UInt32              freeBlocks;             /* number of unused allocation blocks */
  
    UInt32              nextAllocation;         /* start of next allocation search */
    UInt32              rsrcClumpSize;          /* default resource fork clump size */
    UInt32              dataClumpSize;          /* default data fork clump size */
    HFSCatalogNodeID    nextCatalogID;          /* next unused catalog node ID */
  
    UInt32              writeCount;             /* volume write count */
    UInt64              encodingsBitmap;        /* which encodings have been use  on this volume */
  
    UInt8               finderInfo[32];         /* information used by the Finder */
  
    HFSPlusForkData     allocationFile;         /* allocation bitmap file */
    HFSPlusForkData     extentsFile;            /* extents B-tree file */
    HFSPlusForkData     catalogFile;            /* catalog B-tree file */
    HFSPlusForkData     attributesFile;         /* extended attributes B-tree file */
    HFSPlusForkData     startupFile;            /* boot file */
  };
  typedef struct HFSPlusVolumeHeader      HFSPlusVolumeHeader;
  /* ---------- HFS and HFS Plus B-tree structures ---------- */
  /* BTNodeDescriptor -- Every B-tree node starts with these fields. */
  struct BTNodeDescriptor {
    UInt32              fLink;                  /*    next node at this level*/
    UInt32              bLink;                  /*    previous node at this level*/
    SInt8               kind;                   /*    kind of node (leaf, index, header, map)*/
    UInt8               height;                 /*    zero for header, map; child is one more than parent*/
    UInt16              numRecords;             /*    number of records in this node*/
    UInt16              reserved;               /*    reserved; set to zero*/
  };
  typedef struct BTNodeDescriptor         BTNodeDescriptor;
  /* Constants for BTNodeDescriptor kind */
  enum {
    kBTLeafNode                   = -1,
    kBTIndexNode                  = 0,
    kBTHeaderNode                 = 1,
    kBTMapNode                    = 2
  };
  
  /* BTHeaderRec -- The first record of a B-tree header node */
  struct BTHeaderRec {
    UInt16              treeDepth;              /*    maximum height (usually leaf nodes)*/
    UInt32              rootNode;               /*    node number of root node*/
    UInt32              leafRecords;            /*    number of leaf records in all leaf nodes*/
    UInt32              firstLeafNode;          /*    node number of first leaf node*/
    UInt32              lastLeafNode;           /*    node number of last leaf node*/
    UInt16              nodeSize;               /*    size of a node, in bytes*/
    UInt16              maxKeyLength;           /*    reserved*/
    UInt32              totalNodes;             /*    total number of nodes in tree*/
    UInt32              freeNodes;              /*    number of unused (free) nodes in tree*/
    UInt16              reserved1;              /*    unused*/
    UInt32              clumpSize;              /*    reserved*/
    UInt8               btreeType;              /*    reserved*/
    UInt8               reserved2;              /*    reserved*/
    UInt32              attributes;             /*    persistent attributes about the tree*/
    UInt32              reserved3[16];          /*    reserved*/
  };
  typedef struct BTHeaderRec              BTHeaderRec;
  /* Constants for BTHeaderRec attributes */
  enum {
    kBTBadCloseMask               = 0x00000001, /*    reserved*/
    kBTBigKeysMask                = 0x00000002, /*    key length field is 16 bits*/
    kBTVariableIndexKeysMask      = 0x00000004 /*    keys in index nodes are variable length*/
  };
  
  
  #if PRAGMA_STRUCT_ALIGN
      #pragma options align=reset
  #elif PRAGMA_STRUCT_PACKPUSH
      #pragma pack(pop)
  #elif PRAGMA_STRUCT_PACK
      #pragma pack()
  #endif
  
  #ifdef PRAGMA_IMPORT_OFF
  #pragma import off
  #elif PRAGMA_IMPORT
  #pragma import reset
  #endif
  
  
  #endif /* __HFSVOLUMES__ */
  
  