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