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