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