#define HFS_BIT_VOLUME_UNMOUNTED (uint32_t)(1 << 8) /* set if the volume was unmounted properly; as per TN 1150, modern Macintosh OSes always leave this bit set for the boot volume */
#define HFS_BIT_VOLUME_BADBLOCKS (uint32_t)(1 << 9) /* set if there are any bad blocks for this volume (in the Extents B-tree) */
#define HFS_BIT_VOLUME_INCONSISTENT (uint32_t)(1 << 11) /* cleared if the volume was unmounted properly */
#define HFS_BIT_VOLUME_CNIDS_REUSED (uint32_t)(1 << 12) /* set if CNIDs have wrapped around past the maximum value and are being reused; in this case, there are CNIDs on the disk larger than the nextCatalogId field */
#define HFS_VH_OFF 1024 // byte offset in volume to volume header
// signature values
#define HFS_VH_SIG_HFS 0x4244 /* BD in big endian */
#define HFS_VH_SIG_HFSPLUS 0x482b /* H+ in big endian */
#define HFS_VH_SIG_HFSX 0x4858 /* HX in big endian */
// version values
#define HFS_VH_VER_HFSPLUS 0x0004 /* all HFS+ volumes are version 4 */
#define HFS_VH_VER_HFSX 0x0005 /* HFSX volumes start with version 5 */
// attr values (
// bits 0 to 7 are reserved
#define HFS_VH_ATTR_UNMOUNTED (uint32_t)(1<<8) /* set if the volume was unmounted properly; as per TN 1150, modern Macintosh OSes always leave this bit set for the boot volume */
#define HFS_VH_ATTR_BADBLOCKS (uint32_t)(1<<9) /* set if there are any bad blocks for this volume (in the Extents B-tree) */
#define HFS_VH_ATTR_NOCACHE (uint32_t)(1<<10) /* set if volume should not be cached */
#define HFS_VH_ATTR_INCONSISTENT (uint32_t)(1<<11) /* cleared if the volume was unmounted properly */
#define HFS_VH_ATTR_CNIDS_REUSED (uint32_t)(1<<12) /* set if CNIDs have wrapped around past the maximum value and are being reused; in this case, there are CNIDs on the disk larger than the nextCatalogId field */
#define HFS_VH_ATTR_JOURNALED (uint32_t)(1<<13)
// 14 is reserved
#define HFS_VH_ATTR_SOFTWARE_LOCK (uint32_t)(1 << 15) /* set if volume should be write-protected in software */
// 16 to 31 are reserved
// last_mnt_ver values
#define HFS_VH_MVER_HFSPLUS 0x31302e30 /* '10.0' for Mac OS X */
#define HFS_VH_MVER_HFSJ 0x4846534a /* 'HFSJ' for journaled HFS+ on Mac OS X */
#define HFS_VH_MVER_FSK 0x46534b21 /* 'FSK!' for failed journal replay */
#define HFS_VH_MVER_FSCK 0x6673636b /* 'fsck' for fsck_hfs */
#define HFS_VH_MVER_OS89 0x382e3130 /* '8.10' for Mac OS 8.1-9.2.2 */
/* Index values for finder_info array */
#define HFS_VH_FI_BOOT 0 /*Directory ID of bootable directory */
#define HFS_VH_FI_START 1 /* Parent dir ID of startup app */
#define HFS_VH_FI_OPEN 2 /* Directory to open when volume is mounted */
#define HFS_VH_FI_BOOT9 3 /* Directory ID of OS 8 or 9 bootable sys folder */
#define HFS_VH_FI_RESV1 4
#define HFS_VH_FI_BOOTX 5 /* Directory ID of OS X bootable system (CoreServices dir) */
#define HFS_VH_FI_ID1 6 /* OS X Volume ID part 1 */
#define HFS_VH_FI_ID2 7 /* OS X Volume ID part 2 */
/*
** HFS+/HFSX Super Block
*/
...
...
@@ -241,23 +259,30 @@ typedef struct {
uint8_tattr[4];/* volume attributes */
uint8_tlast_mnt_ver[4];/* last mounted version */
uint8_tjinfo_blk[4];/* journal info block */
uint8_tc_date[4];/* volume creation date */
uint8_tm_date[4];/* volume last modified date */
uint8_tbkup_date[4];/* volume last backup date */
uint8_tchk_date[4];/* date of last consistency check */
uint8_tfile_cnt[4];/* number of files on volume */
uint8_tfldr_cnt[4];/* number of folders on volume */
uint8_tblk_sz[4];/* allocation block size */
uint8_tcr_date[4];/* volume creation date (NOT in GMT) */
uint8_tm_date[4];/* volume last modified date (GMT) */
uint8_tbkup_date[4];/* volume last backup date (GMT) */
uint8_tchk_date[4];/* date of last consistency check (GMT) */
uint8_tfile_cnt[4];/* number of files on volume (not incl. special files) */
uint8_tfldr_cnt[4];/* number of folders on volume (not incl. root dir) */
uint8_tblk_sz[4];/* allocation block size (in bytes) */
uint8_tblk_cnt[4];/* number of blocks on disk */
uint8_tfree_blks[4];/* unused block count */
uint8_tnext_alloc[4];/* start of next allocation search */
uint8_trsrc_clmp_sz[4];/* default clump size for resource forks */
uint8_tdata_clmp_sz[4];/* default clump size for data forks */
uint8_tnext_cat_id[4];/* next catalog id */
uint8_twrite_cnt[4];/* write count */
uint8_tenc_bmp[8];/* encoding bitmap */
uint8_tfinder_info[32];
hfs_forkalloc_file;/* location and size of allocation file */
uint8_tnext_alloc[4];/* block addr to start allocation search from */
uint8_trsrc_clmp_sz[4];/* default clump size for resource forks (in bytes) */
uint8_tdata_clmp_sz[4];/* default clump size for data forks (in bytes) */
uint8_tnext_cat_id[4];/* next catalog id for allocation */
uint8_twrite_cnt[4];/* write count: incremented each time it is mounted and modified */
uint8_tenc_bmp[8];/* encoding bitmap (identifies which encodings were used in FS) */
uint8_tfinder_info[8][4];/* Special finder details */
hfs_forkalloc_file;/* location and size of allocation bitmap file */
hfs_forkext_file;/* location and size of extents file */
hfs_forkcat_file;/* location and size of catalog file */
hfs_forkattr_file;/* location and size of attributes file */
...
...
@@ -300,19 +325,82 @@ typedef struct {
uint8_tdrCTExtRec[12];/* extent record with size and location of catalog file */
}hfs_wrapper_sb;
/********* B-Tree data structures **********/
/* Node descriptor that starts each node in a B-tree */
// type values
#define HFS_BT_NODE_TYPE_LEAF -1
#define HFS_BT_NODE_TYPE_IDX 0
#define HFS_BT_NODE_TYPE_HEAD 1
#define HFS_BT_NODE_TYPE_MAP 2
// header that starts every B-tree node
typedefstruct{
uint8_tflink[4];/* node num of next node of same type */
uint8_tblink[4];/* node num of prev node of same type */
int8_ttype;/* type of this node */
uint8_theight;/* level in B-tree (0 for root, 1 for leaf) */
uint8_tnum_rec[2];/* number of records this node */
uint8_tres[2];/* reserved */
}hfs_btree_node;
/*****************/
// structure for the 1st record in the B-Tree header node
// type values
#define HFS_BT_HEAD_TYPE_CNTL 0 // control file (catalog, extents, attributes)
#define HFS_BT_HEAD_TYPE_USER 128 // hot file
#define HFS_BT_HEAD_TYPE_RSV 255
// compType values
#define HFS_BT_HEAD_COMP_SENS 0xCF // case sensitive
#define HFS_BT_HEAD_COMP_INSENS 0xBC // case insensitive
// attr values
#define HFS_BT_HEAD_ATTR_BIGKEYS 0x00000002 /* key length field is 16 bits (req'd for HFS+) */
#define HFS_BT_HEAD_ATTR_VARIDXKEYS 0x00000004 /* Keys in INDEX nodes are variable length */
// NOTE: VARIDXKEYS is required for the Catalog B-tree and cleared for the Extents B-tree
typedefstruct{
uint8_tkey_len[2];
uint8_tdepth[2];/* current depth of btree */
uint8_trootNode[4];/* node number of root node */
uint8_tleafRecords[4];/* number of records in leaf nodes */
uint8_tfirstLeafNode[4];/* number of first leaf node (0 if no leafs) */
uint8_tlastLeafNode[4];/* number of last leaf node (0 if no leafs) */
uint8_tnodesize[2];/* byte size of each node (512..32768) */
uint8_tmaxKeyLen[2];/* max key length in an index or leaf node */
uint8_ttotalNodes[4];/* number of nodes in btree (free or in use) */
uint8_tfreeNodes[4];/* unused nodes in btree */
uint8_tres[2];/* reserved */
uint8_tclumpSize[4];/* clump size */
uint8_ttype;/* btree type (control or user) */
uint8_tcompType;/* HFSX Only: identifies of key comparisons are case sensitive */
uint8_tattr[4];/* attributes */
uint8_tres2[64];/* reserved */
}hfs_btree_header_record;
/* key for category records */
typedefstruct{
uint8_tkey_len[2];// length of key minus 2
uint8_tparent_cnid[4];
hfs_uni_strname;
}hfs_cat_key;
}hfs_btree_key_cat;
/* Key for extents records */
typedefstruct{
uint8_tkey_len[2];
uint8_tkey_len[2];// length of key minus 2
uint8_tfork_type[1];
uint8_tpad[1];
uint8_tfile_id[4];
uint8_tstart_block[4];
}hfs_ext_key;
}hfs_btree_key_ext;
/* Record contents for index record after key */
typedefstruct{
uint8_tchildNode[4];
}hfs_btree_index_record;
typedefstruct{
uint32_tinum;/* inode number */
...
...
@@ -321,32 +409,8 @@ typedef struct {
TSK_DADDR_Toffs;/* offset of beginning of inode */
}htsk_fs_inode_mode_struct;
typedefstruct{
uint8_tflink[4];/* next node number */
uint8_tblink[4];/* previous node number */
int8_tkind;/* type of node */
uint8_theight;/* level in B-tree */
uint8_tnum_rec[2];/* number of records this node */
uint8_tres[2];/* reserved */
}hfs_btree_node;
typedefstruct{
uint8_tdepth[2];/* current depth of btree */
uint8_troot[4];/* node number of root node */
uint8_tleaf[4];/* number of records in leaf nodes */
uint8_tfirstleaf[4];/* number of first leaf node */
uint8_tlastleaf[4];/* number of last leaf node */
uint8_tnodesize[2];/* byte size of leaf node (512..32768) */
uint8_tmax_len[2];/* max key length in an index or leaf node */
uint8_ttotal[4];/* number of nodes in btree (free or in use) */