/usr/include/tsk/fs/tsk_hfs.h is in libtsk-dev 4.4.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 | /*
** The Sleuth Kit
**
** This software is subject to the IBM Public License ver. 1.0,
** which was displayed prior to download and is included in the readme.txt
** file accompanying the Sleuth Kit files. It may also be requested from:
** Crucial Security Inc.
** 14900 Conference Center Drive
** Chantilly, VA 20151
**
**
** Copyright (c) 2009-2011 Brian Carrier. All rights reserved.
**
** Judson Powers [jpowers@atc-nycorp.com]
** Matt Stillerman [matt@atc-nycorp.com]
** Copyright (c) 2008, 2012 ATC-NY. All rights reserved.
** This file contains data developed with support from the National
** Institute of Justice, Office of Justice Programs, U.S. Department of Justice.
**
** Wyatt Banks [wbanks@crucialsecurity.com]
** Copyright (c) 2005 Crucial Security Inc. All rights reserved.
**
** Brian Carrier [carrier@sleuthkit.org]
** Copyright (c) 2003-2005 Brian Carrier. All rights reserved
**
** Copyright (c) 1997,1998,1999, International Business Machines
** Corporation and others. All Rights Reserved.
*/
/* TCT
* LICENSE
* This software is distributed under the IBM Public License.
* AUTHOR(S)
* Wietse Venema
* IBM T.J. Watson Research
* P.O. Box 704
* Yorktown Heights, NY 10598, USA
--*/
/*
** You may distribute the Sleuth Kit, or other software that incorporates
** part of all of the Sleuth Kit, in object code form under a license agreement,
** provided that:
** a) you comply with the terms and conditions of the IBM Public License
** ver 1.0; and
** b) the license agreement
** i) effectively disclaims on behalf of all Contributors all warranties
** and conditions, express and implied, including warranties or
** conditions of title and non-infringement, and implied warranties
** or conditions of merchantability and fitness for a particular
** purpose.
** ii) effectively excludes on behalf of all Contributors liability for
** damages, including direct, indirect, special, incidental and
** consequential damages such as lost profits.
** iii) states that any provisions which differ from IBM Public License
** ver. 1.0 are offered by that Contributor alone and not by any
** other party; and
** iv) states that the source code for the program is available from you,
** and informs licensees how to obtain it in a reasonable manner on or
** through a medium customarily used for software exchange.
**
** When the Sleuth Kit or other software that incorporates part or all of
** the Sleuth Kit is made available in source code form:
** a) it must be made available under IBM Public License ver. 1.0; and
** b) a copy of the IBM Public License ver. 1.0 must be included with
** each copy of the program.
*/
/**
* Contains the structures and function APIs for HFS+ file system support.
*/
#ifndef _TSK_HFS_H
#define _TSK_HFS_H
/*
* Some compilers do not have the boolean type.
*/
#ifndef TRUE
#define TRUE ((unsigned char)1)
#endif
#ifndef FALSE
#define FALSE ((unsigned char)0)
#endif
/*
* All structures created using technote 1150 from Apple.com
* http://developer.apple.com/technotes/tn/tn1150.html
*/
/*
* Constants
*/
#define HFS_FILE_CONTENT_LEN 160 /* size of two hfs_fork data structures */
#define HFS_MAXNAMLEN 765 /* maximum HFS+ name length in bytes, when encoded in UTF8, not including terminating null */
#define HFS_MAXPATHLEN 1024 /* HFS+ can have paths longer than this, but Apple's implementation limits certain items to this value (e.g., symlink targets) */
/*
* HFS uses its own time system, which is seconds since Jan 1 1904
* instead of the typical Jan 1 1970. This number is the seconds between
* 1 Jan 1904 and 1 Jan 1970 which will make ctime(3) work instead of
* re-writing the Apple library function to convert this time.
*/
#define NSEC_BTWN_1904_1970 (uint32_t) 2082844800U
/**
* These two constants are the "ID" of the data fork and resource fork as TSK attributes. By the way,
* those attributes both have type TSK_FS_ATTR_TYPE_NTFS_DATA, which is a bit counter-intuitive.
*/
#define HFS_FS_ATTR_ID_DATA 0
#define HFS_FS_ATTR_ID_RSRC 1
/* predefined files */
#define HFS_ROOT_PARENT_ID 1
#define HFS_ROOT_FOLDER_ID 2
#define HFS_EXTENTS_FILE_ID 3 // extents overflow file
#define HFS_EXTENTS_FILE_NAME "$ExtentsFile"
#define HFS_CATALOG_FILE_ID 4 // catalog file
#define HFS_CATALOG_FILE_NAME "$CatalogFile"
#define HFS_BAD_BLOCK_FILE_ID 5
#define HFS_BAD_BLOCK_FILE_NAME "$BadBlockFile"
#define HFS_ALLOCATION_FILE_ID 6 // allocation file (HFS+)
#define HFS_ALLOCATION_FILE_NAME "$AllocationFile"
#define HFS_STARTUP_FILE_ID 7 // startup file (HFS+)
#define HFS_STARTUP_FILE_NAME "$StartupFile"
#define HFS_ATTRIBUTES_FILE_ID 8 // Attributes file (HFS+)
#define HFS_ATTRIBUTES_FILE_NAME "$AttributesFile"
#define HFS_REPAIR_CATALOG_FILE_ID 14 // Temp file during fsck
#define HFS_REPAIR_CATALOG_FILE_NAME "$RepairCatalogFile"
#define HFS_BOGUS_EXTENT_FILE_ID 15 // Temp file during fsck
#define HFS_BOGUS_EXTENT_FILE_NAME "$BogusExtentFile"
#define HFS_FIRST_USER_CNID 16
#define HFS_ROOT_INUM HFS_ROOT_FOLDER_ID
#define HFS_HARDLINK_FILE_TYPE 0x686C6E6B /* hlnk */
#define HFS_HARDLINK_FILE_CREATOR 0x6866732B /* hfs+ */
#define HFS_LINKDIR_FILE_TYPE 0x66647270 /* fdrp */
#define HFS_LINKDIR_FILE_CREATOR 0x4D414353 /* MACS */
#define UTF16_NULL 0x0000
#define UTF16_NULL_REPLACE 0x005e
// This is the standard Unicode replacement character in UTF16
//#define UTF16_NULL_REPLACE 0xfffd
#define UTF16_SLASH 0x002f
#define UTF16_COLON 0x003a
#define UTF16_LEAST_PRINTABLE 0x0020
#define UTF8_NULL_REPLACE "^"
// This is the standard Unicode replacement character in UTF8
//#define UTF8_NULL_REPLACE "\xef\xbf\xbd"
#define HFS_CATALOGNAME "$CatalogFile"
#define HFS_EXTENTSNAME "$ExtentsFile"
#define HFS_ALLOCATIONNAME "$BitMapFile"
#define HFS_STARTUPNAME "$BootFile"
#define HFS_ATTRIBUTESNAME "$AttributesFile"
/**
* B-Tree Node Types
*/
#define HFS_ATTR_NODE_LEAF -1
#define HFS_ATTR_NODE_HEADER 1
#define HFS_ATTR_NODE_INDEX 0
#define HFS_ATTR_NODE_MAP 2
/*
* HFS structures
*/
/* File and Folder name struct */
typedef struct {
uint8_t length[2];
uint8_t unicode[510];
} hfs_uni_str;
/* access permissions */
// admin flag values
#define HFS_PERM_AFLAG_ARCHIVED 0x01 /* file has been archived */
#define HFS_PERM_AFLAG_IMMUTABLE 0x02 /* file may not be changed */
#define HFS_PERM_AFLAG_APPEND 0x04 /* writes to file may only append */
// owner flag values
#define HFS_PERM_OFLAG_NODUMP 0x01 /* do not dump (back up or archive) this file */
#define HFS_PERM_OFLAG_IMMUTABLE 0x02 /* file may not be changed */
#define HFS_PERM_OFLAG_APPEND 0x04 /* writes to file may only append */
#define HFS_PERM_OFLAG_OPAQUE 0x08 /* directory is opaque */
#define HFS_PERM_OFLAG_COMPRESSED 0x20 /* file is HFS-compressed (see 10.6 sys/stat.h) */
// mode flag values
#define HFS_IN_ISUID 0004000 /* set user id */
#define HFS_IN_ISGID 0002000 /* set group id */
#define HFS_IN_ISVTX 0001000 /* sticky bit (directories only) */
#define HFS_IN_IRUSR 0000400 /* R for user */
#define HFS_IN_IWUSR 0000200 /* W for user */
#define HFS_IN_IXUSR 0000100 /* X for user */
#define HFS_IN_IRGRP 0000040 /* R for group */
#define HFS_IN_IWGRP 0000020 /* W for group */
#define HFS_IN_IXGRP 0000010 /* X for group */
#define HFS_IN_IROTH 0000004 /* R for other */
#define HFS_IN_IWOTH 0000002 /* W for other */
#define HFS_IN_IXOTH 0000001 /* X for other */
#define HFS_IN_IFMT 0170000 /* filetype mask */
#define HFS_IN_IFIFO 0010000 /* named pipe */
#define HFS_IN_IFCHR 0020000 /* character special */
#define HFS_IN_IFDIR 0040000 /* directory */
#define HFS_IN_IFBLK 0060000 /* block special */
#define HFS_IN_IFREG 0100000 /* regular file */
#define HFS_IN_IFLNK 0120000 /* symbolic link */
#define HFS_IN_IFSOCK 0140000 /* socket */
#define HFS_IFWHT 0160000 /* whiteout */
#define HFS_IFXATTR 0200000 /* extended attributes */
typedef struct {
uint8_t owner[4]; /* file owner */
uint8_t group[4]; /* file group */
uint8_t a_flags; /* admin flags */
uint8_t o_flags; /* owner flags */
uint8_t mode[2]; /* file mode */
union {
uint8_t inum[4]; /* inode number (for hard link files) */
uint8_t nlink[4]; /* link count (for direct node files) */
uint8_t raw[4]; /* device id (for block and char device files) */
} special;
} hfs_access_perm;
/* HFS extent descriptor */
typedef struct {
uint8_t start_blk[4]; /* start block */
uint8_t blk_cnt[4]; /* block count */
} hfs_ext_desc;
/* Structure used in the extents tree */
typedef struct {
hfs_ext_desc extents[8];
} hfs_extents;
/* Fork data structure. This is used in both the volume header and catalog tree. */
typedef struct {
uint8_t logic_sz[8]; /* The size (in bytes) of the fork */
uint8_t clmp_sz[4]; /* For "special files" in volume header, clump size. For
* catalog files, this is number of blocks read or not used. */
uint8_t total_blk[4]; /* total blocks in all extents of the fork */
hfs_ext_desc extents[8];
} hfs_fork;
/****************************************************
* Super block / volume header
*/
#define HFS_VH_OFF 1024 // byte offset in volume to volume header
// signature values
#define HFS_VH_SIG_HFS 0x4244 /* BD in big endian */
#define HFS_VH_SIG_HFSPLUS 0x482b /* H+ in big endian */
#define HFS_VH_SIG_HFSX 0x4858 /* HX in big endian */
// version values
#define HFS_VH_VER_HFSPLUS 0x0004 /* all HFS+ volumes are version 4 */
#define HFS_VH_VER_HFSX 0x0005 /* HFSX volumes start with version 5 */
// attr values (
// bits 0 to 7 are reserved
#define HFS_VH_ATTR_UNMOUNTED (uint32_t)(1<<8) /* set if the volume was unmounted properly; as per TN 1150, modern Macintosh OSes always leave this bit set for the boot volume */
#define HFS_VH_ATTR_BADBLOCKS (uint32_t)(1<<9) /* set if there are any bad blocks for this volume (in the Extents B-tree) */
#define HFS_VH_ATTR_NOCACHE (uint32_t)(1<<10) /* set if volume should not be cached */
#define HFS_VH_ATTR_INCONSISTENT (uint32_t)(1<<11) /* cleared if the volume was unmounted properly */
#define HFS_VH_ATTR_CNIDS_REUSED (uint32_t)(1<<12) /* set if CNIDs have wrapped around past the maximum value and are being reused; in this case, there are CNIDs on the disk larger than the nextCatalogId field */
#define HFS_VH_ATTR_JOURNALED (uint32_t)(1<<13)
// 14 is reserved
#define HFS_VH_ATTR_SOFTWARE_LOCK (uint32_t)(1 << 15) /* set if volume should be write-protected in software */
// 16 to 31 are reserved
// last_mnt_ver values
#define HFS_VH_MVER_HFSPLUS 0x31302e30 /* '10.0' for Mac OS X */
#define HFS_VH_MVER_HFSJ 0x4846534a /* 'HFSJ' for journaled HFS+ on Mac OS X */
#define HFS_VH_MVER_FSK 0x46534b21 /* 'FSK!' for failed journal replay */
#define HFS_VH_MVER_FSCK 0x6673636b /* 'fsck' for fsck_hfs */
#define HFS_VH_MVER_OS89 0x382e3130 /* '8.10' for Mac OS 8.1-9.2.2 */
/* Index values for finder_info array */
#define HFS_VH_FI_BOOT 0 /*Directory ID of bootable directory */
#define HFS_VH_FI_START 1 /* Parent dir ID of startup app */
#define HFS_VH_FI_OPEN 2 /* Directory to open when volume is mounted */
#define HFS_VH_FI_BOOT9 3 /* Directory ID of OS 8 or 9 bootable sys folder */
#define HFS_VH_FI_RESV1 4
#define HFS_VH_FI_BOOTX 5 /* Directory ID of OS X bootable system (CoreServices dir) */
#define HFS_VH_FI_ID1 6 /* OS X Volume ID part 1 */
#define HFS_VH_FI_ID2 7 /* OS X Volume ID part 2 */
/**
* Flags to control hfs_UTF16toUTF8()
*/
// If this flag is set, the function will replace fwd slash with colon, as
// required in HFS+ filenames.
#define HFS_U16U8_FLAG_REPLACE_SLASH 0x00000001
#define HFS_U16U8_FLAG_REPLACE_CONTROL 0x00000002
/*
** HFS+/HFSX Super Block
*/
typedef struct {
uint8_t signature[2]; /* "H+" for HFS+, "HX" for HFSX */
uint8_t version[2]; /* 4 for HFS+, 5 for HFSX */
uint8_t attr[4]; /* volume attributes */
uint8_t last_mnt_ver[4]; /* last mounted version */
uint8_t jinfo_blk[4]; /* journal info block */
uint8_t cr_date[4]; /* volume creation date (NOT in GMT) */
uint8_t m_date[4]; /* volume last modified date (GMT) */
uint8_t bkup_date[4]; /* volume last backup date (GMT) */
uint8_t chk_date[4]; /* date of last consistency check (GMT) */
uint8_t file_cnt[4]; /* number of files on volume (not incl. special files) */
uint8_t fldr_cnt[4]; /* number of folders on volume (not incl. root dir) */
uint8_t blk_sz[4]; /* allocation block size (in bytes) */
uint8_t blk_cnt[4]; /* number of blocks on disk */
uint8_t free_blks[4]; /* unused block count */
uint8_t next_alloc[4]; /* block addr to start allocation search from */
uint8_t rsrc_clmp_sz[4]; /* default clump size for resource forks (in bytes) */
uint8_t data_clmp_sz[4]; /* default clump size for data forks (in bytes) */
uint8_t next_cat_id[4]; /* next catalog id for allocation */
uint8_t write_cnt[4]; /* write count: incremented each time it is mounted and modified */
uint8_t enc_bmp[8]; /* encoding bitmap (identifies which encodings were used in FS) */
uint8_t finder_info[8][4]; /* Special finder details */
hfs_fork alloc_file; /* location and size of allocation bitmap file */
hfs_fork ext_file; /* location and size of extents file */
hfs_fork cat_file; /* location and size of catalog file */
hfs_fork attr_file; /* location and size of attributes file */
hfs_fork start_file; /* location and size of startup file */
} hfs_plus_vh;
/*
** HFS (non-Plus) Master Directory Block (volume header-like) (used with wrapped HFS+/HFSX file systems)
*/
typedef struct {
uint8_t drSigWord[2]; /* "BD" for HFS (same location as hfs_plus_vh.signature) */
uint8_t drCrDate[4]; /* volume creation date */
uint8_t drLsMod[4]; /* volume last modified date */
uint8_t drAtrb[2]; /* volume attributes */
uint8_t drNmFls[2]; /* number of files on volume */
uint8_t drVBMSt[2]; /* starting block for volume bitmap */
uint8_t drAllocPtr[2]; /* start of next allocation search */
uint8_t drNmAlBlks[2]; /* number of blocks on disk */
uint8_t drAlBlkSiz[4]; /* size in bytes of each allocation block */
uint8_t drClpSiz[4]; /* default clump size for volume */
uint8_t drAlBlSt[2]; /* first allocation block, in 512-byte sectors */
uint8_t drNxtCNID[4]; /* next unused catalog node ID */
uint8_t drFreeBlks[2]; /* number of unused allocation blocks */
uint8_t drVN[28]; /* volume name, where first byte is length */
uint8_t drVolBkUp[4]; /* volume last backup date */
uint8_t drVSeqNum[2]; /* volume sequence number */
uint8_t drWrCnt[4]; /* write count */
uint8_t drXTClpSiz[4]; /* clump size for extents overflow file */
uint8_t drCTClpSiz[4]; /* clump size for catalog file */
uint8_t drNmRtDirs[2]; /* number of folders in root directory */
uint8_t drFilCnt[4]; /* number of files on volume */
uint8_t drDirCnt[4]; /* number of directories on volume */
uint8_t drFndrInfo[32]; /* Finder info */
uint8_t drEmbedSigWord[2]; /* signature of the embedded HFS+ volume (eg, "H+") - 0x7c offset */
uint8_t drEmbedExtent_startBlock[2]; /* extent descriptor for start of embedded volume */
uint8_t drEmbedExtent_blockCount[2]; /* extent descriptor for num of blks in of embedded volume */
uint8_t drXTFlSize[4]; /* size of the extents overflow file */
uint8_t drXTExtRec[12]; /* extent record with size and location of extents overflow file */
uint8_t drCTFlSize[4]; /* size of the catalog file */
uint8_t drCTExtRec[12]; /* extent record with size and location of catalog file */
} hfs_mdb;
/********* B-Tree data structures **********/
/* Node descriptor that starts each node in a B-tree */
// type values
#define HFS_BT_NODE_TYPE_LEAF -1
#define HFS_BT_NODE_TYPE_IDX 0
#define HFS_BT_NODE_TYPE_HEAD 1
#define HFS_BT_NODE_TYPE_MAP 2
// header that starts every B-tree node
typedef struct {
uint8_t flink[4]; /* node num of next node of same type */
uint8_t blink[4]; /* node num of prev node of same type */
int8_t type; /* type of this node */
uint8_t height; /* level in B-tree (0 for root, 1 for leaf) */
uint8_t num_rec[2]; /* number of records this node */
uint8_t res[2]; /* reserved */
} hfs_btree_node;
/*****************/
// structure for the 1st record in the B-Tree header node
// type values
#define HFS_BT_HEAD_TYPE_CNTL 0 // control file (catalog, extents, attributes)
#define HFS_BT_HEAD_TYPE_USER 128 // hot file
#define HFS_BT_HEAD_TYPE_RSV 255
// compType values
#define HFS_BT_HEAD_COMP_SENS 0xBC // case sensitive
#define HFS_BT_HEAD_COMP_INSENS 0xC7 // case insensitive
// attr values
#define HFS_BT_HEAD_ATTR_BIGKEYS 0x00000002 /* key length field is 16 bits (req'd for HFS+) */
#define HFS_BT_HEAD_ATTR_VARIDXKEYS 0x00000004 /* Keys in INDEX nodes are variable length */
// NOTE: VARIDXKEYS is required for the Catalog B-tree and cleared for the Extents B-tree
typedef struct {
uint8_t depth[2]; /* current depth of btree */
uint8_t rootNode[4]; /* node number of root node */
uint8_t leafRecords[4]; /* number of records in leaf nodes */
uint8_t firstLeafNode[4]; /* number of first leaf node (0 if no leafs) */
uint8_t lastLeafNode[4]; /* number of last leaf node (0 if no leafs) */
uint8_t nodesize[2]; /* byte size of each node (512..32768) */
uint8_t maxKeyLen[2]; /* max key length in an index or leaf node */
uint8_t totalNodes[4]; /* number of nodes in btree (free or in use) */
uint8_t freeNodes[4]; /* unused nodes in btree */
uint8_t res[2]; /* reserved */
uint8_t clumpSize[4]; /* clump size */
uint8_t type; /* btree type (control or user) */
uint8_t compType; /* HFSX Only: identifies of key comparisons are case sensitive */
uint8_t attr[4]; /* attributes */
uint8_t res2[64]; /* reserved */
} hfs_btree_header_record;
/* key for catalog records */
typedef struct {
uint8_t key_len[2]; // length of key minus 2
uint8_t parent_cnid[4];
hfs_uni_str name;
} hfs_btree_key_cat;
/* Key for extents records */
// fork_type values
#define HFS_EXT_KEY_TYPE_DATA 0x00 // extents key is for data fork
#define HFS_EXT_KEY_TYPE_RSRC 0xFF // extents key is for resource fork
typedef struct {
uint8_t key_len[2]; // length of key minus 2 (should always be 10)
uint8_t fork_type; // data or resource fork
uint8_t pad; // reserved
uint8_t file_id[4]; // the cnid that this key is for
uint8_t start_block[4]; // the offset in the file (in blocks) that this run is for
} hfs_btree_key_ext;
/* Record contents for index record after key */
typedef struct {
uint8_t childNode[4];
} hfs_btree_index_record;
/***************** ATTRIBUTES FILE ******************************/
typedef struct {
uint8_t key_len[2];
uint8_t pad[2];
uint8_t file_id[4];
uint8_t start_block[4];
uint8_t attr_name_len[2];
uint8_t attr_name[254];
} hfs_btree_key_attr;
typedef struct {
uint8_t record_type[4]; // HFS_ATTRIBUTE_RECORD_INLINE_DATA
uint8_t reserved[8];
uint8_t attr_size[4];
uint8_t attr_data[2]; /* variable length data */
} hfs_attr_data;
/* Each leaf record in the Attributes file has one of these types. However,
* only "INLINE_DATA" is ever used by Apple. We check the value of the flag,
* but count it as an error if either of the other two values is found.
*/
#define HFS_ATTR_RECORD_INLINE_DATA 0x10
#define HFS_ATTR_RECORD_FORK_DATA 0x20
#define HFS_ATTR_RECORD_EXTENTS 0x30
// Maximum UTF8 size of an attribute name = 127 * 3 + 1; // 382
#define MAX_ATTR_NAME_LENGTH 382
/*
* If a file is compressed, then it will have an extended attribute
* with name com.apple.decmpfs. The value of that attribute is a data
* structure, arranged as shown in the following struct, possibly followed
* by some actual compressed data.
*
* If compression_type = 3, then data follows this compression header, in-line.
* If the first byte of that data is 0xF, then the data is not really compressed, so
* the following bytes are the data. Otherwise, the data following the compression
* header is zlib-compressed.
*
* If the compression_type = 4, then compressed data is stored in the file's resource
* fork, in a resource of type CMPF. There will be a single resource in the fork, and
* it will have this type. The beginning of the resource is a table of offsets for
* successive compression units within the resource.
*/
typedef struct {
/* this structure represents the xattr on disk; the fields below are little-endian */
uint8_t compression_magic[4];
uint8_t compression_type[4];
uint8_t uncompressed_size[8];
unsigned char attr_bytes[0]; /* the bytes of the attribute after the header, if any. */
} DECMPFS_DISK_HEADER;
#define COMPRESSION_UNIT_SIZE 65536U
/********* CATALOG Record structures *********/
typedef struct {
int8_t v[2];
int8_t h[2];
} hfs_point;
#define HFS_FINDER_FLAG_NAME_LOCKED 0x1000
#define HFS_FINDER_FLAG_HAS_BUNDLE 0x2000
#define HFS_FINDER_FLAG_IS_INVISIBLE 0x4000
#define HFS_FINDER_FLAG_IS_ALIAS 0x8000
// Finder info stored in file and folder structures
typedef struct {
uint8_t file_type[4]; /* file type */
uint8_t file_cr[4]; /* file creator */
uint8_t flags[2]; /* finder flags */
hfs_point loc; /* location in the folder */
uint8_t res[2]; /* reserved */
} hfs_fileinfo;
typedef struct {
uint8_t res1[8]; /* reserved 1 */
uint8_t extflags[2]; /* extended finder flags */
uint8_t res2[2]; /* reserved 2 */
uint8_t folderid[4]; /* putaway folder id */
} hfs_extendedfileinfo;
/* Note that the file, folder, and thread structures all
* start with a 2-byte type field. */
// values for rec_type Record Type fields
#define HFS_FOLDER_RECORD 0x0001
#define HFS_FILE_RECORD 0X0002
#define HFS_FOLDER_THREAD 0x0003
#define HFS_FILE_THREAD 0x0004
// the start of the folder and file catalog entries are the same
typedef struct {
uint8_t rec_type[2]; /* record type */
uint8_t flags[2]; /* Flags (reserved (0) for folders) */
uint8_t valence[4]; /* valence - items in this folder (folders only) */
uint8_t cnid[4]; /* CNID of this file or folder */
uint8_t crtime[4]; /* create date */
uint8_t cmtime[4]; /* content modification date (m-time) */
uint8_t amtime[4]; /* attribute mod date (c-time) */
uint8_t atime[4]; /* access date */
uint8_t bkup_date[4]; /* backup date */
hfs_access_perm perm; /* permissions */
hfs_fileinfo u_info; /* user info (Used by Finder) */
hfs_extendedfileinfo f_info; /* finder info */
uint8_t text_enc[4]; /* text encoding hint for file name */
uint8_t res2[4]; /* reserved 2 */
} hfs_file_fold_std;
// structure for folder data in catalog leaf records
typedef struct {
hfs_file_fold_std std; /* standard data that files and folders share */
} hfs_folder;
// value for flags in hfs_file
#define HFS_FILE_FLAG_LOCKED 0x0001 /* file is locked */
#define HFS_FILE_FLAG_THREAD 0x0002 /* File has a thread entry */
// @@@ BC: I Can't find a reference to these values...
#define HFS_FILE_FLAG_ATTR 0x0004 /* file has extended attributes */
#define HFS_FILE_FLAG_ACL 0x0008 /* file has security data (ACLs) */
// structure for file data in catalog leaf records
typedef struct {
hfs_file_fold_std std; /* standard data that files and folders share */
hfs_fork data; /* data fork */
hfs_fork resource; /* resource fork */
} hfs_file;
// structure for thread data in catalog leaf records
typedef struct {
uint8_t rec_type[2]; /* == kHFSPlusFolderThreadRecord or kHFSPlusFileThreadRecord */
uint8_t res[2]; /* reserved - initialized as zero */
uint8_t parent_cnid[4]; /* parent ID for this catalog node */
hfs_uni_str name; /* name of this catalog node (variable length) */
} hfs_thread;
// internally used structure to pass around both files and folders
typedef union {
hfs_folder folder;
hfs_file file;
} hfs_file_folder;
typedef struct {
TSK_FS_INFO fs_info; /* SUPER CLASS */
hfs_plus_vh *fs; /* cached superblock */
char is_case_sensitive;
/* lock protects blockmap_file, blockmap_attr, blockmap_cache, blockmap_cache_start, blockmap_cache_len */
tsk_lock_t lock;
TSK_FS_FILE *blockmap_file; //(r/w shared - lock)
const TSK_FS_ATTR *blockmap_attr; // (r/w shared - lock)
char blockmap_cache[4096]; ///< Cache for blockmap (r/w shared - lock)
TSK_OFF_T blockmap_cache_start; ///< Byte offset of blockmap where cache starts (r/w shared - lock)
size_t blockmap_cache_len; ///< Length of cache that is being used (r/w shared - lock)
TSK_FS_FILE *catalog_file;
const TSK_FS_ATTR *catalog_attr;
hfs_btree_header_record catalog_header;
TSK_FS_FILE *extents_file;
const TSK_FS_ATTR *extents_attr;
hfs_btree_header_record extents_header;
TSK_OFF_T hfs_wrapper_offset; /* byte offset of this FS within an HFS wrapper */
/* Creation times needed for hard link recognition */
time_t root_crtime; // creation time of the root directory, cnid = 2
time_t meta_crtime; // creation time of the dir with path /^^^^HFS+ Private Data (those are nulls)
time_t metadir_crtime; // creation time of dir with path /.HFS+ Private Directory Data^ (that's a carriage return)
unsigned char has_root_crtime; // Boolean -- are the crtime fields set?
unsigned char has_meta_crtime;
unsigned char has_meta_dir_crtime;
TSK_INUM_T meta_inum;
TSK_INUM_T meta_dir_inum;
// We cache the two metadata directory structures here, to speed up hard link resolution
TSK_FS_DIR *meta_dir;
TSK_FS_DIR *dir_meta_dir;
// We need a lock to protect the two metadata directory caches (if this is multi-threaded)
// and will also use this to protect the rest of the HFS_INFO struct.
tsk_lock_t metadata_dir_cache_lock;
// These special files are optional.
unsigned char has_extents_file; // and also the Bad Blocks file
unsigned char has_startup_file;
unsigned char has_attributes_file;
} HFS_INFO;
typedef struct {
hfs_file cat; /* on-disk catalog record (either hfs_file or hfs_folder) */
int flags; /* flags for on-disk record */
TSK_INUM_T inum; /* cnid */
hfs_thread thread; /* thread record */
} HFS_ENTRY;
/****************** Resource File Structures *****************/
typedef struct {
uint8_t dataOffset[4];
uint8_t mapOffset[4];
uint8_t dataLength[4];
uint8_t mapLength[4];
} hfs_resource_fork_header;
typedef struct {
uint8_t length[4];
uint8_t data[2]; // Variable length
} hfs_resource;
typedef struct {
uint8_t reserved1[16]; // copy of resource fork header
uint8_t reserved2[4]; //handle to next resource map
uint8_t reserved3[2]; // file reference number
uint8_t fork_attributes[2]; //??
uint8_t typeListOffset[2]; // Actually, points to a 2-byte count of types (minus 1)
uint8_t nameListOffset[2]; // could be the end of the fork or zero, if there is no name list.
} hfs_resource_fork_map_header;
typedef struct {
unsigned char type[4];
uint8_t count[2]; // number of resources of this type, minus 1
uint8_t offset[2]; // offset from beginning of type list to reference list for this type.
} hfs_resource_type_list_item;
typedef struct {
uint8_t typeCount[2]; // number of types minus one
hfs_resource_type_list_item type[]; // Variable length
} hfs_resource_type_list;
typedef struct {
uint8_t resID[2];
uint8_t resNameOffset[2]; //SIGNED offset from beginning of name list, or -1
uint8_t resAttributes[1]; // ??
uint8_t resDataOffset[3]; // from beginning of resource data to data for this resource
uint8_t reserved[4]; // handle to resource
} hfs_resource_refListItem;
/************** JOURNAL ******************/
/* HFS Journal Info Block */
typedef struct {
uint8_t flags[4];
uint8_t dev_sig[32];
uint8_t offs[8];
uint8_t size[8];
uint8_t res[128];
} hfs_journ_sb;
/*
* Prototypes
*/
extern uint8_t hfs_checked_read_random(TSK_FS_INFO *, char *, size_t,
TSK_OFF_T);
//extern uint8_t hfs_uni2ascii(TSK_FS_INFO *, uint8_t *, int, char *, int);
// replaced by:
extern uint8_t hfs_UTF16toUTF8(TSK_FS_INFO *, uint8_t *, int, char *, int,
uint32_t);
extern int hfs_unicode_compare(HFS_INFO *, const hfs_uni_str *,
const hfs_uni_str *);
extern uint16_t hfs_get_idxkeylen(HFS_INFO * hfs, uint16_t keylen,
const hfs_btree_header_record * header);
extern TSK_RETVAL_ENUM hfs_dir_open_meta(TSK_FS_INFO *, TSK_FS_DIR **,
TSK_INUM_T);
extern int hfs_name_cmp(TSK_FS_INFO *, const char *, const char *);
extern uint8_t hfs_jopen(TSK_FS_INFO *, TSK_INUM_T);
extern uint8_t hfs_jblk_walk(TSK_FS_INFO *, TSK_DADDR_T, TSK_DADDR_T, int,
TSK_FS_JBLK_WALK_CB, void *);
extern uint8_t hfs_jentry_walk(TSK_FS_INFO *, int, TSK_FS_JENTRY_WALK_CB,
void *);
extern TSK_INUM_T hfs_follow_hard_link(HFS_INFO * hfs, hfs_file * entry,
unsigned char *is_error);
extern uint8_t hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum,
HFS_ENTRY * entry, unsigned char follow_hard_link);
extern void error_returned(char *errstr, ...);
extern void error_detected(uint32_t errnum, char *errstr, ...);
/**
* @param hfs
* @param level_type Type of node the records are from
* @param cur_key Key currently being analyzed (record data follows it)
* @param key_off Byte offset in tree that this key is located in
* @param ptr Pointer to data that was passed into parent
*/
typedef uint8_t(*TSK_HFS_BTREE_CB) (HFS_INFO *, int8_t level_type,
const hfs_btree_key_cat * cur_key,
TSK_OFF_T key_off, void *ptr);
// return values for callback
#define HFS_BTREE_CB_IDX_LT 1 // current key is less than target (keeps looking in node)
#define HFS_BTREE_CB_IDX_EQGT 2 // current key is equal or greater than target (stops)
#define HFS_BTREE_CB_LEAF_GO 3 // keep on going to the next key in the leaf node
#define HFS_BTREE_CB_LEAF_STOP 4 // stop processing keys in the leaf node
#define HFS_BTREE_CB_ERR 5
extern uint8_t hfs_cat_traverse(HFS_INFO * hfs,
TSK_HFS_BTREE_CB a_cb, void *ptr);
#endif
|