| 1 | /* |
| 2 | * Copyright (c) 2000-2023 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
| 5 | * |
| 6 | * This file contains Original Code and/or Modifications of Original Code |
| 7 | * as defined in and that are subject to the Apple Public Source License |
| 8 | * Version 2.0 (the 'License'). You may not use this file except in |
| 9 | * compliance with the License. The rights granted to you under the License |
| 10 | * may not be used to create, or enable the creation or redistribution of, |
| 11 | * unlawful or unlicensed copies of an Apple operating system, or to |
| 12 | * circumvent, violate, or enable the circumvention or violation of, any |
| 13 | * terms of an Apple operating system software license agreement. |
| 14 | * |
| 15 | * Please obtain a copy of the License at |
| 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
| 17 | * |
| 18 | * The Original Code and all software distributed under the License are |
| 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| 23 | * Please see the License for the specific language governing rights and |
| 24 | * limitations under the License. |
| 25 | * |
| 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
| 27 | */ |
| 28 | #ifndef __HFS_FORMAT__ |
| 29 | #define __HFS_FORMAT__ |
| 30 | |
| 31 | #include <sys/types.h> |
| 32 | #include <sys/appleapiopts.h> |
| 33 | #include "hfs_unistr.h" |
| 34 | |
| 35 | /* |
| 36 | * hfs_format.h |
| 37 | * |
| 38 | * This file describes the on-disk format for HFS and HFS Plus volumes. |
| 39 | * |
| 40 | * Note: Starting with MacOS 10.9, definition of struct HFSUniStr255 exists in hfs_unistr.h |
| 41 | * |
| 42 | */ |
| 43 | |
| 44 | #ifdef __cplusplus |
| 45 | extern "C" { |
| 46 | #endif |
| 47 | |
| 48 | /* some on-disk hfs structures have 68K alignment (misaligned) */ |
| 49 | |
| 50 | /* Signatures used to differentiate between HFS and HFS Plus volumes */ |
| 51 | enum { |
| 52 | 	kHFSSigWord		= 0x4244,	/* 'BD' in ASCII */ |
| 53 | 	kHFSPlusSigWord		= 0x482B,	/* 'H+' in ASCII */ |
| 54 | 	kHFSXSigWord		= 0x4858,	/* 'HX' in ASCII */ |
| 55 | |
| 56 | 	kHFSPlusVersion		= 0x0004,	/* 'H+' volumes are version 4 only */ |
| 57 | 	kHFSXVersion		= 0x0005,	/* 'HX' volumes start with version 5 */ |
| 58 | |
| 59 | 	kHFSPlusMountVersion	= 0x31302E30,	/* '10.0' for Mac OS X */ |
| 60 | 	kHFSJMountVersion	= 0x4846534a,	/* 'HFSJ' for journaled HFS+ on OS X */ |
| 61 | 	kFSKMountVersion	= 0x46534b21	/* 'FSK!' for failed journal replay */ |
| 62 | }; |
| 63 | |
| 64 | |
| 65 | #ifdef __APPLE_API_PRIVATE |
| 66 | /* |
| 67 | * Mac OS X has two special directories on HFS+ volumes for hardlinked files |
| 68 | * and hardlinked directories as well as for open-unlinked files. |
| 69 | * |
| 70 | * These directories and their contents are not exported from the filesystem |
| 71 | * under Mac OS X. |
| 72 | */ |
| 73 | #define HFSPLUSMETADATAFOLDER "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data" |
| 74 | #define HFSPLUS_DIR_METADATA_FOLDER ".HFS+ Private Directory Data\xd" |
| 75 | |
| 76 | /* |
| 77 | * Files in the "HFS+ Private Data" folder have one of the following prefixes |
| 78 | * followed by a decimal number (no leading zeros) for the file ID. |
| 79 | * |
| 80 | * Note: Earlier version of Mac OS X used a 32 bit random number for the link |
| 81 | * ref number instead of the file id. |
| 82 | * |
| 83 | * e.g. iNode7182000 and temp3296 |
| 84 | */ |
| 85 | #define HFS_INODE_PREFIX	"iNode" |
| 86 | #define HFS_DELETE_PREFIX	"temp" |
| 87 | |
| 88 | /* |
| 89 | * Files in the ".HFS+ Private Directory Data" folder have the following |
| 90 | * prefix followed by a decimal number (no leading zeros) for the file ID. |
| 91 | * |
| 92 | * e.g. dir_555 |
| 93 | */ |
| 94 | #define HFS_DIRINODE_PREFIX	"dir_" |
| 95 | |
| 96 | /* |
| 97 | * Hardlink inodes save the head of the link chain in |
| 98 | * an extended attribute named FIRST_LINK_XATTR_NAME. |
| 99 | * The attribute data is the decimal value in ASCII |
| 100 | * of the cnid for the first link in the chain. |
| 101 | * |
| 102 | * This extended attribute is private (i.e. its not |
| 103 | * exported in the getxattr/listxattr POSIX APIs). |
| 104 | */ |
| 105 | #define FIRST_LINK_XATTR_NAME	"com.apple.system.hfs.firstlink" |
| 106 | #define FIRST_LINK_XATTR_REC_SIZE (sizeof(HFSPlusAttrData) - 2 + 12) |
| 107 | |
| 108 | /* |
| 109 | * The name space ID for generating an HFS volume UUID |
| 110 | * |
| 111 | * B3E20F39-F292-11D6-97A4-00306543ECAC |
| 112 | */ |
| 113 | #define HFS_UUID_NAMESPACE_ID "\xB3\xE2\x0F\x39\xF2\x92\x11\xD6\x97\xA4\x00\x30\x65\x43\xEC\xAC" |
| 114 | |
| 115 | #endif /* __APPLE_API_PRIVATE */ |
| 116 | |
| 117 | /* |
| 118 | * Indirect link files (hard links) have the following type/creator. |
| 119 | */ |
| 120 | enum { |
| 121 | 	kHardLinkFileType = 0x686C6E6B, /* 'hlnk' */ |
| 122 | 	kHFSPlusCreator = 0x6866732B /* 'hfs+' */ |
| 123 | }; |
| 124 | |
| 125 | |
| 126 | /* |
| 127 | *	File type and creator for symbolic links |
| 128 | */ |
| 129 | enum { |
| 130 | kSymLinkFileType = 0x736C6E6B, /* 'slnk' */ |
| 131 | kSymLinkCreator = 0x72686170 /* 'rhap' */ |
| 132 | }; |
| 133 | |
| 134 | |
| 135 | enum { |
| 136 | 	kHFSMaxVolumeNameChars		= 27, |
| 137 | 	kHFSMaxFileNameChars		= 31, |
| 138 | 	kHFSPlusMaxFileNameChars	= 255 |
| 139 | }; |
| 140 | |
| 141 | |
| 142 | /* Extent overflow file data structures */ |
| 143 | |
| 144 | /* HFS Extent key */ |
| 145 | struct HFSExtentKey { |
| 146 | 	u_int8_t 	keyLength;	/* length of key, excluding this field */ |
| 147 | 	u_int8_t 	forkType;	/* 0 = data fork, FF = resource fork */ |
| 148 | 	u_int32_t 	fileID;		/* file ID */ |
| 149 | 	u_int16_t 	startBlock;	/* first file allocation block number in this extent */ |
| 150 | } __attribute__((aligned(2), packed)); |
| 151 | typedef struct HFSExtentKey HFSExtentKey; |
| 152 | |
| 153 | /* HFS Plus Extent key */ |
| 154 | struct HFSPlusExtentKey { |
| 155 | 	u_int16_t 	keyLength;		/* length of key, excluding this field */ |
| 156 | 	u_int8_t 	forkType;		/* 0 = data fork, FF = resource fork */ |
| 157 | 	u_int8_t 	pad;			/* make the other fields align on 32-bit boundary */ |
| 158 | 	u_int32_t 	fileID;			/* file ID */ |
| 159 | 	u_int32_t 	startBlock;		/* first file allocation block number in this extent */ |
| 160 | } __attribute__((aligned(2), packed)); |
| 161 | typedef struct HFSPlusExtentKey HFSPlusExtentKey; |
| 162 | |
| 163 | /* Number of extent descriptors per extent record */ |
| 164 | enum { |
| 165 | 	kHFSExtentDensity	= 3, |
| 166 | 	kHFSPlusExtentDensity	= 8 |
| 167 | }; |
| 168 | |
| 169 | /* HFS extent descriptor */ |
| 170 | struct HFSExtentDescriptor { |
| 171 | 	u_int16_t 	startBlock;		/* first allocation block */ |
| 172 | 	u_int16_t 	blockCount;		/* number of allocation blocks */ |
| 173 | } __attribute__((aligned(2), packed)); |
| 174 | typedef struct HFSExtentDescriptor HFSExtentDescriptor; |
| 175 | |
| 176 | /* HFS Plus extent descriptor */ |
| 177 | struct HFSPlusExtentDescriptor { |
| 178 | 	u_int32_t 	startBlock;		/* first allocation block */ |
| 179 | 	u_int32_t 	blockCount;		/* number of allocation blocks */ |
| 180 | } __attribute__((aligned(2), packed)); |
| 181 | typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor; |
| 182 | |
| 183 | /* HFS extent record */ |
| 184 | typedef HFSExtentDescriptor HFSExtentRecord[3]; |
| 185 | |
| 186 | /* HFS Plus extent record */ |
| 187 | typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8]; |
| 188 | |
| 189 | |
| 190 | /* Finder information */ |
| 191 | struct FndrFileInfo { |
| 192 | 	u_int32_t 	fdType;		/* file type */ |
| 193 | 	u_int32_t 	fdCreator;	/* file creator */ |
| 194 | 	u_int16_t 	fdFlags;	/* Finder flags */ |
| 195 | 	struct { |
| 196 | 	 int16_t	v;		/* file's location */ |
| 197 | 	 int16_t	h; |
| 198 | 	} fdLocation; |
| 199 | 	int16_t 	opaque; |
| 200 | } __attribute__((aligned(2), packed)); |
| 201 | typedef struct FndrFileInfo FndrFileInfo; |
| 202 | |
| 203 | struct FndrDirInfo { |
| 204 | 	struct {			/* folder's window rectangle */ |
| 205 | 	 int16_t	top; |
| 206 | 	 int16_t	left; |
| 207 | 	 int16_t	bottom; |
| 208 | 	 int16_t	right; |
| 209 | 	} frRect; |
| 210 | 	unsigned short 	frFlags;	/* Finder flags */ |
| 211 | 	struct { |
| 212 | 	 u_int16_t	v;		/* folder's location */ |
| 213 | 	 u_int16_t	h; |
| 214 | 	} frLocation; |
| 215 | 	int16_t 	opaque; |
| 216 | } __attribute__((aligned(2), packed)); |
| 217 | typedef struct FndrDirInfo FndrDirInfo; |
| 218 | |
| 219 | struct FndrOpaqueInfo { |
| 220 | 	int8_t opaque[16]; |
| 221 | } __attribute__((aligned(2), packed)); |
| 222 | typedef struct FndrOpaqueInfo FndrOpaqueInfo; |
| 223 | |
| 224 | struct FndrExtendedDirInfo { |
| 225 | 	u_int32_t document_id; |
| 226 | 	u_int32_t date_added; |
| 227 | 	u_int16_t extended_flags; |
| 228 | 	u_int16_t reserved3; |
| 229 | 	u_int32_t write_gen_counter; |
| 230 | } __attribute__((aligned(2), packed)); |
| 231 | |
| 232 | struct FndrExtendedFileInfo { |
| 233 | 	u_int32_t document_id; |
| 234 | 	u_int32_t date_added; |
| 235 | 	u_int16_t extended_flags; |
| 236 | 	u_int16_t reserved2; |
| 237 | 	u_int32_t write_gen_counter; |
| 238 | } __attribute__((aligned(2), packed)); |
| 239 | |
| 240 | /* HFS Plus Fork data info - 80 bytes */ |
| 241 | struct HFSPlusForkData { |
| 242 | 	u_int64_t 		logicalSize;	/* fork's logical size in bytes */ |
| 243 | 	u_int32_t 		clumpSize;	/* fork's clump size in bytes */ |
| 244 | 	u_int32_t 		totalBlocks;	/* total blocks used by this fork */ |
| 245 | 	HFSPlusExtentRecord 	extents;	/* initial set of extents */ |
| 246 | } __attribute__((aligned(2), packed)); |
| 247 | typedef struct HFSPlusForkData HFSPlusForkData; |
| 248 | |
| 249 | |
| 250 | /* Mac OS X has 16 bytes worth of "BSD" info. |
| 251 | * |
| 252 | * Note: Mac OS 9 implementations and applications |
| 253 | * should preserve, but not change, this information. |
| 254 | */ |
| 255 | struct HFSPlusBSDInfo { |
| 256 | 	u_int32_t 	ownerID;	/* user-id of owner or hard link chain previous link */ |
| 257 | 	u_int32_t 	groupID;	/* group-id of owner or hard link chain next link */ |
| 258 | 	u_int8_t 	adminFlags;	/* super-user changeable flags */ |
| 259 | 	u_int8_t 	ownerFlags;	/* owner changeable flags */ |
| 260 | 	u_int16_t 	fileMode;	/* file type and permission bits */ |
| 261 | 	union { |
| 262 | 	 u_int32_t	iNodeNum;	/* indirect node number (hard links only) */ |
| 263 | 	 u_int32_t	linkCount;	/* links that refer to this indirect node */ |
| 264 | 	 u_int32_t	rawDevice;	/* special file device (FBLK and FCHR only) */ |
| 265 | 	} special; |
| 266 | } __attribute__((aligned(2), packed)); |
| 267 | typedef struct HFSPlusBSDInfo HFSPlusBSDInfo; |
| 268 | |
| 269 | /* |
| 270 | * Hardlink "links" resolve to an inode |
| 271 | * and the actual uid/gid comes from that |
| 272 | * inode. |
| 273 | * |
| 274 | * We repurpose the links's uid/gid fields |
| 275 | * for the hardlink link chain. The chain |
| 276 | * consists of a doubly linked list of file |
| 277 | * ids. |
| 278 | */ |
| 279 | |
| 280 | #define hl_firstLinkID reserved1 /* Valid only if HasLinkChain flag is set (indirect nodes only) */ |
| 281 | |
| 282 | #define hl_prevLinkID bsdInfo.ownerID /* Valid only if HasLinkChain flag is set */ |
| 283 | #define hl_nextLinkID bsdInfo.groupID /* Valid only if HasLinkChain flag is set */ |
| 284 | |
| 285 | #define hl_linkReference bsdInfo.special.iNodeNum |
| 286 | #define hl_linkCount bsdInfo.special.linkCount |
| 287 | |
| 288 | |
| 289 | /* Catalog file data structures */ |
| 290 | |
| 291 | enum { |
| 292 | 	kHFSRootParentID		= 1,	/* Parent ID of the root folder */ |
| 293 | 	kHFSRootFolderID		= 2,	/* Folder ID of the root folder */ |
| 294 | 	kHFSExtentsFileID		= 3,	/* File ID of the extents file */ |
| 295 | 	kHFSCatalogFileID		= 4,	/* File ID of the catalog file */ |
| 296 | 	kHFSBadBlockFileID		= 5,	/* File ID of the bad allocation block file */ |
| 297 | 	kHFSAllocationFileID		= 6,	/* File ID of the allocation file (HFS Plus only) */ |
| 298 | 	kHFSStartupFileID		= 7,	/* File ID of the startup file (HFS Plus only) */ |
| 299 | 	kHFSAttributesFileID		= 8,	/* File ID of the attribute file (HFS Plus only) */ |
| 300 | 	kHFSAttributeDataFileID = 13,	/* Used in Mac OS X runtime for extent based attributes */ |
| 301 | 	 /* kHFSAttributeDataFileID is never stored on disk. */ |
| 302 | 	kHFSRepairCatalogFileID		= 14,	/* Used when rebuilding Catalog B-tree */ |
| 303 | 	kHFSBogusExtentFileID		= 15,	/* Used for exchanging extents in extents file */ |
| 304 | 	kHFSFirstUserCatalogNodeID	= 16 |
| 305 | }; |
| 306 | |
| 307 | /* HFS catalog key */ |
| 308 | struct HFSCatalogKey { |
| 309 | 	u_int8_t 	keyLength;		/* key length (in bytes) */ |
| 310 | 	u_int8_t 	reserved;		/* reserved (set to zero) */ |
| 311 | 	u_int32_t 	parentID;		/* parent folder ID */ |
| 312 | 	u_int8_t 	nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */ |
| 313 | } __attribute__((aligned(2), packed)); |
| 314 | typedef struct HFSCatalogKey HFSCatalogKey; |
| 315 | |
| 316 | /* HFS Plus catalog key */ |
| 317 | struct HFSPlusCatalogKey { |
| 318 | 	u_int16_t 		keyLength;	/* key length (in bytes) */ |
| 319 | 	u_int32_t 		parentID;	/* parent folder ID */ |
| 320 | 	HFSUniStr255 		nodeName;	/* catalog node name */ |
| 321 | } __attribute__((aligned(2), packed)); |
| 322 | typedef struct HFSPlusCatalogKey HFSPlusCatalogKey; |
| 323 | |
| 324 | /* Catalog record types */ |
| 325 | enum { |
| 326 | 	/* HFS Catalog Records */ |
| 327 | 	kHFSFolderRecord		= 0x0100,	/* Folder record */ |
| 328 | 	kHFSFileRecord			= 0x0200,	/* File record */ |
| 329 | 	kHFSFolderThreadRecord		= 0x0300,	/* Folder thread record */ |
| 330 | 	kHFSFileThreadRecord		= 0x0400,	/* File thread record */ |
| 331 | |
| 332 | 	/* HFS Plus Catalog Records */ |
| 333 | 	kHFSPlusFolderRecord		= 1,		/* Folder record */ |
| 334 | 	kHFSPlusFileRecord		= 2,		/* File record */ |
| 335 | 	kHFSPlusFolderThreadRecord	= 3,		/* Folder thread record */ |
| 336 | 	kHFSPlusFileThreadRecord	= 4		/* File thread record */ |
| 337 | }; |
| 338 | |
| 339 | |
| 340 | /* Catalog file record flags */ |
| 341 | enum { |
| 342 | 	kHFSFileLockedBit	= 0x0000,	/* file is locked and cannot be written to */ |
| 343 | 	kHFSFileLockedMask	= 0x0001, |
| 344 | |
| 345 | 	kHFSThreadExistsBit	= 0x0001,	/* a file thread record exists for this file */ |
| 346 | 	kHFSThreadExistsMask	= 0x0002, |
| 347 | |
| 348 | 	kHFSHasAttributesBit	= 0x0002,	/* object has extended attributes */ |
| 349 | 	kHFSHasAttributesMask	= 0x0004, |
| 350 | |
| 351 | 	kHFSHasSecurityBit	= 0x0003,	/* object has security data (ACLs) */ |
| 352 | 	kHFSHasSecurityMask	= 0x0008, |
| 353 | |
| 354 | 	kHFSHasFolderCountBit	= 0x0004,	/* only for HFSX, folder maintains a separate sub-folder count */ |
| 355 | 	kHFSHasFolderCountMask	= 0x0010,	/* (sum of folder records and directory hard links) */ |
| 356 | |
| 357 | 	kHFSHasLinkChainBit	= 0x0005,	/* has hardlink chain (inode or link) */ |
| 358 | 	kHFSHasLinkChainMask	= 0x0020, |
| 359 | |
| 360 | 	kHFSHasChildLinkBit	= 0x0006,	/* folder has a child that's a dir link */ |
| 361 | 	kHFSHasChildLinkMask	= 0x0040, |
| 362 | |
| 363 | 	kHFSHasDateAddedBit = 0x0007,	/* File/Folder has the date-added stored in the finder info. */ |
| 364 | 	kHFSHasDateAddedMask = 0x0080, |
| 365 | |
| 366 | 	kHFSFastDevPinnedBit = 0x0008, /* this file has been pinned to the fast-device by the hot-file code on cooperative fusion */ |
| 367 | 	kHFSFastDevPinnedMask = 0x0100, |
| 368 | |
| 369 | 	kHFSDoNotFastDevPinBit = 0x0009, /* this file can not be pinned to the fast-device */ |
| 370 | 	kHFSDoNotFastDevPinMask = 0x0200, |
| 371 | |
| 372 | 	kHFSFastDevCandidateBit = 0x000a, /* this item is a potential candidate for fast-dev pinning (as are any of its descendents */ |
| 373 | 	kHFSFastDevCandidateMask = 0x0400, |
| 374 | |
| 375 | 	kHFSAutoCandidateBit = 0x000b, /* this item was automatically marked as a fast-dev candidate by the kernel */ |
| 376 | 	kHFSAutoCandidateMask = 0x0800, |
| 377 | |
| 378 | 	kHFSCatExpandedTimesBit = 0x000c,		/* this item has expanded timestamps */ |
| 379 | 	kHFSCatExpandedTimesMask = 0x1000 |
| 380 | |
| 381 | 	// There are only 3 flag bits remaining: 0x2000, 0x4000, 0x8000 |
| 382 | }; |
| 383 | |
| 384 | |
| 385 | /* HFS catalog folder record - 70 bytes */ |
| 386 | struct HFSCatalogFolder { |
| 387 | 	int16_t 		recordType;		/* == kHFSFolderRecord */ |
| 388 | 	u_int16_t 		flags;			/* folder flags */ |
| 389 | 	u_int16_t 		valence;		/* folder valence */ |
| 390 | 	u_int32_t		folderID;		/* folder ID */ |
| 391 | 	u_int32_t 		createDate;		/* date and time of creation */ |
| 392 | 	u_int32_t 		modifyDate;		/* date and time of last modification */ |
| 393 | 	u_int32_t 		backupDate;		/* date and time of last backup */ |
| 394 | 	FndrDirInfo 		userInfo;		/* Finder information */ |
| 395 | 	FndrOpaqueInfo		finderInfo;		/* additional Finder information */ |
| 396 | 	u_int32_t 		reserved[4];		/* reserved - initialized as zero */ |
| 397 | } __attribute__((aligned(2), packed)); |
| 398 | typedef struct HFSCatalogFolder HFSCatalogFolder; |
| 399 | |
| 400 | /* HFS Plus catalog folder record - 88 bytes */ |
| 401 | struct HFSPlusCatalogFolder { |
| 402 | 	int16_t 		recordType;		/* == kHFSPlusFolderRecord */ |
| 403 | 	u_int16_t 		flags;			/* file flags */ |
| 404 | 	u_int32_t 		valence;		/* folder's item count */ |
| 405 | 	u_int32_t 		folderID;		/* folder ID */ |
| 406 | 	u_int32_t 		createDate;		/* date and time of creation */ |
| 407 | 	u_int32_t 		contentModDate;		/* date and time of last content modification */ |
| 408 | 	u_int32_t 		attributeModDate;	/* date and time of last attribute modification */ |
| 409 | 	u_int32_t 		accessDate;		/* date and time of last access (MacOS X only) */ |
| 410 | 	u_int32_t 		backupDate;		/* date and time of last backup */ |
| 411 | 	HFSPlusBSDInfo		bsdInfo;		/* permissions (for MacOS X) */ |
| 412 | 	FndrDirInfo 		userInfo;		/* Finder information */ |
| 413 | 	FndrOpaqueInfo	 	finderInfo;		/* additional Finder information */ |
| 414 | 	u_int32_t 		textEncoding;		/* hint for name conversions */ |
| 415 | 	u_int32_t 		folderCount;		/* number of enclosed folders, active when HasFolderCount is set */ |
| 416 | } __attribute__((aligned(2), packed)); |
| 417 | typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder; |
| 418 | |
| 419 | /* HFS catalog file record - 102 bytes */ |
| 420 | struct HFSCatalogFile { |
| 421 | 	int16_t 		recordType;		/* == kHFSFileRecord */ |
| 422 | 	u_int8_t 		flags;			/* file flags */ |
| 423 | 	int8_t 			fileType;		/* file type (unused ?) */ |
| 424 | 	FndrFileInfo 		userInfo;		/* Finder information */ |
| 425 | 	u_int32_t 		fileID;			/* file ID */ |
| 426 | 	u_int16_t 		dataStartBlock;		/* not used - set to zero */ |
| 427 | 	int32_t 		dataLogicalSize;	/* logical EOF of data fork */ |
| 428 | 	int32_t 		dataPhysicalSize;	/* physical EOF of data fork */ |
| 429 | 	u_int16_t		rsrcStartBlock;		/* not used - set to zero */ |
| 430 | 	int32_t			rsrcLogicalSize;	/* logical EOF of resource fork */ |
| 431 | 	int32_t			rsrcPhysicalSize;	/* physical EOF of resource fork */ |
| 432 | 	u_int32_t		createDate;		/* date and time of creation */ |
| 433 | 	u_int32_t		modifyDate;		/* date and time of last modification */ |
| 434 | 	u_int32_t		backupDate;		/* date and time of last backup */ |
| 435 | 	FndrOpaqueInfo		finderInfo;		/* additional Finder information */ |
| 436 | 	u_int16_t		clumpSize;		/* file clump size (not used) */ |
| 437 | 	HFSExtentRecord		dataExtents;		/* first data fork extent record */ |
| 438 | 	HFSExtentRecord		rsrcExtents;		/* first resource fork extent record */ |
| 439 | 	u_int32_t		reserved;		/* reserved - initialized as zero */ |
| 440 | } __attribute__((aligned(2), packed)); |
| 441 | typedef struct HFSCatalogFile HFSCatalogFile; |
| 442 | |
| 443 | /* HFS Plus catalog file record - 248 bytes */ |
| 444 | struct HFSPlusCatalogFile { |
| 445 | 	int16_t 		recordType;		/* == kHFSPlusFileRecord */ |
| 446 | 	u_int16_t 		flags;			/* file flags */ |
| 447 | 	u_int32_t 		reserved1;		/* reserved - initialized as zero */ |
| 448 | 	u_int32_t 		fileID;			/* file ID */ |
| 449 | 	u_int32_t 		createDate;		/* date and time of creation */ |
| 450 | 	u_int32_t 		contentModDate;		/* date and time of last content modification */ |
| 451 | 	u_int32_t 		attributeModDate;	/* date and time of last attribute modification */ |
| 452 | 	u_int32_t 		accessDate;		/* date and time of last access (MacOS X only) */ |
| 453 | 	u_int32_t 		backupDate;		/* date and time of last backup */ |
| 454 | 	HFSPlusBSDInfo 		bsdInfo;		/* permissions (for MacOS X) */ |
| 455 | 	FndrFileInfo 		userInfo;		/* Finder information */ |
| 456 | 	FndrOpaqueInfo	 	finderInfo;		/* additional Finder information */ |
| 457 | 	u_int32_t 		textEncoding;		/* hint for name conversions */ |
| 458 | 	u_int32_t 		reserved2;		/* reserved - initialized as zero */ |
| 459 | |
| 460 | 	/* Note: these start on double long (64 bit) boundary */ |
| 461 | 	HFSPlusForkData 	dataFork;		/* size and block data for data fork */ |
| 462 | 	HFSPlusForkData 	resourceFork;		/* size and block data for resource fork */ |
| 463 | } __attribute__((aligned(2), packed)); |
| 464 | typedef struct HFSPlusCatalogFile HFSPlusCatalogFile; |
| 465 | |
| 466 | /* HFS catalog thread record - 46 bytes */ |
| 467 | struct HFSCatalogThread { |
| 468 | 	int16_t 	recordType;		/* == kHFSFolderThreadRecord or kHFSFileThreadRecord */ |
| 469 | 	int32_t 	reserved[2];		/* reserved - initialized as zero */ |
| 470 | 	u_int32_t 	parentID;		/* parent ID for this catalog node */ |
| 471 | 	u_int8_t 	nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */ |
| 472 | } __attribute__((aligned(2), packed)); |
| 473 | typedef struct HFSCatalogThread HFSCatalogThread; |
| 474 | |
| 475 | /* HFS Plus catalog thread record -- 264 bytes */ |
| 476 | struct HFSPlusCatalogThread { |
| 477 | 	int16_t 	recordType;		/* == kHFSPlusFolderThreadRecord or kHFSPlusFileThreadRecord */ |
| 478 | 	int16_t 	reserved;		/* reserved - initialized as zero */ |
| 479 | 	u_int32_t 	parentID;		/* parent ID for this catalog node */ |
| 480 | 	HFSUniStr255 	nodeName;		/* name of this catalog node (variable length) */ |
| 481 | } __attribute__((aligned(2), packed)); |
| 482 | typedef struct HFSPlusCatalogThread HFSPlusCatalogThread; |
| 483 | |
| 484 | #ifdef __APPLE_API_UNSTABLE |
| 485 | /* |
| 486 | * 	These are the types of records in the attribute B-tree. The values were |
| 487 | * 	chosen so that they wouldn't conflict with the catalog record types. |
| 488 | */ |
| 489 | enum { |
| 490 | 	kHFSPlusAttrInlineData	= 0x10, /* attributes whose data fits in a b-tree node */ |
| 491 | 	kHFSPlusAttrForkData	= 0x20, /* extent based attributes (data lives in extents) */ |
| 492 | 	kHFSPlusAttrExtents	= 0x30 /* overflow extents for large attributes */ |
| 493 | }; |
| 494 | |
| 495 | |
| 496 | /* |
| 497 | * 	HFSPlusAttrForkData |
| 498 | * 	For larger attributes, whose value is stored in allocation blocks. |
| 499 | * 	If the attribute has more than 8 extents, there will be additional |
| 500 | * 	records (of type HFSPlusAttrExtents) for this attribute. |
| 501 | */ |
| 502 | struct HFSPlusAttrForkData { |
| 503 | 	u_int32_t 	recordType;		/* == kHFSPlusAttrForkData*/ |
| 504 | 	u_int32_t 	reserved; |
| 505 | 	HFSPlusForkData theFork;		/* size and first extents of value*/ |
| 506 | } __attribute__((aligned(2), packed)); |
| 507 | typedef struct HFSPlusAttrForkData HFSPlusAttrForkData; |
| 508 | |
| 509 | /* |
| 510 | * 	HFSPlusAttrExtents |
| 511 | * 	This record contains information about overflow extents for large, |
| 512 | * 	fragmented attributes. |
| 513 | */ |
| 514 | struct HFSPlusAttrExtents { |
| 515 | 	u_int32_t 		recordType;	/* == kHFSPlusAttrExtents*/ |
| 516 | 	u_int32_t 		reserved; |
| 517 | 	HFSPlusExtentRecord	extents;	/* additional extents*/ |
| 518 | } __attribute__((aligned(2), packed)); |
| 519 | typedef struct HFSPlusAttrExtents HFSPlusAttrExtents; |
| 520 | |
| 521 | /* |
| 522 | * Atrributes B-tree Data Record |
| 523 | * |
| 524 | * For small attributes, whose entire value is stored |
| 525 | * within a single B-tree record. |
| 526 | */ |
| 527 | struct HFSPlusAttrData { |
| 528 | 	u_int32_t recordType; /* == kHFSPlusAttrInlineData */ |
| 529 | 	u_int32_t reserved[2]; |
| 530 | 	u_int32_t attrSize; /* size of attribute data in bytes */ |
| 531 | 	u_int8_t attrData[2]; /* variable length */ |
| 532 | } __attribute__((aligned(2), packed)); |
| 533 | typedef struct HFSPlusAttrData HFSPlusAttrData; |
| 534 | |
| 535 | |
| 536 | /* HFSPlusAttrInlineData is obsolete use HFSPlusAttrData instead */ |
| 537 | struct HFSPlusAttrInlineData { |
| 538 | 	u_int32_t 	recordType; |
| 539 | 	u_int32_t 	reserved; |
| 540 | 	u_int32_t 	logicalSize; |
| 541 | 	u_int8_t 	userData[2]; |
| 542 | } __attribute__((aligned(2), packed)); |
| 543 | typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData; |
| 544 | |
| 545 | |
| 546 | /* A generic Attribute Record */ |
| 547 | union HFSPlusAttrRecord { |
| 548 | 	u_int32_t 		recordType; |
| 549 | 	HFSPlusAttrInlineData 	inlineData; /* NOT USED */ |
| 550 | 	HFSPlusAttrData 	attrData; |
| 551 | 	HFSPlusAttrForkData 	forkData; |
| 552 | 	HFSPlusAttrExtents 	overflowExtents; |
| 553 | }; |
| 554 | typedef union HFSPlusAttrRecord HFSPlusAttrRecord; |
| 555 | |
| 556 | /* Attribute key */ |
| 557 | enum { kHFSMaxAttrNameLen = 127 }; |
| 558 | struct HFSPlusAttrKey { |
| 559 | 	u_int16_t keyLength; /* key length (in bytes) */ |
| 560 | 	u_int16_t pad;	 /* set to zero */ |
| 561 | 	u_int32_t fileID; /* file associated with attribute */ |
| 562 | 	u_int32_t startBlock; /* first allocation block number for extents */ |
| 563 | 	u_int16_t attrNameLen; /* number of unicode characters */ |
| 564 | 	u_int16_t attrName[kHFSMaxAttrNameLen]; /* attribute name (Unicode) */ |
| 565 | } __attribute__((aligned(2), packed)); |
| 566 | typedef struct HFSPlusAttrKey HFSPlusAttrKey; |
| 567 | |
| 568 | #define kHFSPlusAttrKeyMaximumLength (sizeof(HFSPlusAttrKey) - sizeof(u_int16_t)) |
| 569 | #define kHFSPlusAttrKeyMinimumLength (kHFSPlusAttrKeyMaximumLength - kHFSMaxAttrNameLen*sizeof(u_int16_t)) |
| 570 | |
| 571 | #endif /* __APPLE_API_UNSTABLE */ |
| 572 | |
| 573 | |
| 574 | /* Key and node lengths */ |
| 575 | enum { |
| 576 | 	kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(u_int16_t), |
| 577 | 	kHFSExtentKeyMaximumLength	= sizeof(HFSExtentKey) - sizeof(u_int8_t), |
| 578 | 	kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(u_int16_t), |
| 579 | 	kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(u_int16_t), |
| 580 | 	kHFSCatalogKeyMaximumLength	= sizeof(HFSCatalogKey) - sizeof(u_int8_t), |
| 581 | 	kHFSCatalogKeyMinimumLength	= kHFSCatalogKeyMaximumLength - (kHFSMaxFileNameChars + 1) + sizeof(u_int8_t), |
| 582 | 	kHFSPlusCatalogMinNodeSize	= 4096, |
| 583 | 	kHFSPlusExtentMinNodeSize	= 512, |
| 584 | 	kHFSPlusAttrMinNodeSize		= 4096 |
| 585 | }; |
| 586 | |
| 587 | /* HFS and HFS Plus volume attribute bits */ |
| 588 | enum { |
| 589 | 	/* Bits 0-6 are reserved (always cleared by MountVol call) */ |
| 590 | 	kHFSVolumeHardwareLockBit	= 7,		/* volume is locked by hardware */ |
| 591 | 	kHFSVolumeUnmountedBit		= 8,		/* volume was successfully unmounted */ |
| 592 | 	kHFSVolumeSparedBlocksBit	= 9,		/* volume has bad blocks spared */ |
| 593 | 	kHFSVolumeNoCacheRequiredBit = 10,		/* don't cache volume blocks (i.e. RAM or ROM disk) */ |
| 594 | 	kHFSBootVolumeInconsistentBit = 11,		/* boot volume is inconsistent (System 7.6 and later) */ |
| 595 | 	kHFSCatalogNodeIDsReusedBit = 12, |
| 596 | 	kHFSVolumeJournaledBit = 13,			/* this volume has a journal on it */ |
| 597 | 	kHFSVolumeInconsistentBit = 14,			/* serious inconsistencies detected at runtime */ |
| 598 | 	kHFSVolumeSoftwareLockBit	= 15,		/* volume is locked by software */ |
| 599 | 	/* |
| 600 | 	 * HFS only has 16 bits of attributes in the MDB, but HFS Plus has 32 bits. |
| 601 | 	 * Therefore, bits 16-31 can only be used on HFS Plus. |
| 602 | 	 */ |
| 603 | 	kHFSUnusedNodeFixBit = 31,				/* Unused nodes in the Catalog B-tree have been zero-filled. See Radar #6947811. */ |
| 604 | 	kHFSContentProtectionBit = 30,			/* Volume has per-file content protection */ |
| 605 | 	kHFSExpandedTimesBit = 29,				/* Volume has expanded / non-MacOS native timestamps */ |
| 606 | |
| 607 | 	/*** Keep these in sync with the bits above ! ****/ |
| 608 | 	kHFSVolumeHardwareLockMask		= 0x00000080, |
| 609 | 	kHFSVolumeUnmountedMask			= 0x00000100, |
| 610 | 	kHFSVolumeSparedBlocksMask		= 0x00000200, |
| 611 | 	kHFSVolumeNoCacheRequiredMask 	= 0x00000400, |
| 612 | 	kHFSBootVolumeInconsistentMask	= 0x00000800, |
| 613 | 	kHFSCatalogNodeIDsReusedMask 	= 0x00001000, |
| 614 | 	kHFSVolumeJournaledMask			= 0x00002000, |
| 615 | 	kHFSVolumeInconsistentMask 		= 0x00004000, |
| 616 | 	kHFSVolumeSoftwareLockMask		= 0x00008000, |
| 617 | 	 |
| 618 | 	/* Bits 16-31 are allocated from high to low */ |
| 619 | |
| 620 | 	kHFSExpandedTimesMask			= 0x20000000, |
| 621 | 	kHFSContentProtectionMask 		= 0x40000000, |
| 622 | 	kHFSUnusedNodeFixMask 			= 0x80000000, |
| 623 | 	 |
| 624 | 	kHFSMDBAttributesMask			= 0x8380 |
| 625 | }; |
| 626 | |
| 627 | enum { |
| 628 | 	kHFSUnusedNodesFixDate 			= 0xc5ef2480, /* March 25, 2009 (aka 3320784000) */ |
| 629 | 	kHFSUnusedNodesFixExpandedDate 	= 0x49c97400 /* March 25, 2009 (akai 1237939200) - BSD epoch-relative */ |
| 630 | }; |
| 631 | |
| 632 | /* HFS Master Directory Block - 162 bytes */ |
| 633 | /* Stored at sector #2 (3rd sector) and second-to-last sector. */ |
| 634 | struct HFSMasterDirectoryBlock { |
| 635 | 	u_int16_t 		drSigWord;	/* == kHFSSigWord */ |
| 636 | 	u_int32_t 		drCrDate;	/* date and time of volume creation */ |
| 637 | 	u_int32_t 		drLsMod;	/* date and time of last modification */ |
| 638 | 	u_int16_t 		drAtrb;		/* volume attributes */ |
| 639 | 	u_int16_t 		drNmFls;	/* number of files in root folder */ |
| 640 | 	u_int16_t 		drVBMSt;	/* first block of volume bitmap */ |
| 641 | 	u_int16_t 		drAllocPtr;	/* start of next allocation search */ |
| 642 | 	u_int16_t 		drNmAlBlks;	/* number of allocation blocks in volume */ |
| 643 | 	u_int32_t 		drAlBlkSiz;	/* size (in bytes) of allocation blocks */ |
| 644 | 	u_int32_t 		drClpSiz;	/* default clump size */ |
| 645 | 	u_int16_t 		drAlBlSt;	/* first allocation block in volume */ |
| 646 | 	u_int32_t 		drNxtCNID;	/* next unused catalog node ID */ |
| 647 | 	u_int16_t 		drFreeBks;	/* number of unused allocation blocks */ |
| 648 | 	u_int8_t 		drVN[kHFSMaxVolumeNameChars + 1]; /* volume name */ |
| 649 | 	u_int32_t 		drVolBkUp;	/* date and time of last backup */ |
| 650 | 	u_int16_t 		drVSeqNum;	/* volume backup sequence number */ |
| 651 | 	u_int32_t 		drWrCnt;	/* volume write count */ |
| 652 | 	u_int32_t 		drXTClpSiz;	/* clump size for extents overflow file */ |
| 653 | 	u_int32_t 		drCTClpSiz;	/* clump size for catalog file */ |
| 654 | 	u_int16_t 		drNmRtDirs;	/* number of directories in root folder */ |
| 655 | 	u_int32_t 		drFilCnt;	/* number of files in volume */ |
| 656 | 	u_int32_t 		drDirCnt;	/* number of directories in volume */ |
| 657 | 	u_int32_t 		drFndrInfo[8];	/* information used by the Finder */ |
| 658 | 	u_int16_t 		drEmbedSigWord;	/* embedded volume signature (formerly drVCSize) */ |
| 659 | 	HFSExtentDescriptor	drEmbedExtent;	/* embedded volume location and size (formerly drVBMCSize and drCtlCSize) */ |
| 660 | 	u_int32_t		drXTFlSize;	/* size of extents overflow file */ |
| 661 | 	HFSExtentRecord		drXTExtRec;	/* extent record for extents overflow file */ |
| 662 | 	u_int32_t 		drCTFlSize;	/* size of catalog file */ |
| 663 | 	HFSExtentRecord 	drCTExtRec;	/* extent record for catalog file */ |
| 664 | } __attribute__((aligned(2), packed)); |
| 665 | typedef struct HFSMasterDirectoryBlock	HFSMasterDirectoryBlock; |
| 666 | |
| 667 | |
| 668 | #ifdef __APPLE_API_UNSTABLE |
| 669 | #define SET_HFS_TEXT_ENCODING(hint) \ |
| 670 | 	(0x656e6300 | ((hint) & 0xff)) |
| 671 | #define GET_HFS_TEXT_ENCODING(hint) \ |
| 672 | 	(((hint) & 0xffffff00) == 0x656e6300 ? (hint) & 0x000000ff : 0xffffffffU) |
| 673 | #endif /* __APPLE_API_UNSTABLE */ |
| 674 | |
| 675 | |
| 676 | /* HFS Plus Volume Header - 512 bytes */ |
| 677 | /* Stored at sector #2 (3rd sector) and second-to-last sector. */ |
| 678 | struct HFSPlusVolumeHeader { |
| 679 | 	u_int16_t 	signature;		/* == kHFSPlusSigWord */ |
| 680 | 	u_int16_t 	version;		/* == kHFSPlusVersion */ |
| 681 | 	u_int32_t 	attributes;		/* volume attributes */ |
| 682 | 	u_int32_t 	lastMountedVersion;	/* implementation version which last mounted volume */ |
| 683 | 	u_int32_t 	journalInfoBlock;	/* block addr of journal info (if volume is journaled, zero otherwise) */ |
| 684 | |
| 685 | 	u_int32_t 	createDate;		/* date and time of volume creation */ |
| 686 | 	u_int32_t 	modifyDate;		/* date and time of last modification */ |
| 687 | 	u_int32_t 	backupDate;		/* date and time of last backup */ |
| 688 | 	u_int32_t 	checkedDate;		/* date and time of last disk check */ |
| 689 | |
| 690 | 	u_int32_t 	fileCount;		/* number of files in volume */ |
| 691 | 	u_int32_t 	folderCount;		/* number of directories in volume */ |
| 692 | |
| 693 | 	u_int32_t 	blockSize;		/* size (in bytes) of allocation blocks */ |
| 694 | 	u_int32_t 	totalBlocks;		/* number of allocation blocks in volume (includes this header and VBM*/ |
| 695 | 	u_int32_t 	freeBlocks;		/* number of unused allocation blocks */ |
| 696 | |
| 697 | 	u_int32_t 	nextAllocation;		/* start of next allocation search */ |
| 698 | 	u_int32_t 	rsrcClumpSize;		/* default resource fork clump size */ |
| 699 | 	u_int32_t 	dataClumpSize;		/* default data fork clump size */ |
| 700 | 	u_int32_t 	nextCatalogID;		/* next unused catalog node ID */ |
| 701 | |
| 702 | 	u_int32_t 	writeCount;		/* volume write count */ |
| 703 | 	u_int64_t 	encodingsBitmap;	/* which encodings have been use on this volume */ |
| 704 | |
| 705 | 	u_int8_t 	finderInfo[32];		/* information used by the Finder */ |
| 706 | |
| 707 | 	HFSPlusForkData	 allocationFile;	/* allocation bitmap file */ |
| 708 | 	HFSPlusForkData extentsFile;		/* extents B-tree file */ |
| 709 | 	HFSPlusForkData catalogFile;		/* catalog B-tree file */ |
| 710 | 	HFSPlusForkData attributesFile;	/* extended attributes B-tree file */ |
| 711 | 	HFSPlusForkData	 startupFile;		/* boot file (secondary loader) */ |
| 712 | } __attribute__((aligned(2), packed)); |
| 713 | typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader; |
| 714 | |
| 715 | |
| 716 | /* B-tree structures */ |
| 717 | |
| 718 | enum BTreeKeyLimits{ |
| 719 | 	kMaxKeyLength	= 520 |
| 720 | }; |
| 721 | |
| 722 | union BTreeKey{ |
| 723 | 	u_int8_t	length8; |
| 724 | 	u_int16_t	length16; |
| 725 | 	u_int8_t	rawData [kMaxKeyLength+2]; |
| 726 | }; |
| 727 | typedef union BTreeKey BTreeKey; |
| 728 | |
| 729 | /* BTNodeDescriptor -- Every B-tree node starts with these fields. */ |
| 730 | struct BTNodeDescriptor { |
| 731 | 	u_int32_t	fLink;			/* next node at this level*/ |
| 732 | 	u_int32_t 	bLink;			/* previous node at this level*/ |
| 733 | 	int8_t 		kind;			/* kind of node (leaf, index, header, map)*/ |
| 734 | 	u_int8_t 	height;			/* zero for header, map; child is one more than parent*/ |
| 735 | 	u_int16_t 	numRecords;		/* number of records in this node*/ |
| 736 | 	u_int16_t 	reserved;		/* reserved - initialized as zero */ |
| 737 | } __attribute__((aligned(2), packed)); |
| 738 | typedef struct BTNodeDescriptor BTNodeDescriptor; |
| 739 | |
| 740 | /* Constants for BTNodeDescriptor kind */ |
| 741 | enum { |
| 742 | 	kBTLeafNode	= -1, |
| 743 | 	kBTIndexNode	= 0, |
| 744 | 	kBTHeaderNode	= 1, |
| 745 | 	kBTMapNode	= 2 |
| 746 | }; |
| 747 | |
| 748 | /* BTHeaderRec -- The first record of a B-tree header node */ |
| 749 | struct BTHeaderRec { |
| 750 | 	u_int16_t	treeDepth;		/* maximum height (usually leaf nodes) */ |
| 751 | 	u_int32_t 	rootNode;		/* node number of root node */ |
| 752 | 	u_int32_t 	leafRecords;		/* number of leaf records in all leaf nodes */ |
| 753 | 	u_int32_t 	firstLeafNode;		/* node number of first leaf node */ |
| 754 | 	u_int32_t 	lastLeafNode;		/* node number of last leaf node */ |
| 755 | 	u_int16_t 	nodeSize;		/* size of a node, in bytes */ |
| 756 | 	u_int16_t 	maxKeyLength;		/* reserved */ |
| 757 | 	u_int32_t 	totalNodes;		/* total number of nodes in tree */ |
| 758 | 	u_int32_t 	freeNodes;		/* number of unused (free) nodes in tree */ |
| 759 | 	u_int16_t 	reserved1;		/* unused */ |
| 760 | 	u_int32_t 	clumpSize;		/* reserved */ |
| 761 | 	u_int8_t 	btreeType;		/* reserved */ |
| 762 | 	u_int8_t 	keyCompareType;		/* Key string Comparison Type */ |
| 763 | 	u_int32_t 	attributes;		/* persistent attributes about the tree */ |
| 764 | 	u_int32_t 	reserved3[16];		/* reserved */ |
| 765 | } __attribute__((aligned(2), packed)); |
| 766 | typedef struct BTHeaderRec BTHeaderRec; |
| 767 | |
| 768 | /* Constants for BTHeaderRec attributes */ |
| 769 | enum { |
| 770 | 	kBTBadCloseMask		 = 0x00000001,	/* reserved */ |
| 771 | 	kBTBigKeysMask		 = 0x00000002,	/* key length field is 16 bits */ |
| 772 | 	kBTVariableIndexKeysMask = 0x00000004	/* keys in index nodes are variable length */ |
| 773 | }; |
| 774 | |
| 775 | |
| 776 | /* Catalog Key Name Comparison Type */ |
| 777 | enum { |
| 778 | 	kHFSCaseFolding = 0xCF, /* case folding (case-insensitive) */ |
| 779 | 	kHFSBinaryCompare = 0xBC /* binary compare (case-sensitive) */ |
| 780 | }; |
| 781 | |
| 782 | #ifdef __cplusplus |
| 783 | } |
| 784 | #endif |
| 785 | |
| 786 | #include <uuid/uuid.h> |
| 787 | |
| 788 | #ifdef __cplusplus |
| 789 | extern "C" { |
| 790 | #endif |
| 791 | |
| 792 | /* JournalInfoBlock - Structure that describes where our journal lives */ |
| 793 | |
| 794 | // the original size of the reserved field in the JournalInfoBlock was |
| 795 | // 32*sizeof(u_int32_t). To keep the total size of the structure the |
| 796 | // same we subtract the size of new fields (currently: ext_jnl_uuid and |
| 797 | // machine_uuid). If you add additional fields, place them before the |
| 798 | // reserved field and subtract their size in this macro. |
| 799 | // |
| 800 | #define JIB_RESERVED_SIZE ((32*sizeof(u_int32_t)) - sizeof(uuid_string_t) - 48) |
| 801 | |
| 802 | struct JournalInfoBlock { |
| 803 | 	u_int32_t	flags; |
| 804 | 	u_int32_t device_signature[8]; // signature used to locate our device. |
| 805 | 	u_int64_t offset; // byte offset to the journal on the device |
| 806 | 	u_int64_t size; // size in bytes of the journal |
| 807 | 	uuid_string_t ext_jnl_uuid; |
| 808 | 	char machine_serial_num[48]; |
| 809 | 	char 	reserved[JIB_RESERVED_SIZE]; |
| 810 | } __attribute__((aligned(2), packed)); |
| 811 | typedef struct JournalInfoBlock JournalInfoBlock; |
| 812 | |
| 813 | enum { |
| 814 | kJIJournalInFSMask = 0x00000001, |
| 815 | kJIJournalOnOtherDeviceMask = 0x00000002, |
| 816 | kJIJournalNeedInitMask = 0x00000004 |
| 817 | }; |
| 818 | |
| 819 | // |
| 820 | // This the content type uuid for "external journal" GPT |
| 821 | // partitions. Each instance of a partition also has a |
| 822 | // uuid that uniquely identifies that instance. |
| 823 | // |
| 824 | #define EXTJNL_CONTENT_TYPE_UUID "4A6F7572-6E61-11AA-AA11-00306543ECAC" |
| 825 | |
| 826 | |
| 827 | #ifdef __cplusplus |
| 828 | } |
| 829 | #endif |
| 830 | |
| 831 | #endif /* __HFS_FORMAT__ */ |