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