Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/i386/include/hfs/hfs_format.h

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

Archive Download this file

Revision: 2238