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