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