Home | History | Annotate | Line # | Download | only in hfs
libhfs.h revision 1.7
      1  1.7      maxv /*	$NetBSD: libhfs.h,v 1.7 2015/06/21 14:00:40 maxv Exp $	*/
      2  1.1     dillo 
      3  1.1     dillo /*-
      4  1.1     dillo  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
      5  1.1     dillo  * All rights reserved.
      6  1.1     dillo  *
      7  1.1     dillo  * This code is derived from software contributed to The NetBSD Foundation
      8  1.3     dillo  * by Yevgeny Binder, Dieter Baron, and Pelle Johansson.
      9  1.1     dillo  *
     10  1.1     dillo  * Redistribution and use in source and binary forms, with or without
     11  1.1     dillo  * modification, are permitted provided that the following conditions
     12  1.1     dillo  * are met:
     13  1.1     dillo  * 1. Redistributions of source code must retain the above copyright
     14  1.1     dillo  *    notice, this list of conditions and the following disclaimer.
     15  1.1     dillo  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1     dillo  *    notice, this list of conditions and the following disclaimer in the
     17  1.1     dillo  *    documentation and/or other materials provided with the distribution.
     18  1.1     dillo  *
     19  1.1     dillo  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1     dillo  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1     dillo  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1     dillo  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1     dillo  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1     dillo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1     dillo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1     dillo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1     dillo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1     dillo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1     dillo  * POSSIBILITY OF SUCH DAMAGE.
     30  1.7      maxv  */
     31  1.1     dillo 
     32  1.2     dillo #ifndef _FS_HFS_LIBHFS_H_
     33  1.2     dillo #define _FS_HFS_LIBHFS_H_
     34  1.1     dillo 
     35  1.1     dillo #include <sys/endian.h>
     36  1.1     dillo #include <sys/param.h>
     37  1.1     dillo #include <sys/mount.h>	/* needs to go after sys/param.h or compile fails */
     38  1.1     dillo #include <sys/types.h>
     39  1.1     dillo #if defined(_KERNEL)
     40  1.1     dillo #include <sys/kernel.h>
     41  1.1     dillo #include <sys/systm.h>
     42  1.1     dillo #include <sys/fcntl.h>
     43  1.1     dillo #endif /* defined(_KERNEL) */
     44  1.1     dillo 
     45  1.1     dillo #if !defined(_KERNEL) && !defined(STANDALONE)
     46  1.1     dillo #include <fcntl.h>
     47  1.1     dillo #include <iconv.h>
     48  1.1     dillo #include <stdarg.h>
     49  1.1     dillo #include <stdint.h>
     50  1.1     dillo #include <stdio.h>
     51  1.1     dillo #include <stdlib.h>
     52  1.1     dillo #include <unistd.h>
     53  1.1     dillo #endif /* !defined(_KERNEL) && !defined(STANDALONE) */
     54  1.1     dillo 
     55  1.1     dillo #define max(A,B) ((A) > (B) ? (A):(B))
     56  1.1     dillo #define min(A,B) ((A) < (B) ? (A):(B))
     57  1.1     dillo 
     58  1.1     dillo 
     59  1.2     dillo /* Macros to handle errors in this library. Not recommended outside libhfs.c */
     60  1.4  gmcgarry #ifdef __PCC__
     61  1.2     dillo #define HFS_LIBERR(format, ...) \
     62  1.4  gmcgarry 	do{ hfslib_error(format, __FILE__, __LINE__); \
     63  1.1     dillo 		goto error; } while(/*CONSTCOND*/ 0)
     64  1.4  gmcgarry #else
     65  1.4  gmcgarry #define HFS_LIBERR(format, ...) \
     66  1.4  gmcgarry 	do{ hfslib_error(format, __FILE__, __LINE__, ##__VA_ARGS__); \
     67  1.4  gmcgarry 		goto error; } while(/*CONSTCOND*/ 0)
     68  1.4  gmcgarry #endif
     69  1.1     dillo 
     70  1.1     dillo #if 0
     71  1.1     dillo #pragma mark Constants (on-disk)
     72  1.1     dillo #endif
     73  1.1     dillo 
     74  1.1     dillo 
     75  1.7      maxv enum {
     76  1.2     dillo 	HFS_SIG_HFSP	= 0x482B,	/* 'H+' */
     77  1.2     dillo 	HFS_SIG_HFSX	= 0x4858,	/* 'HX' */
     78  1.2     dillo 	HFS_SIG_HFS	= 0x4244	/* 'BD' */
     79  1.1     dillo }; /* volume signatures */
     80  1.1     dillo 
     81  1.7      maxv typedef enum {
     82  1.1     dillo 							/* bits 0-6 are reserved */
     83  1.2     dillo 	HFS_VOL_HWLOCK			= 7,
     84  1.2     dillo 	HFS_VOL_UNMOUNTED		= 8,
     85  1.2     dillo 	HFS_VOL_BADBLOCKS		= 9,
     86  1.2     dillo 	HFS_VOL_NOCACHE		= 10,
     87  1.2     dillo 	HFS_VOL_DIRTY			= 11,
     88  1.2     dillo 	HFS_VOL_CNIDS_RECYCLED	= 12,
     89  1.2     dillo 	HFS_VOL_JOURNALED		= 13,
     90  1.1     dillo 							/* bit 14 is reserved */
     91  1.2     dillo 	HFS_VOL_SWLOCK			= 15
     92  1.1     dillo 							/* bits 16-31 are reserved */
     93  1.2     dillo } hfs_volume_attribute_bit; /* volume header attribute bits */
     94  1.1     dillo 
     95  1.7      maxv typedef enum {
     96  1.2     dillo 	HFS_LEAFNODE	= -1,
     97  1.2     dillo 	HFS_INDEXNODE	= 0,
     98  1.2     dillo 	HFS_HEADERNODE	= 1,
     99  1.2     dillo 	HFS_MAPNODE	= 2
    100  1.2     dillo } hfs_node_kind; /* btree node kinds */
    101  1.1     dillo 
    102  1.7      maxv enum {
    103  1.2     dillo 	HFS_BAD_CLOSE_MASK			= 0x00000001,
    104  1.2     dillo 	HFS_BIG_KEYS_MASK			= 0x00000002,
    105  1.2     dillo 	HFS_VAR_INDEX_KEYS_MASK	= 0x00000004
    106  1.1     dillo }; /* btree header attribute masks */
    107  1.1     dillo 
    108  1.7      maxv typedef enum {
    109  1.2     dillo 	HFS_CNID_ROOT_PARENT	= 1,
    110  1.2     dillo 	HFS_CNID_ROOT_FOLDER	= 2,
    111  1.2     dillo 	HFS_CNID_EXTENTS		= 3,
    112  1.2     dillo 	HFS_CNID_CATALOG		= 4,
    113  1.2     dillo 	HFS_CNID_BADBLOCKS		= 5,
    114  1.2     dillo 	HFS_CNID_ALLOCATION	= 6,
    115  1.2     dillo 	HFS_CNID_STARTUP		= 7,
    116  1.2     dillo 	HFS_CNID_ATTRIBUTES	= 8,
    117  1.1     dillo 								/* CNIDs 9-13 are reserved */
    118  1.2     dillo 	HFS_CNID_REPAIR		= 14,
    119  1.2     dillo 	HFS_CNID_TEMP			= 15,
    120  1.2     dillo 	HFS_CNID_USER			= 16
    121  1.2     dillo } hfs_special_cnid; /* special CNID values */
    122  1.1     dillo 
    123  1.7      maxv typedef enum {
    124  1.2     dillo 	HFS_REC_FLDR			= 0x0001,
    125  1.2     dillo 	HFS_REC_FILE			= 0x0002,
    126  1.2     dillo 	HFS_REC_FLDR_THREAD	= 0x0003,
    127  1.2     dillo 	HFS_REC_FILE_THREAD	= 0x0004
    128  1.2     dillo } hfs_catalog_rec_kind; /* catalog record types */
    129  1.1     dillo 
    130  1.7      maxv enum {
    131  1.7      maxv 	HFS_JOURNAL_ON_DISK_MASK		= 0x00000001, /* journal on same volume */
    132  1.7      maxv 	HFS_JOURNAL_ON_OTHER_MASK		= 0x00000002, /* journal elsewhere */
    133  1.7      maxv 	HFS_JOURNAL_NEEDS_INIT_MASK	= 0x00000004
    134  1.1     dillo }; /* journal flag masks */
    135  1.1     dillo 
    136  1.7      maxv enum {
    137  1.2     dillo 	HFS_JOURNAL_HEADER_MAGIC	= 0x4a4e4c78,
    138  1.2     dillo 	HFS_JOURNAL_ENDIAN_MAGIC	= 0x12345678
    139  1.1     dillo }; /* journal magic numbers */
    140  1.1     dillo 
    141  1.7      maxv enum {
    142  1.2     dillo 	HFS_DATAFORK	= 0x00,
    143  1.2     dillo 	HFS_RSRCFORK	= 0xFF
    144  1.1     dillo }; /* common fork types */
    145  1.1     dillo 
    146  1.7      maxv enum {
    147  1.2     dillo 	HFS_KEY_CASEFOLD	= 0xCF,
    148  1.2     dillo 	HFS_KEY_BINARY		= 0XBC
    149  1.1     dillo }; /* catalog key comparison method types */
    150  1.1     dillo 
    151  1.7      maxv enum {
    152  1.2     dillo 	HFS_MIN_CAT_KEY_LEN	= 6,
    153  1.2     dillo 	HFS_MAX_CAT_KEY_LEN	= 516,
    154  1.2     dillo 	HFS_MAX_EXT_KEY_LEN	= 10
    155  1.1     dillo };
    156  1.1     dillo 
    157  1.1     dillo enum {
    158  1.7      maxv 	HFS_HARD_LINK_FILE_TYPE = 0x686C6E6B,  /* 'hlnk' */
    159  1.7      maxv 	HFS_HFSLUS_CREATOR     = 0x6866732B   /* 'hfs+' */
    160  1.1     dillo };
    161  1.1     dillo 
    162  1.1     dillo 
    163  1.1     dillo #if 0
    164  1.1     dillo #pragma mark -
    165  1.1     dillo #pragma mark Constants (custom)
    166  1.1     dillo #endif
    167  1.1     dillo 
    168  1.1     dillo 
    169  1.1     dillo /* number of bytes between start of volume and volume header */
    170  1.2     dillo #define HFS_VOLUME_HEAD_RESERVE_SIZE	1024
    171  1.1     dillo 
    172  1.7      maxv typedef enum {
    173  1.2     dillo 	HFS_CATALOG_FILE = 1,
    174  1.2     dillo 	HFS_EXTENTS_FILE = 2,
    175  1.2     dillo 	HFS_ATTRIBUTES_FILE = 3
    176  1.2     dillo } hfs_btree_file_type; /* btree file kinds */
    177  1.1     dillo 
    178  1.1     dillo 
    179  1.1     dillo #if 0
    180  1.1     dillo #pragma mark -
    181  1.1     dillo #pragma mark On-Disk Types (Mac OS specific)
    182  1.1     dillo #endif
    183  1.1     dillo 
    184  1.2     dillo typedef uint32_t	hfs_macos_type_code; /* four 1-byte char field */
    185  1.1     dillo 
    186  1.7      maxv typedef struct {
    187  1.7      maxv 	int16_t	v;
    188  1.7      maxv 	int16_t	h;
    189  1.2     dillo } hfs_macos_point_t;
    190  1.1     dillo 
    191  1.7      maxv typedef struct {
    192  1.7      maxv 	int16_t	t;	/* top */
    193  1.7      maxv 	int16_t	l;	/* left */
    194  1.7      maxv 	int16_t	b;	/* bottom */
    195  1.7      maxv 	int16_t	r;	/* right */
    196  1.2     dillo } hfs_macos_rect_t;
    197  1.1     dillo 
    198  1.7      maxv typedef struct {
    199  1.7      maxv 	hfs_macos_type_code	file_type;
    200  1.7      maxv 	hfs_macos_type_code	file_creator;
    201  1.7      maxv 	uint16_t				finder_flags;
    202  1.7      maxv 	hfs_macos_point_t	location;
    203  1.7      maxv 	uint16_t				reserved;
    204  1.2     dillo } hfs_macos_file_info_t;
    205  1.1     dillo 
    206  1.7      maxv typedef struct {
    207  1.7      maxv 	int16_t	reserved[4];
    208  1.7      maxv 	uint16_t	extended_finder_flags;
    209  1.7      maxv 	int16_t	reserved2;
    210  1.7      maxv 	int32_t	put_away_folder_cnid;
    211  1.2     dillo } hfs_macos_extended_file_info_t;
    212  1.1     dillo 
    213  1.7      maxv typedef struct {
    214  1.7      maxv 	hfs_macos_rect_t		window_bounds;
    215  1.7      maxv 	uint16_t				finder_flags;
    216  1.7      maxv 	hfs_macos_point_t	location;
    217  1.7      maxv 	uint16_t				reserved;
    218  1.2     dillo } hfs_macos_folder_info_t;
    219  1.1     dillo 
    220  1.7      maxv typedef struct {
    221  1.7      maxv 	hfs_macos_point_t	scroll_position;
    222  1.7      maxv 	int32_t				reserved;
    223  1.7      maxv 	uint16_t				extended_finder_flags;
    224  1.7      maxv 	int16_t				reserved2;
    225  1.7      maxv 	int32_t				put_away_folder_cnid;
    226  1.2     dillo } hfs_macos_extended_folder_info_t;
    227  1.1     dillo 
    228  1.1     dillo 
    229  1.1     dillo #if 0
    230  1.1     dillo #pragma mark -
    231  1.1     dillo #pragma mark On-Disk Types
    232  1.1     dillo #endif
    233  1.1     dillo 
    234  1.1     dillo typedef uint16_t unichar_t;
    235  1.1     dillo 
    236  1.2     dillo typedef uint32_t hfs_cnid_t;
    237  1.1     dillo 
    238  1.7      maxv typedef struct {
    239  1.1     dillo 	uint16_t	length;
    240  1.1     dillo 	unichar_t	unicode[255];
    241  1.2     dillo } hfs_unistr255_t;
    242  1.1     dillo 
    243  1.7      maxv typedef struct {
    244  1.1     dillo 	uint32_t	start_block;
    245  1.1     dillo 	uint32_t	block_count;
    246  1.2     dillo } hfs_extent_descriptor_t;
    247  1.1     dillo 
    248  1.2     dillo typedef hfs_extent_descriptor_t hfs_extent_record_t[8];
    249  1.1     dillo 
    250  1.7      maxv typedef struct hfs_fork_t {
    251  1.1     dillo 	uint64_t				logical_size;
    252  1.1     dillo 	uint32_t				clump_size;
    253  1.1     dillo 	uint32_t				total_blocks;
    254  1.2     dillo 	hfs_extent_record_t	extents;
    255  1.2     dillo } hfs_fork_t;
    256  1.7      maxv 
    257  1.7      maxv typedef struct {
    258  1.1     dillo 	uint16_t	signature;
    259  1.1     dillo 	uint16_t	version;
    260  1.1     dillo 	uint32_t	attributes;
    261  1.1     dillo 	uint32_t	last_mounting_version;
    262  1.1     dillo 	uint32_t	journal_info_block;
    263  1.7      maxv 
    264  1.1     dillo 	uint32_t	date_created;
    265  1.1     dillo 	uint32_t	date_modified;
    266  1.1     dillo 	uint32_t	date_backedup;
    267  1.1     dillo 	uint32_t	date_checked;
    268  1.7      maxv 
    269  1.1     dillo 	uint32_t	file_count;
    270  1.1     dillo 	uint32_t	folder_count;
    271  1.7      maxv 
    272  1.1     dillo 	uint32_t	block_size;
    273  1.1     dillo 	uint32_t	total_blocks;
    274  1.1     dillo 	uint32_t	free_blocks;
    275  1.7      maxv 
    276  1.1     dillo 	uint32_t	next_alloc_block;
    277  1.1     dillo 	uint32_t	rsrc_clump_size;
    278  1.1     dillo 	uint32_t	data_clump_size;
    279  1.2     dillo 	hfs_cnid_t	next_cnid;
    280  1.7      maxv 
    281  1.1     dillo 	uint32_t	write_count;
    282  1.1     dillo 	uint64_t	encodings;
    283  1.7      maxv 
    284  1.1     dillo 	uint32_t	finder_info[8];
    285  1.7      maxv 
    286  1.2     dillo 	hfs_fork_t	allocation_file;
    287  1.2     dillo 	hfs_fork_t	extents_file;
    288  1.2     dillo 	hfs_fork_t	catalog_file;
    289  1.2     dillo 	hfs_fork_t	attributes_file;
    290  1.2     dillo 	hfs_fork_t	startup_file;
    291  1.2     dillo } hfs_volume_header_t;
    292  1.1     dillo 
    293  1.7      maxv typedef struct {
    294  1.1     dillo 	uint32_t	flink;
    295  1.1     dillo 	uint32_t	blink;
    296  1.1     dillo 	int8_t		kind;
    297  1.1     dillo 	uint8_t		height;
    298  1.1     dillo 	uint16_t	num_recs;
    299  1.1     dillo 	uint16_t	reserved;
    300  1.2     dillo } hfs_node_descriptor_t;
    301  1.1     dillo 
    302  1.7      maxv typedef struct {
    303  1.1     dillo 	uint16_t	tree_depth;
    304  1.1     dillo 	uint32_t	root_node;
    305  1.1     dillo 	uint32_t	leaf_recs;
    306  1.1     dillo 	uint32_t	first_leaf;
    307  1.1     dillo 	uint32_t	last_leaf;
    308  1.1     dillo 	uint16_t	node_size;
    309  1.1     dillo 	uint16_t	max_key_len;
    310  1.1     dillo 	uint32_t	total_nodes;
    311  1.1     dillo 	uint32_t	free_nodes;
    312  1.1     dillo 	uint16_t	reserved;
    313  1.1     dillo 	uint32_t	clump_size;		/* misaligned */
    314  1.1     dillo 	uint8_t		btree_type;
    315  1.1     dillo 	uint8_t		keycomp_type;
    316  1.1     dillo 	uint32_t	attributes;		/* long aligned again */
    317  1.1     dillo 	uint32_t	reserved2[16];
    318  1.2     dillo } hfs_header_record_t;
    319  1.1     dillo 
    320  1.7      maxv typedef struct {
    321  1.1     dillo 	uint16_t			key_len;
    322  1.2     dillo 	hfs_cnid_t			parent_cnid;
    323  1.2     dillo 	hfs_unistr255_t	name;
    324  1.2     dillo } hfs_catalog_key_t;
    325  1.1     dillo 
    326  1.7      maxv typedef struct {
    327  1.1     dillo 	uint16_t	key_length;
    328  1.1     dillo 	uint8_t		fork_type;
    329  1.1     dillo 	uint8_t		padding;
    330  1.2     dillo 	hfs_cnid_t	file_cnid;
    331  1.1     dillo 	uint32_t	start_block;
    332  1.2     dillo } hfs_extent_key_t;
    333  1.1     dillo 
    334  1.7      maxv typedef struct {
    335  1.1     dillo 	uint32_t	owner_id;
    336  1.1     dillo 	uint32_t	group_id;
    337  1.1     dillo 	uint8_t		admin_flags;
    338  1.1     dillo 	uint8_t		owner_flags;
    339  1.1     dillo 	uint16_t	file_mode;
    340  1.7      maxv 	union {
    341  1.1     dillo 		uint32_t	inode_num;
    342  1.1     dillo 		uint32_t	link_count;
    343  1.1     dillo 		uint32_t	raw_device;
    344  1.1     dillo 	} special;
    345  1.2     dillo } hfs_bsd_data_t;
    346  1.1     dillo 
    347  1.7      maxv typedef struct {
    348  1.1     dillo 	int16_t			rec_type;
    349  1.1     dillo 	uint16_t		flags;
    350  1.1     dillo 	uint32_t		valence;
    351  1.2     dillo 	hfs_cnid_t		cnid;
    352  1.1     dillo 	uint32_t		date_created;
    353  1.1     dillo 	uint32_t		date_content_mod;
    354  1.1     dillo 	uint32_t		date_attrib_mod;
    355  1.1     dillo 	uint32_t		date_accessed;
    356  1.1     dillo 	uint32_t		date_backedup;
    357  1.2     dillo 	hfs_bsd_data_t						bsd;
    358  1.2     dillo 	hfs_macos_folder_info_t			user_info;
    359  1.2     dillo 	hfs_macos_extended_folder_info_t	finder_info;
    360  1.1     dillo 	uint32_t		text_encoding;
    361  1.1     dillo 	uint32_t		reserved;
    362  1.2     dillo } hfs_folder_record_t;
    363  1.1     dillo 
    364  1.7      maxv typedef struct {
    365  1.1     dillo 	int16_t			rec_type;
    366  1.1     dillo 	uint16_t		flags;
    367  1.1     dillo 	uint32_t		reserved;
    368  1.2     dillo 	hfs_cnid_t		cnid;
    369  1.1     dillo 	uint32_t		date_created;
    370  1.1     dillo 	uint32_t		date_content_mod;
    371  1.1     dillo 	uint32_t		date_attrib_mod;
    372  1.1     dillo 	uint32_t		date_accessed;
    373  1.1     dillo 	uint32_t		date_backedup;
    374  1.2     dillo 	hfs_bsd_data_t						bsd;
    375  1.2     dillo 	hfs_macos_file_info_t				user_info;
    376  1.2     dillo 	hfs_macos_extended_file_info_t		finder_info;
    377  1.1     dillo 	uint32_t		text_encoding;
    378  1.1     dillo 	uint32_t		reserved2;
    379  1.2     dillo 	hfs_fork_t		data_fork;
    380  1.2     dillo 	hfs_fork_t		rsrc_fork;
    381  1.2     dillo } hfs_file_record_t;
    382  1.1     dillo 
    383  1.7      maxv typedef struct {
    384  1.1     dillo 	int16_t				rec_type;
    385  1.1     dillo 	int16_t				reserved;
    386  1.2     dillo 	hfs_cnid_t			parent_cnid;
    387  1.2     dillo 	hfs_unistr255_t	name;
    388  1.2     dillo } hfs_thread_record_t;
    389  1.1     dillo 
    390  1.7      maxv typedef struct {
    391  1.1     dillo 	uint32_t	flags;
    392  1.1     dillo 	uint32_t	device_signature[8];
    393  1.1     dillo 	uint64_t	offset;
    394  1.1     dillo 	uint64_t	size;
    395  1.1     dillo 	uint64_t	reserved[32];
    396  1.2     dillo } hfs_journal_info_t;
    397  1.1     dillo 
    398  1.7      maxv typedef struct {
    399  1.1     dillo 	uint32_t	magic;
    400  1.1     dillo 	uint32_t	endian;
    401  1.1     dillo 	uint64_t	start;
    402  1.1     dillo 	uint64_t	end;
    403  1.1     dillo 	uint64_t	size;
    404  1.1     dillo 	uint32_t	blocklist_header_size;
    405  1.1     dillo 	uint32_t	checksum;
    406  1.1     dillo 	uint32_t	journal_header_size;
    407  1.2     dillo } hfs_journal_header_t;
    408  1.1     dillo 
    409  1.3     dillo /* plain HFS structures needed for hfs wrapper support */
    410  1.3     dillo 
    411  1.7      maxv typedef struct {
    412  1.7      maxv 	uint16_t        start_block;
    413  1.7      maxv 	uint16_t        block_count;
    414  1.3     dillo } hfs_hfs_extent_descriptor_t;
    415  1.3     dillo 
    416  1.3     dillo typedef hfs_hfs_extent_descriptor_t hfs_hfs_extent_record_t[3];
    417  1.3     dillo 
    418  1.7      maxv typedef struct {
    419  1.7      maxv 	uint16_t        signature;
    420  1.7      maxv 	uint32_t        date_created;
    421  1.7      maxv 	uint32_t        date_modified;
    422  1.7      maxv 	uint16_t        attributes;
    423  1.7      maxv 	uint16_t        root_file_count;
    424  1.7      maxv 	uint16_t        volume_bitmap;
    425  1.7      maxv 	uint16_t        next_alloc_block;
    426  1.7      maxv 	uint16_t        total_blocks;
    427  1.7      maxv 	uint32_t        block_size;
    428  1.7      maxv 	uint32_t        clump_size;
    429  1.7      maxv 	uint16_t        first_block;
    430  1.7      maxv 	hfs_cnid_t      next_cnid;
    431  1.7      maxv 	uint16_t        free_blocks;
    432  1.7      maxv 	unsigned char   volume_name[28];
    433  1.7      maxv 	uint32_t        date_backedup;
    434  1.7      maxv 	uint16_t        backup_seqnum;
    435  1.7      maxv 	uint32_t        write_count;
    436  1.7      maxv 	uint32_t        extents_clump_size;
    437  1.7      maxv 	uint32_t        catalog_clump_size;
    438  1.7      maxv 	uint16_t        root_folder_count;
    439  1.7      maxv 	uint32_t        file_count;
    440  1.7      maxv 	uint32_t        folder_count;
    441  1.7      maxv 	uint32_t        finder_info[8];
    442  1.7      maxv 	uint16_t        embedded_signature;
    443  1.7      maxv 	hfs_hfs_extent_descriptor_t embedded_extent;
    444  1.7      maxv 	uint32_t        extents_size;
    445  1.7      maxv 	hfs_hfs_extent_record_t extents_extents;
    446  1.7      maxv 	uint32_t        catalog_size;
    447  1.7      maxv 	hfs_hfs_extent_record_t catalog_extents;
    448  1.3     dillo } hfs_hfs_master_directory_block_t;
    449  1.3     dillo 
    450  1.1     dillo #if 0
    451  1.1     dillo #pragma mark -
    452  1.1     dillo #pragma mark Custom Types
    453  1.1     dillo #endif
    454  1.1     dillo 
    455  1.7      maxv typedef struct {
    456  1.2     dillo 	hfs_volume_header_t	vh;		/* volume header */
    457  1.2     dillo 	hfs_header_record_t	chr;	/* catalog file header node record*/
    458  1.2     dillo 	hfs_header_record_t	ehr;	/* extent overflow file header node record*/
    459  1.1     dillo 	uint8_t	catkeysizefieldsize;	/* size of catalog file key_len field in
    460  1.1     dillo 									 * bytes (1 or 2); always 2 for HFS+ */
    461  1.1     dillo 	uint8_t	extkeysizefieldsize;	/* size of extent file key_len field in
    462  1.1     dillo 									 * bytes (1 or 2); always 2 for HFS+ */
    463  1.2     dillo 	hfs_unistr255_t		name;	/* volume name */
    464  1.1     dillo 
    465  1.1     dillo 	/* pointer to catalog file key comparison function */
    466  1.1     dillo 	int (*keycmp) (const void*, const void*);
    467  1.1     dillo 
    468  1.1     dillo 	int						journaled;	/* 1 if volume is journaled, else 0 */
    469  1.2     dillo 	hfs_journal_info_t		jib;	/* journal info block */
    470  1.2     dillo 	hfs_journal_header_t	jh;		/* journal header */
    471  1.1     dillo 
    472  1.3     dillo 	uint64_t offset;	/* offset, in bytes, of HFS+ volume */
    473  1.1     dillo 	int		readonly;	/* 0 if mounted r/w, 1 if mounted r/o */
    474  1.1     dillo 	void*	cbdata;		/* application-specific data; allocated, defined and
    475  1.1     dillo 						 * used (if desired) by the program, usually within
    476  1.1     dillo 						 * callback routines */
    477  1.2     dillo } hfs_volume;
    478  1.1     dillo 
    479  1.7      maxv typedef union {
    480  1.1     dillo 	/* for leaf nodes */
    481  1.1     dillo 	int16_t					type; /* type of record: folder, file, or thread */
    482  1.2     dillo 	hfs_folder_record_t	folder;
    483  1.2     dillo 	hfs_file_record_t		file;
    484  1.2     dillo 	hfs_thread_record_t	thread;
    485  1.7      maxv 
    486  1.1     dillo 	/* for pointer nodes */
    487  1.1     dillo 	/* (using this large union for just one tiny field is not memory-efficient,
    488  1.1     dillo 	 *	 so change this if it becomes problematic) */
    489  1.1     dillo 	uint32_t	child;	/* node number of this node's child node */
    490  1.2     dillo } hfs_catalog_keyed_record_t;
    491  1.1     dillo 
    492  1.1     dillo /*
    493  1.2     dillo  * These arguments are passed among libhfs without any inspection. This struct
    494  1.2     dillo  * is accepted by all public functions of libhfs, and passed to each callback.
    495  1.1     dillo  * An application dereferences each pointer to its own specific struct of
    496  1.1     dillo  * arguments. Callbacks must be prepared to deal with NULL values for any of
    497  1.1     dillo  * these fields (by providing default values to be used in lieu of that
    498  1.1     dillo  * argument). However, a NULL pointer to this struct is an error.
    499  1.1     dillo  *
    500  1.1     dillo  * It was decided to make one unified argument structure, rather than many
    501  1.1     dillo  * separate, operand-specific structures, because, when this structure is passed
    502  1.2     dillo  * to a public function (e.g., hfslib_open_volume()), the function may make
    503  1.1     dillo  * several calls (and subcalls) to various facilities, e.g., read(), malloc(),
    504  1.1     dillo  * and free(), all of which require their own particular arguments. The
    505  1.1     dillo  * facilities to be used are quite impractical to foreshadow, so the application
    506  1.1     dillo  * takes care of all possible calls at once. This also reinforces the idea that
    507  1.1     dillo  * a public call is an umbrella to a set of system calls, and all of these calls
    508  1.1     dillo  * must be passed arguments which do not change within the context of this
    509  1.1     dillo  * umbrella. (E.g., if a public function makes two calls to read(), one call
    510  1.1     dillo  * should not be passed a uid of root and the other passed a uid of daemon.)
    511  1.1     dillo  */
    512  1.7      maxv typedef struct {
    513  1.1     dillo 	/* The 'error' function does not take an argument. All others do. */
    514  1.7      maxv 
    515  1.1     dillo 	void*	allocmem;
    516  1.1     dillo 	void*	reallocmem;
    517  1.1     dillo 	void*	freemem;
    518  1.1     dillo 	void*	openvol;
    519  1.1     dillo 	void*	closevol;
    520  1.1     dillo 	void*	read;
    521  1.2     dillo } hfs_callback_args;
    522  1.1     dillo 
    523  1.7      maxv typedef struct {
    524  1.1     dillo 	/* error(in_format, in_file, in_line, in_args) */
    525  1.1     dillo 	void (*error) (const char*, const char*, int, va_list);
    526  1.7      maxv 
    527  1.1     dillo 	/* allocmem(in_size, cbargs) */
    528  1.2     dillo 	void* (*allocmem) (size_t, hfs_callback_args*);
    529  1.7      maxv 
    530  1.1     dillo 	/* reallocmem(in_ptr, in_size, cbargs) */
    531  1.2     dillo 	void* (*reallocmem) (void*, size_t, hfs_callback_args*);
    532  1.7      maxv 
    533  1.1     dillo 	/* freemem(in_ptr, cbargs) */
    534  1.2     dillo 	void (*freemem) (void*, hfs_callback_args*);
    535  1.7      maxv 
    536  1.3     dillo 	/* openvol(in_volume, in_devicepath, cbargs)
    537  1.1     dillo 	 * returns 0 on success */
    538  1.3     dillo 	int (*openvol) (hfs_volume*, const char*, hfs_callback_args*);
    539  1.7      maxv 
    540  1.1     dillo 	/* closevol(in_volume, cbargs) */
    541  1.2     dillo 	void (*closevol) (hfs_volume*, hfs_callback_args*);
    542  1.7      maxv 
    543  1.1     dillo 	/* read(in_volume, out_buffer, in_length, in_offset, cbargs)
    544  1.1     dillo 	 * returns 0 on success */
    545  1.2     dillo 	int (*read) (hfs_volume*, void*, uint64_t, uint64_t,
    546  1.2     dillo 		hfs_callback_args*);
    547  1.2     dillo } hfs_callbacks;
    548  1.1     dillo 
    549  1.6      matt extern hfs_callbacks	hfs_gcb;	/* global callbacks */
    550  1.1     dillo 
    551  1.1     dillo /*
    552  1.1     dillo  * global case folding table
    553  1.2     dillo  * (lazily initialized; see comments at bottom of hfs_open_volume())
    554  1.1     dillo  */
    555  1.6      matt extern unichar_t* hfs_gcft;
    556  1.1     dillo 
    557  1.1     dillo #if 0
    558  1.1     dillo #pragma mark -
    559  1.1     dillo #pragma mark Functions
    560  1.1     dillo #endif
    561  1.1     dillo 
    562  1.2     dillo void hfslib_init(hfs_callbacks*);
    563  1.2     dillo void hfslib_done(void);
    564  1.2     dillo void hfslib_init_cbargs(hfs_callback_args*);
    565  1.2     dillo 
    566  1.3     dillo int hfslib_open_volume(const char*, int, hfs_volume*,
    567  1.2     dillo 	hfs_callback_args*);
    568  1.2     dillo void hfslib_close_volume(hfs_volume*, hfs_callback_args*);
    569  1.2     dillo 
    570  1.2     dillo int hfslib_path_to_cnid(hfs_volume*, hfs_cnid_t, char**, uint16_t*,
    571  1.2     dillo 	hfs_callback_args*);
    572  1.2     dillo hfs_cnid_t hfslib_find_parent_thread(hfs_volume*, hfs_cnid_t,
    573  1.2     dillo 	hfs_thread_record_t*, hfs_callback_args*);
    574  1.2     dillo int hfslib_find_catalog_record_with_cnid(hfs_volume*, hfs_cnid_t,
    575  1.2     dillo 	hfs_catalog_keyed_record_t*, hfs_catalog_key_t*, hfs_callback_args*);
    576  1.2     dillo int hfslib_find_catalog_record_with_key(hfs_volume*, hfs_catalog_key_t*,
    577  1.2     dillo 	hfs_catalog_keyed_record_t*, hfs_callback_args*);
    578  1.2     dillo int hfslib_find_extent_record_with_key(hfs_volume*, hfs_extent_key_t*,
    579  1.2     dillo 	hfs_extent_record_t*, hfs_callback_args*);
    580  1.2     dillo int hfslib_get_directory_contents(hfs_volume*, hfs_cnid_t,
    581  1.2     dillo 	hfs_catalog_keyed_record_t**, hfs_unistr255_t**, uint32_t*,
    582  1.2     dillo 	hfs_callback_args*);
    583  1.2     dillo int hfslib_is_journal_clean(hfs_volume*);
    584  1.2     dillo int hfslib_is_private_file(hfs_catalog_key_t*);
    585  1.2     dillo 
    586  1.2     dillo int hfslib_get_hardlink(hfs_volume *, uint32_t,
    587  1.2     dillo 			 hfs_catalog_keyed_record_t *, hfs_callback_args *);
    588  1.2     dillo 
    589  1.2     dillo size_t hfslib_read_volume_header(void*, hfs_volume_header_t*);
    590  1.3     dillo size_t hfslib_read_master_directory_block(void*,
    591  1.3     dillo 	hfs_hfs_master_directory_block_t*);
    592  1.2     dillo size_t hfslib_reada_node(void*, hfs_node_descriptor_t*, void***, uint16_t**,
    593  1.2     dillo 	hfs_btree_file_type, hfs_volume*, hfs_callback_args*);
    594  1.2     dillo size_t hfslib_reada_node_offsets(void*, uint16_t*);
    595  1.2     dillo size_t hfslib_read_header_node(void**, uint16_t*, uint16_t,
    596  1.2     dillo 	hfs_header_record_t*, void*, void*);
    597  1.2     dillo size_t hfslib_read_catalog_keyed_record(void*, hfs_catalog_keyed_record_t*,
    598  1.2     dillo 	int16_t*, hfs_catalog_key_t*, hfs_volume*);
    599  1.2     dillo size_t hfslib_read_extent_record(void*, hfs_extent_record_t*, hfs_node_kind,
    600  1.2     dillo 	hfs_extent_key_t*, hfs_volume*);
    601  1.2     dillo void hfslib_free_recs(void***, uint16_t**, uint16_t*, hfs_callback_args*);
    602  1.2     dillo 
    603  1.2     dillo size_t hfslib_read_fork_descriptor(void*, hfs_fork_t*);
    604  1.2     dillo size_t hfslib_read_extent_descriptors(void*, hfs_extent_record_t*);
    605  1.2     dillo size_t hfslib_read_unistr255(void*, hfs_unistr255_t*);
    606  1.2     dillo size_t hfslib_read_bsd_data(void*, hfs_bsd_data_t*);
    607  1.2     dillo size_t hfslib_read_file_userinfo(void*, hfs_macos_file_info_t*);
    608  1.2     dillo size_t hfslib_read_file_finderinfo(void*, hfs_macos_extended_file_info_t*);
    609  1.2     dillo size_t hfslib_read_folder_userinfo(void*, hfs_macos_folder_info_t*);
    610  1.2     dillo size_t hfslib_read_folder_finderinfo(void*, hfs_macos_extended_folder_info_t*);
    611  1.2     dillo size_t hfslib_read_journal_info(void*, hfs_journal_info_t*);
    612  1.2     dillo size_t hfslib_read_journal_header(void*, hfs_journal_header_t*);
    613  1.2     dillo 
    614  1.2     dillo uint16_t hfslib_make_catalog_key(hfs_cnid_t, uint16_t, unichar_t*,
    615  1.2     dillo 	hfs_catalog_key_t*);
    616  1.2     dillo uint16_t hfslib_make_extent_key(hfs_cnid_t, uint8_t, uint32_t,
    617  1.2     dillo 	hfs_extent_key_t*);
    618  1.2     dillo uint16_t hfslib_get_file_extents(hfs_volume*, hfs_cnid_t, uint8_t,
    619  1.2     dillo 	hfs_extent_descriptor_t**, hfs_callback_args*);
    620  1.2     dillo int hfslib_readd_with_extents(hfs_volume*, void*, uint64_t*, uint64_t,
    621  1.2     dillo 	uint64_t, hfs_extent_descriptor_t*, uint16_t, hfs_callback_args*);
    622  1.2     dillo 
    623  1.2     dillo int hfslib_compare_catalog_keys_cf(const void*, const void*);
    624  1.2     dillo int hfslib_compare_catalog_keys_bc(const void*, const void*);
    625  1.2     dillo int hfslib_compare_extent_keys(const void*, const void*);
    626  1.1     dillo 
    627  1.1     dillo 
    628  1.1     dillo /* callback wrappers */
    629  1.2     dillo void hfslib_error(const char*, const char*, int, ...) __attribute__ ((format (printf, 1, 4)));
    630  1.2     dillo void* hfslib_malloc(size_t, hfs_callback_args*);
    631  1.2     dillo void* hfslib_realloc(void*, size_t, hfs_callback_args*);
    632  1.2     dillo void hfslib_free(void*, hfs_callback_args*);
    633  1.3     dillo int hfslib_openvoldevice(hfs_volume*, const char*, hfs_callback_args*);
    634  1.2     dillo void hfslib_closevoldevice(hfs_volume*, hfs_callback_args*);
    635  1.2     dillo int hfslib_readd(hfs_volume*, void*, uint64_t, uint64_t, hfs_callback_args*);
    636  1.1     dillo 
    637  1.2     dillo #endif /* !_FS_HFS_LIBHFS_H_ */
    638