diff options
Diffstat (limited to 'libparted/fs/hfs/hfs.h')
-rw-r--r-- | libparted/fs/hfs/hfs.h | 648 |
1 files changed, 648 insertions, 0 deletions
diff --git a/libparted/fs/hfs/hfs.h b/libparted/fs/hfs/hfs.h new file mode 100644 index 0000000..5b9138c --- /dev/null +++ b/libparted/fs/hfs/hfs.h @@ -0,0 +1,648 @@ +/* + libparted - a library for manipulating disk partitions + Copyright (C) 2003-2005, 2007, 2009-2014, 2019-2023 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _HFS_H +#define _HFS_H + +/* WARNING : bn is used 2 times in theses macro */ +/* so _never_ use side effect operators when using them */ +#define TST_BLOC_OCCUPATION(tab,bn) \ + (((tab)[(bn)/8]) & (1<<(7-((bn)&7)))) +#define SET_BLOC_OCCUPATION(tab,bn) \ + (((tab)[(bn)/8]) |= (1<<(7-((bn)&7)))) +#define CLR_BLOC_OCCUPATION(tab,bn) \ + (((tab)[(bn)/8]) &= ~(1<<(7-((bn)&7)))) + +/* Maximum number of blocks for the copy buffers */ +#define BLOCK_MAX_BUFF 256 +/* Maximum size of the copy buffers, in bytes */ +#define BYTES_MAX_BUFF 8388608 + +/* Apple Creator Codes follow */ +#define HFSP_IMPL_Shnk 0x53686e6b /* in use */ +#define HFSP_IMPL_Xpnd 0x58706e64 /* reserved */ +#define HFSP_IMPL_Resz 0x5265737a /* reserved */ +#define HFSP_IMPL_PHpx 0x50482b78 /* reserved */ +#define HFSP_IMPL_traP 0x74726150 /* reserved */ +#define HFSP_IMPL_GnuP 0x476e7550 /* reserved */ + +#define HFS_SIGNATURE 0x4244 /* 'BD' */ +#define HFSP_SIGNATURE 0x482B /* 'H+' */ +#define HFSX_SIGNATURE 0x4858 /* 'HX' */ + +#define HFSP_VERSION 4 +#define HFSX_VERSION 5 + +#define HFS_HARD_LOCK 7 +#define HFS_UNMOUNTED 8 +#define HFS_BAD_SPARED 9 +#define HFS_SOFT_LOCK 15 +#define HFSP_NO_CACHE 10 +#define HFSP_INCONSISTENT 11 +#define HFSP_REUSE_CNID 12 +#define HFSP_JOURNALED 13 + +#define HFS_IDX_NODE 0x00 +#define HFS_HDR_NODE 0x01 +#define HFS_MAP_NODE 0x02 +#define HFS_LEAF_NODE 0xFF + +#define HFS_FIRST_REC 0x0E +#define HFS_NSD_HD_REC 0x78 +#define HFS_MAP_REC 0xF8 + +#define HFS_DATA_FORK 0x00 +#define HFS_RES_FORK 0xFF + +#define HFS_CAT_DIR 0x01 +#define HFS_CAT_FILE 0x02 +#define HFS_CAT_DIR_TH 0x03 +#define HFS_CAT_FILE_TH 0x04 + +#define HFSP_ATTR_INLINE 0x10 +#define HFSP_ATTR_FORK 0x20 +#define HFSP_ATTR_EXTENTS 0x30 + +#define HFS_ROOT_PAR_ID 0x01 +#define HFS_ROOT_DIR_ID 0x02 +#define HFS_XTENT_ID 0x03 +#define HFS_CATALOG_ID 0x04 +#define HFS_BAD_BLOCK_ID 0x05 +#define HFSP_ALLOC_ID 0x06 +#define HFSP_STARTUP_ID 0x07 +#define HFSP_ATTRIB_ID 0x08 +#define HFSP_BOGUS_ID 0x0F +#define HFSP_FIRST_AV_ID 0x10 + +#define HFSJ_JOURN_IN_FS 0x00 +#define HFSJ_JOURN_OTHER_DEV 0x01 +#define HFSJ_JOURN_NEED_INIT 0x02 + +#define HFSJ_HEADER_MAGIC 0x4a4e4c78 +#define HFSJ_ENDIAN_MAGIC 0x12345678 + +#define HFSX_CASE_FOLDING 0xCF /* case insensitive HFSX */ +#define HFSX_BINARY_COMPARE 0xBC /* case sensitive HFSX */ + +#define HFS_EXT_NB 3 +#define HFSP_EXT_NB 8 + +/* Define the filenames used by the FS extractor */ +#ifdef HFS_EXTRACT_FS + +#define HFS_MDB_FILENAME "mdb.hfs" +#define HFS_CATALOG_FILENAME "catalog.hfs" +#define HFS_EXTENTS_FILENAME "extents.hfs" +#define HFS_BITMAP_FILENAME "bitmap.hfs" + +#define HFSP_VH_FILENAME "vh.hfsplus" +#define HFSP_CATALOG_FILENAME "catalog.hfsplus" +#define HFSP_EXTENTS_FILENAME "extents.hfsplus" +#define HFSP_BITMAP_FILENAME "bitmap.hfsplus" +#define HFSP_ATTRIB_FILENAME "attributes.hfsplus" +#define HFSP_STARTUP_FILENAME "startup.hfsplus" + +#endif /* HFS_EXTRACT_FS */ + + + +/* ----------------------------------- */ +/* -- HFS DATA STRUCTURES -- */ +/* ----------------------------------- */ + +/* Extent descriptor */ +struct __attribute__ ((packed)) _HfsExtDescriptor { + uint16_t start_block; + uint16_t block_count; +}; +typedef struct _HfsExtDescriptor HfsExtDescriptor; +typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB]; + +/* Volume header */ +struct __attribute__ ((packed)) _HfsMasterDirectoryBlock { + uint16_t signature; + uint32_t create_date; + uint32_t modify_date; + uint16_t volume_attributes; + uint16_t files_in_root; + uint16_t volume_bitmap_block; /* in sectors */ + uint16_t next_allocation; + uint16_t total_blocks; + uint32_t block_size; /* in bytes */ + uint32_t def_clump_size; /* in bytes */ + uint16_t start_block; /* in sectors */ + uint32_t next_free_node; + uint16_t free_blocks; + uint8_t name_length; + char name[27]; + uint32_t backup_date; + uint16_t backup_number; + uint32_t write_count; + uint32_t extents_clump; + uint32_t catalog_clump; + uint16_t dirs_in_root; + uint32_t file_count; + uint32_t dir_count; + uint32_t finder_info[8]; + union __attribute__ ((packed)) { + struct __attribute__ ((packed)) { + uint16_t volume_cache_size; /* in blocks */ + uint16_t bitmap_cache_size; /* in blocks */ + uint16_t common_cache_size; /* in blocks */ + } legacy; + struct __attribute__ ((packed)) { + uint16_t signature; + HfsExtDescriptor location; + } embedded; + } old_new; + uint32_t extents_file_size; /* in bytes, block size multiple */ + HfsExtDataRec extents_file_rec; + uint32_t catalog_file_size; /* in bytes, block size multiple */ + HfsExtDataRec catalog_file_rec; +}; +typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock; + +/* B*-Tree Node Descriptor */ +struct __attribute__ ((packed)) _HfsNodeDescriptor { + uint32_t next; + uint32_t previous; + int8_t type; + uint8_t height; + uint16_t rec_nb; + uint16_t reserved; +}; +typedef struct _HfsNodeDescriptor HfsNodeDescriptor; + +/* Header record of a whole B*-Tree */ +struct __attribute__ ((packed)) _HfsHeaderRecord { + uint16_t depth; + uint32_t root_node; + uint32_t leaf_records; + uint32_t first_leaf_node; + uint32_t last_leaf_node; + uint16_t node_size; + uint16_t max_key_len; + uint32_t total_nodes; + uint32_t free_nodes; + int8_t reserved[76]; +}; +typedef struct _HfsHeaderRecord HfsHeaderRecord; + +/* Catalog key for B*-Tree lookup in the catalog file */ +struct __attribute__ ((packed)) _HfsCatalogKey { + uint8_t key_length; /* length of the key without key_length */ + uint8_t reserved; + uint32_t parent_ID; + uint8_t name_length; + char name[31]; /* in fact physicaly 1 upto 31 */ +}; +typedef struct _HfsCatalogKey HfsCatalogKey; + +/* Extents overflow key for B*-Tree lookup */ +struct __attribute__ ((packed)) _HfsExtentKey { + uint8_t key_length; /* length of the key without key_length */ + uint8_t type; /* data or ressource fork */ + uint32_t file_ID; + uint16_t start; +}; +typedef struct _HfsExtentKey HfsExtentKey; + +/* Catalog subdata case directory */ +struct __attribute__ ((packed)) _HfsDir { + uint16_t flags; + uint16_t valence; /* number of files in this directory */ + uint32_t dir_ID; + uint32_t create_date; + uint32_t modify_date; + uint32_t backup_date; + int8_t DInfo[16]; /* used by Finder, handle as reserved */ + int8_t DXInfo[16]; /* used by Finder, handle as reserved */ + uint32_t reserved[4]; +}; +typedef struct _HfsDir HfsDir; + +/* Catalog subdata case file */ +struct __attribute__ ((packed)) _HfsFile { + int8_t flags; + int8_t type; /* should be 0 */ + int8_t FInfo[16]; /* used by Finder, handle as reserved */ + uint32_t file_ID; + uint16_t data_start_block; + uint32_t data_sz_byte; + uint32_t data_sz_block; + uint16_t res_start_block; + uint32_t res_sz_byte; + uint32_t res_sz_block; + uint32_t create_date; + uint32_t modify_date; + uint32_t backup_date; + int8_t FXInfo[16]; /* used by Finder, handle as reserved */ + uint16_t clump_size; + HfsExtDataRec extents_data; + HfsExtDataRec extents_res; + uint32_t reserved; +}; +typedef struct _HfsFile HfsFile; + +/* Catalog subdata case directory thread */ +struct __attribute__ ((packed)) _HfsDirTh { + uint32_t reserved[2]; + uint32_t parent_ID; + int8_t name_length; + char name[31]; +}; +typedef struct _HfsDirTh HfsDirTh; + +/* Catalog subdata case file thread */ +typedef struct _HfsDirTh HfsFileTh; /* same as directory thread */ + +/* Catalog data */ +struct __attribute__ ((packed)) _HfsCatalog { + int8_t type; + int8_t reserved; + union { + HfsDir dir; + HfsFile file; + HfsDirTh dir_th; + HfsFileTh file_th; + } sel; +}; +typedef struct _HfsCatalog HfsCatalog; + + + +/* ------------------------------------ */ +/* -- HFS+ DATA STRUCTURES -- */ +/* ------------------------------------ */ + +/* documented since 2004 in tn1150 */ +struct __attribute__ ((packed)) _HfsPPerms { + uint32_t owner_ID; + uint32_t group_ID; + uint32_t permissions; + uint32_t special_devices; +}; +typedef struct _HfsPPerms HfsPPerms; + +/* HFS+ extent descriptor*/ +struct __attribute__ ((packed)) _HfsPExtDescriptor { + uint32_t start_block; + uint32_t block_count; +}; +typedef struct _HfsPExtDescriptor HfsPExtDescriptor; +typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB]; + +/* HFS+ fork data structure */ +struct __attribute__ ((packed)) _HfsPForkData { + uint64_t logical_size; + uint32_t clump_size; + uint32_t total_blocks; + HfsPExtDataRec extents; +}; +typedef struct _HfsPForkData HfsPForkData; + +/* HFS+ catalog node ID */ +typedef uint32_t HfsPNodeID; + +/* HFS+ file names */ +typedef uint16_t unichar; +struct __attribute__ ((packed)) _HfsPUniStr255 { + uint16_t length; + unichar unicode[255]; /* 1 upto 255 */ +}; +typedef struct _HfsPUniStr255 HfsPUniStr255; + +/* HFS+ volume header */ +struct __attribute__ ((packed)) _HfsPVolumeHeader { + uint16_t signature; + uint16_t version; + uint32_t attributes; + uint32_t last_mounted_version; + uint32_t journal_info_block; + + uint32_t create_date; + uint32_t modify_date; + uint32_t backup_date; + uint32_t checked_date; + + uint32_t file_count; + uint32_t dir_count; + + uint32_t block_size; + uint32_t total_blocks; + uint32_t free_blocks; + + uint32_t next_allocation; + uint32_t res_clump_size; + uint32_t data_clump_size; + HfsPNodeID next_catalog_ID; + + uint32_t write_count; + uint64_t encodings_bitmap; + + uint8_t finder_info[32]; + + HfsPForkData allocation_file; + HfsPForkData extents_file; + HfsPForkData catalog_file; + HfsPForkData attributes_file; + HfsPForkData startup_file; +}; +typedef struct _HfsPVolumeHeader HfsPVolumeHeader; + +/* HFS+ B-Tree Node Descriptor. Same as HFS btree. */ +struct __attribute__ ((packed)) _HfsPNodeDescriptor { + uint32_t next; + uint32_t previous; + int8_t type; + uint8_t height; + uint16_t rec_nb; + uint16_t reserved; +}; +typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor; + +/* Header record of a whole HFS+ B-Tree. */ +struct __attribute__ ((packed)) _HfsPHeaderRecord { + uint16_t depth; + uint32_t root_node; + uint32_t leaf_records; + uint32_t first_leaf_node; + uint32_t last_leaf_node; + uint16_t node_size; + uint16_t max_key_len; + uint32_t total_nodes; + uint32_t free_nodes; /* same as hfs btree until here */ + uint16_t reserved1; + + uint32_t clump_size; + uint8_t btree_type; /* must be 0 for HFS+ B-Tree */ + uint8_t key_compare_type; /* hfsx => 0xCF = case folding */ + /* 0xBC = binary compare */ + /* otherwise, reserved */ + uint32_t attributes; + uint32_t reserved3[16]; +}; +typedef struct _HfsPHeaderRecord HfsPHeaderRecord; + +/* Catalog key for B-Tree lookup in the HFS+ catalog file */ +struct __attribute__ ((packed)) _HfsPCatalogKey { + uint16_t key_length; + HfsPNodeID parent_ID; + HfsPUniStr255 node_name; +}; +typedef struct _HfsPCatalogKey HfsPCatalogKey; + +/* HFS+ catalog subdata case dir */ +struct __attribute__ ((packed)) _HfsPDir { + uint16_t flags; + uint32_t valence; + HfsPNodeID dir_ID; + uint32_t create_date; + uint32_t modify_date; + uint32_t attrib_mod_date; + uint32_t access_date; + uint32_t backup_date; + HfsPPerms permissions; + int8_t DInfo[16]; /* used by Finder, handle as reserved */ + int8_t DXInfo[16]; /* used by Finder, handle as reserved */ + uint32_t text_encoding; + uint32_t reserved; +}; +typedef struct _HfsPDir HfsPDir; + +/* HFS+ catalog subdata case file */ +struct __attribute__ ((packed)) _HfsPFile { + uint16_t flags; + uint32_t reserved1; + HfsPNodeID file_ID; + uint32_t create_date; + uint32_t modify_date; + uint32_t attrib_mod_date; + uint32_t access_date; + uint32_t backup_date; + HfsPPerms permissions; + int8_t FInfo[16]; /* used by Finder, handle as reserved */ + int8_t FXInfo[16]; /* used by Finder, handle as reserved */ + uint32_t text_encoding; + uint32_t reserved2; + + HfsPForkData data_fork; + HfsPForkData res_fork; +}; +typedef struct _HfsPFile HfsPFile; + +/* HFS+ catalog subdata case thread */ +struct __attribute__ ((packed)) _HfsPThread { + int16_t reserved; + HfsPNodeID parent_ID; + HfsPUniStr255 node_name; +}; +typedef struct _HfsPThread HfsPDirTh; +typedef struct _HfsPThread HfsPFileTh; + +/* HFS+ Catalog leaf data */ +struct __attribute__ ((packed)) _HfsPCatalog { + int16_t type; + union { + HfsPDir dir; + HfsPFile file; + HfsPDirTh dir_th; + HfsPFileTh file_th; + } sel; +}; +typedef struct _HfsPCatalog HfsPCatalog; + +/* HFS+ extents file key */ +struct __attribute__ ((packed)) _HfsPExtentKey { + uint16_t key_length; + uint8_t type; + uint8_t pad; + HfsPNodeID file_ID; + uint32_t start; +}; +typedef struct _HfsPExtentKey HfsPExtentKey; + +/* extent file data is HfsPExtDataRec */ + +/* Fork data attribute file */ +struct __attribute__ ((packed)) _HfsPForkDataAttr { + uint32_t record_type; + uint32_t reserved; + union __attribute__ ((packed)) { + HfsPForkData fork; + HfsPExtDataRec extents; + } fork_res; +}; +typedef struct _HfsPForkDataAttr HfsPForkDataAttr; + + +/* ----------- Journal data structures ----------- */ + +/* Info block : stored in a block # defined in the VH */ +struct __attribute__ ((packed)) _HfsJJournalInfoBlock { + uint32_t flags; + uint32_t device_signature[8]; + uint64_t offset; + uint64_t size; + uint32_t reserved[32]; +}; +typedef struct _HfsJJournalInfoBlock HfsJJournalInfoBlock; + +struct __attribute__ ((packed)) _HfsJJournalHeader { + uint32_t magic; + uint32_t endian; + uint64_t start; + uint64_t end; + uint64_t size; + uint32_t blhdr_size; + uint32_t checksum; + uint32_t jhdr_size; +}; +typedef struct _HfsJJournalHeader HfsJJournalHeader; + +struct __attribute__ ((packed)) _HfsJBlockInfo { + uint64_t bnum; /* sector number */ + uint32_t bsize; /* size in bytes */ + uint32_t next; +}; +typedef struct _HfsJBlockInfo HfsJBlockInfo; + +struct __attribute__ ((packed)) _HfsJBlockListHeader { + uint16_t max_blocks; /* reserved */ + uint16_t num_blocks; + uint32_t bytes_used; + uint32_t checksum; + uint32_t pad; + HfsJBlockInfo binfo[]; +}; +typedef struct _HfsJBlockListHeader HfsJBlockListHeader; + + + +/* ---------------------------------------- */ +/* -- INTERNAL DATA STRUCTURES -- */ +/* ---------------------------------------- */ + +/* Data of an opened HFS file */ +struct _HfsPrivateFile { + PedSector sect_nb; + PedFileSystem* fs; + uint32_t CNID; /* disk order (BE) */ + HfsExtDataRec first; /* disk order (BE) */ + HfsExtDataRec cache; /* disk order (BE) */ + uint16_t start_cache; /* CPU order */ +}; +typedef struct _HfsPrivateFile HfsPrivateFile; + +/* To store bad block list */ +struct _HfsPrivateLinkExtent { + HfsExtDescriptor extent; + struct _HfsPrivateLinkExtent* next; +}; +typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent; + +/* HFS Filesystem specific data */ +struct _HfsPrivateFSData { + uint8_t alloc_map[(1<<16) / 8]; + HfsMasterDirectoryBlock* mdb; + HfsPrivateFile* extent_file; + HfsPrivateFile* catalog_file; + HfsPrivateLinkExtent* bad_blocks_xtent_list; + unsigned int bad_blocks_xtent_nb; + char bad_blocks_loaded; +}; +typedef struct _HfsPrivateFSData HfsPrivateFSData; + +/* Generic btree key */ +struct __attribute__ ((packed)) _HfsPrivateGenericKey { + uint8_t key_length; + uint8_t key_content[1]; /* we use 1 as a minimum size */ +}; +typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey; + +/* ----- HFS+ ----- */ + +/* Data of an opened HFS file */ +struct _HfsPPrivateFile { + PedSector sect_nb; + PedFileSystem* fs; + HfsPNodeID CNID; /* disk order (BE) */ + HfsPExtDataRec first; /* disk order (BE) */ + HfsPExtDataRec cache; /* disk order (BE) */ + uint32_t start_cache; /* CPU order */ +}; +typedef struct _HfsPPrivateFile HfsPPrivateFile; + +struct _HfsPPrivateExtent { + PedSector start_sector; + PedSector sector_count; +}; +typedef struct _HfsPPrivateExtent HfsPPrivateExtent; + +/* To store bad block list */ +struct _HfsPPrivateLinkExtent { + HfsPExtDescriptor extent; + struct _HfsPPrivateLinkExtent* next; +}; +typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent; + +/* HFS+ file system specific data */ +struct _HfsPPrivateFSData { + PedFileSystem* wrapper; /* NULL if hfs+ is not embedded */ + PedGeometry* plus_geom; /* Geometry of HFS+ _volume_ */ + uint8_t* alloc_map; + uint8_t* dirty_alloc_map; + HfsPVolumeHeader* vh; + HfsPPrivateFile* extents_file; + HfsPPrivateFile* catalog_file; + HfsPPrivateFile* attributes_file; + HfsPPrivateFile* allocation_file; + HfsPPrivateLinkExtent* bad_blocks_xtent_list; + uint32_t jib_start_block; + uint32_t jl_start_block; + unsigned int bad_blocks_xtent_nb; + char bad_blocks_loaded; + char free_geom; /* 1 = plus_geom must be freed */ +}; +typedef struct _HfsPPrivateFSData HfsPPrivateFSData; + +/* Generic + btree key */ +struct __attribute__ ((packed)) _HfsPPrivateGenericKey { + uint16_t key_length; + uint8_t key_content[1]; /* we use 1 as a minimum size */ +}; +typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey; + +/* ---- common ---- */ + +/* node and lead record reference for a BTree search */ +struct _HfsCPrivateLeafRec { + unsigned int node_size; /* in sectors */ + unsigned int node_number; + unsigned int record_pos; + unsigned int record_number; +}; +typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec; + +extern uint8_t* hfs_block; +extern uint8_t* hfsp_block; +extern unsigned hfs_block_count; +extern unsigned hfsp_block_count; + +#endif /* _HFS_H */ |