/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef __HFS_FORMAT__
#define __HFS_FORMAT__
+#include <sys/types.h>
#include <sys/appleapiopts.h>
/*
enum {
kHFSSigWord = 0x4244, /* 'BD' in ASCII */
kHFSPlusSigWord = 0x482B, /* 'H+' in ASCII */
- kHFSPlusVersion = 0x0004, /* will change as format changes */
- /* version 4 shipped with Mac OS 8.1 */
- kHFSPlusMountVersion = 0x31302E30 /* '10.0' for Mac OS X */
+ kHFSXSigWord = 0x4858, /* 'HX' in ASCII */
+
+ kHFSPlusVersion = 0x0004, /* 'H+' volumes are version 4 only */
+ kHFSXVersion = 0x0005, /* 'HX' volumes start with version 5 */
+
+ kHFSPlusMountVersion = 0x31302E30, /* '10.0' for Mac OS X */
+ kHFSJMountVersion = 0x4846534a, /* 'HFSJ' for journaled HFS+ on OS X */
+ kFSKMountVersion = 0x46534b21 /* 'FSK!' for failed journal replay */
};
};
+#ifndef _HFSUNISTR255_DEFINED_
+#define _HFSUNISTR255_DEFINED_
/* Unicode strings are used for HFS Plus file and folder names */
struct HFSUniStr255 {
u_int16_t length; /* number of unicode characters */
};
typedef struct HFSUniStr255 HFSUniStr255;
typedef const HFSUniStr255 *ConstHFSUniStr255Param;
+#endif /* _HFSUNISTR255_DEFINED_ */
enum {
kHFSMaxVolumeNameChars = 27,
kHFSAllocationFileID = 6, /* File ID of the allocation file (HFS Plus only) */
kHFSStartupFileID = 7, /* File ID of the startup file (HFS Plus only) */
kHFSAttributesFileID = 8, /* File ID of the attribute file (HFS Plus only) */
+ kHFSRepairCatalogFileID = 14, /* Used when rebuilding Catalog B-tree */
kHFSBogusExtentFileID = 15, /* Used for exchanging extents in extents file */
kHFSFirstUserCatalogNodeID = 16
};
u_int8_t keyLength; /* key length (in bytes) */
u_int8_t reserved; /* reserved (set to zero) */
u_int32_t parentID; /* parent folder ID */
- u_char nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */
+ u_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */
};
typedef struct HFSCatalogKey HFSCatalogKey;
enum {
kHFSFileLockedBit = 0x0000, /* file is locked and cannot be written to */
kHFSFileLockedMask = 0x0001,
+
kHFSThreadExistsBit = 0x0001, /* a file thread record exists for this file */
- kHFSThreadExistsMask = 0x0002
+ kHFSThreadExistsMask = 0x0002,
+
+ kHFSHasAttributesBit = 0x0002, /* object has extended attributes */
+ kHFSHasAttributesMask = 0x0004,
+
+ kHFSHasSecurityBit = 0x0003, /* object has security data (ACLs) */
+ kHFSHasSecurityMask = 0x0008
};
FndrDirInfo userInfo; /* Finder information */
FndrOpaqueInfo finderInfo; /* additional Finder information */
u_int32_t textEncoding; /* hint for name conversions */
- u_int32_t reserved; /* reserved - initialized as zero */
+ u_int32_t attrBlocks; /* cached count of attribute data blocks */
};
typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder;
FndrFileInfo userInfo; /* Finder information */
FndrOpaqueInfo finderInfo; /* additional Finder information */
u_int32_t textEncoding; /* hint for name conversions */
- u_int32_t reserved2; /* reserved - initialized as zero */
+ u_int32_t attrBlocks; /* cached count of attribute data blocks */
/* Note: these start on double long (64 bit) boundry */
HFSPlusForkData dataFork; /* size and block data for data fork */
int16_t recordType; /* == kHFSFolderThreadRecord or kHFSFileThreadRecord */
int32_t reserved[2]; /* reserved - initialized as zero */
u_int32_t parentID; /* parent ID for this catalog node */
- u_char nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */
+ u_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */
};
typedef struct HFSCatalogThread HFSCatalogThread;
chosen so that they wouldn't conflict with the catalog record types.
*/
enum {
- kHFSPlusAttrInlineData = 0x10, /* if size < kAttrOverflowSize */
- kHFSPlusAttrForkData = 0x20, /* if size >= kAttrOverflowSize */
- kHFSPlusAttrExtents = 0x30 /* overflow extents for large attributes */
-};
-
-
-/*
- HFSPlusAttrInlineData
- For small attributes, whose entire value is stored within this one
- B-tree record.
- There would not be any other records for this attribute.
-*/
-struct HFSPlusAttrInlineData {
- u_int32_t recordType; /* == kHFSPlusAttrInlineData*/
- u_int32_t reserved;
- u_int32_t logicalSize; /* size in bytes of userData*/
- u_int8_t userData[2]; /* variable length; space allocated is a multiple of 2 bytes*/
+ kHFSPlusAttrInlineData = 0x10, /* if size < kAttrOverflowSize */
+ kHFSPlusAttrForkData = 0x20, /* if size >= kAttrOverflowSize */
+ kHFSPlusAttrExtents = 0x30 /* overflow extents for large attributes */
};
-typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData;
/*
};
typedef struct HFSPlusAttrExtents HFSPlusAttrExtents;
+/*
+ * Atrributes B-tree Data Record
+ *
+ * For small attributes, whose entire value is stored
+ * within a single B-tree record.
+ */
+struct HFSPlusAttrData {
+ u_int32_t recordType; /* == kHFSPlusAttrInlineData */
+ u_int32_t reserved[2];
+ u_int32_t attrSize; /* size of attribute data in bytes */
+ u_int8_t attrData[2]; /* variable length */
+};
+typedef struct HFSPlusAttrData HFSPlusAttrData;
+
+
+/* HFSPlusAttrInlineData is obsolete use HFSPlusAttrData instead */
+struct HFSPlusAttrInlineData {
+ u_int32_t recordType;
+ u_int32_t reserved;
+ u_int32_t logicalSize;
+ u_int8_t userData[2];
+};
+typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData;
+
+
/* A generic Attribute Record*/
union HFSPlusAttrRecord {
u_int32_t recordType;
- HFSPlusAttrInlineData inlineData;
+ HFSPlusAttrInlineData inlineData; /* NOT USED */
+ HFSPlusAttrData attrData;
HFSPlusAttrForkData forkData;
HFSPlusAttrExtents overflowExtents;
};
typedef union HFSPlusAttrRecord HFSPlusAttrRecord;
+/* Attribute key */
+enum { kHFSMaxAttrNameLen = 127 };
+struct HFSPlusAttrKey {
+ u_int16_t keyLength; /* key length (in bytes) */
+ u_int16_t pad; /* set to zero */
+ u_int32_t fileID; /* file associated with attribute */
+ u_int32_t startBlock; /* first attribue allocation block number for extents */
+ u_int16_t attrNameLen; /* number of unicode characters */
+ u_int16_t attrName[kHFSMaxAttrNameLen]; /* attribute name (Unicode) */
+};
+typedef struct HFSPlusAttrKey HFSPlusAttrKey;
+
+#define kHFSPlusAttrKeyMaximumLength (sizeof(HFSPlusAttrKey) - sizeof(u_int16_t))
+#define kHFSPlusAttrKeyMinimumLength (kHFSPlusAttrKeyMaximumLength - kHFSMaxAttrNameLen*sizeof(u_int16_t))
+
+#endif /* __APPLE_API_UNSTABLE */
+
+
/* Key and node lengths */
enum {
kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(u_int16_t),
kHFSPlusExtentMinNodeSize = 512,
kHFSPlusAttrMinNodeSize = 4096
};
-#endif /* __APPLE_API_UNSTABLE */
/* HFS and HFS Plus volume attribute bits */
enum {
kHFSVolumeNoCacheRequiredBit = 10, /* don't cache volume blocks (i.e. RAM or ROM disk) */
kHFSBootVolumeInconsistentBit = 11, /* boot volume is inconsistent (System 7.6 and later) */
kHFSCatalogNodeIDsReusedBit = 12,
- /* Bits 13-14 are reserved for future use */
+ kHFSVolumeJournaledBit = 13, /* this volume has a journal on it */
+ kHFSVolumeInconsistentBit = 14, /* serious inconsistencies detected at runtime */
kHFSVolumeSoftwareLockBit = 15, /* volume is locked by software */
kHFSVolumeHardwareLockMask = 1 << kHFSVolumeHardwareLockBit,
kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit,
kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit,
kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit,
+ kHFSVolumeJournaledMask = 1 << kHFSVolumeJournaledBit,
+ kHFSVolumeInconsistentMask = 1 << kHFSVolumeInconsistentBit,
kHFSVolumeSoftwareLockMask = 1 << kHFSVolumeSoftwareLockBit,
kHFSMDBAttributesMask = 0x8380
};
u_int16_t drAlBlSt; /* first allocation block in volume */
u_int32_t drNxtCNID; /* next unused catalog node ID */
u_int16_t drFreeBks; /* number of unused allocation blocks */
- u_char drVN[kHFSMaxVolumeNameChars + 1]; /* volume name */
+ u_int8_t drVN[kHFSMaxVolumeNameChars + 1]; /* volume name */
u_int32_t drVolBkUp; /* date and time of last backup */
u_int16_t drVSeqNum; /* volume backup sequence number */
u_int32_t drWrCnt; /* volume write count */
typedef struct HFSMasterDirectoryBlock HFSMasterDirectoryBlock;
+#ifdef __APPLE_API_UNSTABLE
+#define SET_HFS_TEXT_ENCODING(hint) \
+ (0x656e6300 | ((hint) & 0xff))
+#define GET_HFS_TEXT_ENCODING(hint) \
+ (((hint) & 0xffffff00) == 0x656e6300 ? (hint) & 0x000000ff : 0xffffffffU)
+#endif /* __APPLE_API_UNSTABLE */
+
+
/* HFS Plus Volume Header - 512 bytes */
/* Stored at sector #2 (3rd sector) and second-to-last sector. */
struct HFSPlusVolumeHeader {
u_int16_t version; /* == kHFSPlusVersion */
u_int32_t attributes; /* volume attributes */
u_int32_t lastMountedVersion; /* implementation version which last mounted volume */
- u_int32_t reserved; /* reserved - initialized as zero */
+ u_int32_t journalInfoBlock; /* block addr of journal info (if volume is journaled, zero otherwise) */
u_int32_t createDate; /* date and time of volume creation */
u_int32_t modifyDate; /* date and time of last modification */
u_int16_t reserved1; /* unused */
u_int32_t clumpSize; /* reserved */
u_int8_t btreeType; /* reserved */
- u_int8_t reserved2; /* reserved */
+ u_int8_t keyCompareType; /* Key string Comparison Type */
u_int32_t attributes; /* persistent attributes about the tree */
u_int32_t reserved3[16]; /* reserved */
};
kBTVariableIndexKeysMask = 0x00000004 /* keys in index nodes are variable length */
};
+
+/* Catalog Key Name Comparison Type */
+enum {
+ kHFSCaseFolding = 0xCF, /* case folding (case-insensitive) */
+ kHFSBinaryCompare = 0xBC /* binary compare (case-sensitive) */
+};
+
+/* JournalInfoBlock - Structure that describes where our journal lives */
+struct JournalInfoBlock {
+ u_int32_t flags;
+ u_int32_t device_signature[8]; // signature used to locate our device.
+ u_int64_t offset; // byte offset to the journal on the device
+ u_int64_t size; // size in bytes of the journal
+ u_int32_t reserved[32];
+};
+typedef struct JournalInfoBlock JournalInfoBlock;
+
+enum {
+ kJIJournalInFSMask = 0x00000001,
+ kJIJournalOnOtherDeviceMask = 0x00000002,
+ kJIJournalNeedInitMask = 0x00000004
+};
+
+
#pragma options align=reset
#ifdef __cplusplus