blob: bb6d50d4c1360abb42295e187b47a50d604af673 [file] [log] [blame]
/*
libparted - a library for manipulating disk partitions
Copyright (C) 2003, 2004, 2005 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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#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[1];
};
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 */