Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
/*	$NetBSD: libhfs.h,v 1.8 2019/01/05 10:25:11 maya Exp $	*/

/*-
 * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Yevgeny Binder, Dieter Baron, and Pelle Johansson.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _FS_HFS_LIBHFS_H_
#define _FS_HFS_LIBHFS_H_

#include <sys/endian.h>
#include <sys/param.h>
#include <sys/mount.h>	/* needs to go after sys/param.h or compile fails */
#include <sys/types.h>
#if defined(_KERNEL)
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#endif /* defined(_KERNEL) */

#if !defined(_KERNEL) && !defined(STANDALONE)
#include <fcntl.h>
#include <iconv.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif /* !defined(_KERNEL) && !defined(STANDALONE) */

#define max(A,B) ((A) > (B) ? (A):(B))
#define min(A,B) ((A) < (B) ? (A):(B))


/* Macros to handle errors in this library. Not recommended outside libhfs.c */
#define HFS_LIBERR(format, ...) \
	do{ hfslib_error(format, __FILE__, __LINE__, ##__VA_ARGS__); \
		goto error; } while(/*CONSTCOND*/ 0)

#if 0
#pragma mark Constants (on-disk)
#endif


enum {
	HFS_SIG_HFSP	= 0x482B,	/* 'H+' */
	HFS_SIG_HFSX	= 0x4858,	/* 'HX' */
	HFS_SIG_HFS	= 0x4244	/* 'BD' */
}; /* volume signatures */

typedef enum {
							/* bits 0-6 are reserved */
	HFS_VOL_HWLOCK			= 7,
	HFS_VOL_UNMOUNTED		= 8,
	HFS_VOL_BADBLOCKS		= 9,
	HFS_VOL_NOCACHE		= 10,
	HFS_VOL_DIRTY			= 11,
	HFS_VOL_CNIDS_RECYCLED	= 12,
	HFS_VOL_JOURNALED		= 13,
							/* bit 14 is reserved */
	HFS_VOL_SWLOCK			= 15
							/* bits 16-31 are reserved */
} hfs_volume_attribute_bit; /* volume header attribute bits */

typedef enum {
	HFS_LEAFNODE	= -1,
	HFS_INDEXNODE	= 0,
	HFS_HEADERNODE	= 1,
	HFS_MAPNODE	= 2
} hfs_node_kind; /* btree node kinds */

enum {
	HFS_BAD_CLOSE_MASK			= 0x00000001,
	HFS_BIG_KEYS_MASK			= 0x00000002,
	HFS_VAR_INDEX_KEYS_MASK	= 0x00000004
}; /* btree header attribute masks */

typedef enum {
	HFS_CNID_ROOT_PARENT	= 1,
	HFS_CNID_ROOT_FOLDER	= 2,
	HFS_CNID_EXTENTS		= 3,
	HFS_CNID_CATALOG		= 4,
	HFS_CNID_BADBLOCKS		= 5,
	HFS_CNID_ALLOCATION	= 6,
	HFS_CNID_STARTUP		= 7,
	HFS_CNID_ATTRIBUTES	= 8,
								/* CNIDs 9-13 are reserved */
	HFS_CNID_REPAIR		= 14,
	HFS_CNID_TEMP			= 15,
	HFS_CNID_USER			= 16
} hfs_special_cnid; /* special CNID values */

typedef enum {
	HFS_REC_FLDR			= 0x0001,
	HFS_REC_FILE			= 0x0002,
	HFS_REC_FLDR_THREAD	= 0x0003,
	HFS_REC_FILE_THREAD	= 0x0004
} hfs_catalog_rec_kind; /* catalog record types */

enum {
	HFS_JOURNAL_ON_DISK_MASK		= 0x00000001, /* journal on same volume */
	HFS_JOURNAL_ON_OTHER_MASK		= 0x00000002, /* journal elsewhere */
	HFS_JOURNAL_NEEDS_INIT_MASK	= 0x00000004
}; /* journal flag masks */

enum {
	HFS_JOURNAL_HEADER_MAGIC	= 0x4a4e4c78,
	HFS_JOURNAL_ENDIAN_MAGIC	= 0x12345678
}; /* journal magic numbers */

enum {
	HFS_DATAFORK	= 0x00,
	HFS_RSRCFORK	= 0xFF
}; /* common fork types */

enum {
	HFS_KEY_CASEFOLD	= 0xCF,
	HFS_KEY_BINARY		= 0XBC
}; /* catalog key comparison method types */

enum {
	HFS_MIN_CAT_KEY_LEN	= 6,
	HFS_MAX_CAT_KEY_LEN	= 516,
	HFS_MAX_EXT_KEY_LEN	= 10
};

enum {
	HFS_HARD_LINK_FILE_TYPE = 0x686C6E6B,  /* 'hlnk' */
	HFS_HFSLUS_CREATOR     = 0x6866732B   /* 'hfs+' */
};


#if 0
#pragma mark -
#pragma mark Constants (custom)
#endif


/* number of bytes between start of volume and volume header */
#define HFS_VOLUME_HEAD_RESERVE_SIZE	1024

typedef enum {
	HFS_CATALOG_FILE = 1,
	HFS_EXTENTS_FILE = 2,
	HFS_ATTRIBUTES_FILE = 3
} hfs_btree_file_type; /* btree file kinds */


#if 0
#pragma mark -
#pragma mark On-Disk Types (Mac OS specific)
#endif

typedef uint32_t	hfs_macos_type_code; /* four 1-byte char field */

typedef struct {
	int16_t	v;
	int16_t	h;
} hfs_macos_point_t;

typedef struct {
	int16_t	t;	/* top */
	int16_t	l;	/* left */
	int16_t	b;	/* bottom */
	int16_t	r;	/* right */
} hfs_macos_rect_t;

typedef struct {
	hfs_macos_type_code	file_type;
	hfs_macos_type_code	file_creator;
	uint16_t				finder_flags;
	hfs_macos_point_t	location;
	uint16_t				reserved;
} hfs_macos_file_info_t;

typedef struct {
	int16_t	reserved[4];
	uint16_t	extended_finder_flags;
	int16_t	reserved2;
	int32_t	put_away_folder_cnid;
} hfs_macos_extended_file_info_t;

typedef struct {
	hfs_macos_rect_t		window_bounds;
	uint16_t				finder_flags;
	hfs_macos_point_t	location;
	uint16_t				reserved;
} hfs_macos_folder_info_t;

typedef struct {
	hfs_macos_point_t	scroll_position;
	int32_t				reserved;
	uint16_t				extended_finder_flags;
	int16_t				reserved2;
	int32_t				put_away_folder_cnid;
} hfs_macos_extended_folder_info_t;


#if 0
#pragma mark -
#pragma mark On-Disk Types
#endif

typedef uint16_t unichar_t;

typedef uint32_t hfs_cnid_t;

typedef struct {
	uint16_t	length;
	unichar_t	unicode[255];
} hfs_unistr255_t;

typedef struct {
	uint32_t	start_block;
	uint32_t	block_count;
} hfs_extent_descriptor_t;

typedef hfs_extent_descriptor_t hfs_extent_record_t[8];

typedef struct hfs_fork_t {
	uint64_t				logical_size;
	uint32_t				clump_size;
	uint32_t				total_blocks;
	hfs_extent_record_t	extents;
} hfs_fork_t;

typedef struct {
	uint16_t	signature;
	uint16_t	version;
	uint32_t	attributes;
	uint32_t	last_mounting_version;
	uint32_t	journal_info_block;

	uint32_t	date_created;
	uint32_t	date_modified;
	uint32_t	date_backedup;
	uint32_t	date_checked;

	uint32_t	file_count;
	uint32_t	folder_count;

	uint32_t	block_size;
	uint32_t	total_blocks;
	uint32_t	free_blocks;

	uint32_t	next_alloc_block;
	uint32_t	rsrc_clump_size;
	uint32_t	data_clump_size;
	hfs_cnid_t	next_cnid;

	uint32_t	write_count;
	uint64_t	encodings;

	uint32_t	finder_info[8];

	hfs_fork_t	allocation_file;
	hfs_fork_t	extents_file;
	hfs_fork_t	catalog_file;
	hfs_fork_t	attributes_file;
	hfs_fork_t	startup_file;
} hfs_volume_header_t;

typedef struct {
	uint32_t	flink;
	uint32_t	blink;
	int8_t		kind;
	uint8_t		height;
	uint16_t	num_recs;
	uint16_t	reserved;
} hfs_node_descriptor_t;

typedef struct {
	uint16_t	tree_depth;
	uint32_t	root_node;
	uint32_t	leaf_recs;
	uint32_t	first_leaf;
	uint32_t	last_leaf;
	uint16_t	node_size;
	uint16_t	max_key_len;
	uint32_t	total_nodes;
	uint32_t	free_nodes;
	uint16_t	reserved;
	uint32_t	clump_size;		/* misaligned */
	uint8_t		btree_type;
	uint8_t		keycomp_type;
	uint32_t	attributes;		/* long aligned again */
	uint32_t	reserved2[16];
} hfs_header_record_t;

typedef struct {
	uint16_t			key_len;
	hfs_cnid_t			parent_cnid;
	hfs_unistr255_t	name;
} hfs_catalog_key_t;

typedef struct {
	uint16_t	key_length;
	uint8_t		fork_type;
	uint8_t		padding;
	hfs_cnid_t	file_cnid;
	uint32_t	start_block;
} hfs_extent_key_t;

typedef struct {
	uint32_t	owner_id;
	uint32_t	group_id;
	uint8_t		admin_flags;
	uint8_t		owner_flags;
	uint16_t	file_mode;
	union {
		uint32_t	inode_num;
		uint32_t	link_count;
		uint32_t	raw_device;
	} special;
} hfs_bsd_data_t;

typedef struct {
	int16_t			rec_type;
	uint16_t		flags;
	uint32_t		valence;
	hfs_cnid_t		cnid;
	uint32_t		date_created;
	uint32_t		date_content_mod;
	uint32_t		date_attrib_mod;
	uint32_t		date_accessed;
	uint32_t		date_backedup;
	hfs_bsd_data_t						bsd;
	hfs_macos_folder_info_t			user_info;
	hfs_macos_extended_folder_info_t	finder_info;
	uint32_t		text_encoding;
	uint32_t		reserved;
} hfs_folder_record_t;

typedef struct {
	int16_t			rec_type;
	uint16_t		flags;
	uint32_t		reserved;
	hfs_cnid_t		cnid;
	uint32_t		date_created;
	uint32_t		date_content_mod;
	uint32_t		date_attrib_mod;
	uint32_t		date_accessed;
	uint32_t		date_backedup;
	hfs_bsd_data_t						bsd;
	hfs_macos_file_info_t				user_info;
	hfs_macos_extended_file_info_t		finder_info;
	uint32_t		text_encoding;
	uint32_t		reserved2;
	hfs_fork_t		data_fork;
	hfs_fork_t		rsrc_fork;
} hfs_file_record_t;

typedef struct {
	int16_t				rec_type;
	int16_t				reserved;
	hfs_cnid_t			parent_cnid;
	hfs_unistr255_t	name;
} hfs_thread_record_t;

typedef struct {
	uint32_t	flags;
	uint32_t	device_signature[8];
	uint64_t	offset;
	uint64_t	size;
	uint64_t	reserved[32];
} hfs_journal_info_t;

typedef struct {
	uint32_t	magic;
	uint32_t	endian;
	uint64_t	start;
	uint64_t	end;
	uint64_t	size;
	uint32_t	blocklist_header_size;
	uint32_t	checksum;
	uint32_t	journal_header_size;
} hfs_journal_header_t;

/* plain HFS structures needed for hfs wrapper support */

typedef struct {
	uint16_t        start_block;
	uint16_t        block_count;
} hfs_hfs_extent_descriptor_t;

typedef hfs_hfs_extent_descriptor_t hfs_hfs_extent_record_t[3];

typedef struct {
	uint16_t        signature;
	uint32_t        date_created;
	uint32_t        date_modified;
	uint16_t        attributes;
	uint16_t        root_file_count;
	uint16_t        volume_bitmap;
	uint16_t        next_alloc_block;
	uint16_t        total_blocks;
	uint32_t        block_size;
	uint32_t        clump_size;
	uint16_t        first_block;
	hfs_cnid_t      next_cnid;
	uint16_t        free_blocks;
	unsigned char   volume_name[28];
	uint32_t        date_backedup;
	uint16_t        backup_seqnum;
	uint32_t        write_count;
	uint32_t        extents_clump_size;
	uint32_t        catalog_clump_size;
	uint16_t        root_folder_count;
	uint32_t        file_count;
	uint32_t        folder_count;
	uint32_t        finder_info[8];
	uint16_t        embedded_signature;
	hfs_hfs_extent_descriptor_t embedded_extent;
	uint32_t        extents_size;
	hfs_hfs_extent_record_t extents_extents;
	uint32_t        catalog_size;
	hfs_hfs_extent_record_t catalog_extents;
} hfs_hfs_master_directory_block_t;

#if 0
#pragma mark -
#pragma mark Custom Types
#endif

typedef struct {
	hfs_volume_header_t	vh;		/* volume header */
	hfs_header_record_t	chr;	/* catalog file header node record*/
	hfs_header_record_t	ehr;	/* extent overflow file header node record*/
	uint8_t	catkeysizefieldsize;	/* size of catalog file key_len field in
									 * bytes (1 or 2); always 2 for HFS+ */
	uint8_t	extkeysizefieldsize;	/* size of extent file key_len field in
									 * bytes (1 or 2); always 2 for HFS+ */
	hfs_unistr255_t		name;	/* volume name */

	/* pointer to catalog file key comparison function */
	int (*keycmp) (const void*, const void*);

	int						journaled;	/* 1 if volume is journaled, else 0 */
	hfs_journal_info_t		jib;	/* journal info block */
	hfs_journal_header_t	jh;		/* journal header */

	uint64_t offset;	/* offset, in bytes, of HFS+ volume */
	int		readonly;	/* 0 if mounted r/w, 1 if mounted r/o */
	void*	cbdata;		/* application-specific data; allocated, defined and
						 * used (if desired) by the program, usually within
						 * callback routines */
} hfs_volume;

typedef union {
	/* for leaf nodes */
	int16_t					type; /* type of record: folder, file, or thread */
	hfs_folder_record_t	folder;
	hfs_file_record_t		file;
	hfs_thread_record_t	thread;

	/* for pointer nodes */
	/* (using this large union for just one tiny field is not memory-efficient,
	 *	 so change this if it becomes problematic) */ 
	uint32_t	child;	/* node number of this node's child node */
} hfs_catalog_keyed_record_t;

/*
 * These arguments are passed among libhfs without any inspection. This struct
 * is accepted by all public functions of libhfs, and passed to each callback.
 * An application dereferences each pointer to its own specific struct of
 * arguments. Callbacks must be prepared to deal with NULL values for any of
 * these fields (by providing default values to be used in lieu of that
 * argument). However, a NULL pointer to this struct is an error.
 *
 * It was decided to make one unified argument structure, rather than many
 * separate, operand-specific structures, because, when this structure is passed
 * to a public function (e.g., hfslib_open_volume()), the function may make
 * several calls (and subcalls) to various facilities, e.g., read(), malloc(),
 * and free(), all of which require their own particular arguments. The
 * facilities to be used are quite impractical to foreshadow, so the application
 * takes care of all possible calls at once. This also reinforces the idea that
 * a public call is an umbrella to a set of system calls, and all of these calls
 * must be passed arguments which do not change within the context of this
 * umbrella. (E.g., if a public function makes two calls to read(), one call
 * should not be passed a uid of root and the other passed a uid of daemon.)
 */
typedef struct {
	/* The 'error' function does not take an argument. All others do. */

	void*	allocmem;
	void*	reallocmem;
	void*	freemem;
	void*	openvol;
	void*	closevol;
	void*	read;
} hfs_callback_args;

typedef struct {
	/* error(in_format, in_file, in_line, in_args) */
	void (*error) (const char*, const char*, int, va_list);

	/* allocmem(in_size, cbargs) */
	void* (*allocmem) (size_t, hfs_callback_args*);

	/* reallocmem(in_ptr, in_size, cbargs) */
	void* (*reallocmem) (void*, size_t, hfs_callback_args*);

	/* freemem(in_ptr, cbargs) */
	void (*freemem) (void*, hfs_callback_args*);

	/* openvol(in_volume, in_devicepath, cbargs)
	 * returns 0 on success */
	int (*openvol) (hfs_volume*, const char*, hfs_callback_args*);

	/* closevol(in_volume, cbargs) */
	void (*closevol) (hfs_volume*, hfs_callback_args*);

	/* read(in_volume, out_buffer, in_length, in_offset, cbargs)
	 * returns 0 on success */
	int (*read) (hfs_volume*, void*, uint64_t, uint64_t,
		hfs_callback_args*);
} hfs_callbacks;

extern hfs_callbacks	hfs_gcb;	/* global callbacks */

/*
 * global case folding table
 * (lazily initialized; see comments at bottom of hfs_open_volume())
 */
extern unichar_t* hfs_gcft;

#if 0
#pragma mark -
#pragma mark Functions
#endif

void hfslib_init(hfs_callbacks*);
void hfslib_done(void);
void hfslib_init_cbargs(hfs_callback_args*);

int hfslib_open_volume(const char*, int, hfs_volume*,
	hfs_callback_args*);
void hfslib_close_volume(hfs_volume*, hfs_callback_args*);

int hfslib_path_to_cnid(hfs_volume*, hfs_cnid_t, char**, uint16_t*,
	hfs_callback_args*);
hfs_cnid_t hfslib_find_parent_thread(hfs_volume*, hfs_cnid_t,
	hfs_thread_record_t*, hfs_callback_args*);
int hfslib_find_catalog_record_with_cnid(hfs_volume*, hfs_cnid_t,
	hfs_catalog_keyed_record_t*, hfs_catalog_key_t*, hfs_callback_args*);
int hfslib_find_catalog_record_with_key(hfs_volume*, hfs_catalog_key_t*,
	hfs_catalog_keyed_record_t*, hfs_callback_args*);
int hfslib_find_extent_record_with_key(hfs_volume*, hfs_extent_key_t*,
	hfs_extent_record_t*, hfs_callback_args*);
int hfslib_get_directory_contents(hfs_volume*, hfs_cnid_t,
	hfs_catalog_keyed_record_t**, hfs_unistr255_t**, uint32_t*,
	hfs_callback_args*);
int hfslib_is_journal_clean(hfs_volume*);
int hfslib_is_private_file(hfs_catalog_key_t*);

int hfslib_get_hardlink(hfs_volume *, uint32_t,
			 hfs_catalog_keyed_record_t *, hfs_callback_args *);

size_t hfslib_read_volume_header(void*, hfs_volume_header_t*);
size_t hfslib_read_master_directory_block(void*,
	hfs_hfs_master_directory_block_t*);
size_t hfslib_reada_node(void*, hfs_node_descriptor_t*, void***, uint16_t**,
	hfs_btree_file_type, hfs_volume*, hfs_callback_args*);
size_t hfslib_reada_node_offsets(void*, uint16_t*);
size_t hfslib_read_header_node(void**, uint16_t*, uint16_t,
	hfs_header_record_t*, void*, void*);
size_t hfslib_read_catalog_keyed_record(void*, hfs_catalog_keyed_record_t*,
	int16_t*, hfs_catalog_key_t*, hfs_volume*);
size_t hfslib_read_extent_record(void*, hfs_extent_record_t*, hfs_node_kind,
	hfs_extent_key_t*, hfs_volume*);
void hfslib_free_recs(void***, uint16_t**, uint16_t*, hfs_callback_args*);

size_t hfslib_read_fork_descriptor(void*, hfs_fork_t*);
size_t hfslib_read_extent_descriptors(void*, hfs_extent_record_t*);
size_t hfslib_read_unistr255(void*, hfs_unistr255_t*);
size_t hfslib_read_bsd_data(void*, hfs_bsd_data_t*);
size_t hfslib_read_file_userinfo(void*, hfs_macos_file_info_t*);
size_t hfslib_read_file_finderinfo(void*, hfs_macos_extended_file_info_t*);
size_t hfslib_read_folder_userinfo(void*, hfs_macos_folder_info_t*);
size_t hfslib_read_folder_finderinfo(void*, hfs_macos_extended_folder_info_t*);
size_t hfslib_read_journal_info(void*, hfs_journal_info_t*);
size_t hfslib_read_journal_header(void*, hfs_journal_header_t*);

uint16_t hfslib_make_catalog_key(hfs_cnid_t, uint16_t, unichar_t*,
	hfs_catalog_key_t*);
uint16_t hfslib_make_extent_key(hfs_cnid_t, uint8_t, uint32_t,
	hfs_extent_key_t*);
uint16_t hfslib_get_file_extents(hfs_volume*, hfs_cnid_t, uint8_t,
	hfs_extent_descriptor_t**, hfs_callback_args*);
int hfslib_readd_with_extents(hfs_volume*, void*, uint64_t*, uint64_t,
	uint64_t, hfs_extent_descriptor_t*, uint16_t, hfs_callback_args*);

int hfslib_compare_catalog_keys_cf(const void*, const void*);
int hfslib_compare_catalog_keys_bc(const void*, const void*);
int hfslib_compare_extent_keys(const void*, const void*);


/* callback wrappers */
void hfslib_error(const char*, const char*, int, ...) __attribute__ ((format (printf, 1, 4)));
void* hfslib_malloc(size_t, hfs_callback_args*);
void* hfslib_realloc(void*, size_t, hfs_callback_args*);
void hfslib_free(void*, hfs_callback_args*);
int hfslib_openvoldevice(hfs_volume*, const char*, hfs_callback_args*);
void hfslib_closevoldevice(hfs_volume*, hfs_callback_args*);
int hfslib_readd(hfs_volume*, void*, uint64_t, uint64_t, hfs_callback_args*);

#endif /* !_FS_HFS_LIBHFS_H_ */