libhfs.h revision 1.3 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