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