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