CloverBootloader/FileSystems/VBoxFsDxe/hfs_format.h
2019-09-03 12:58:42 +03:00

912 lines
35 KiB
C

/* $Id: hfs_format.h 33540 2010-10-28 09:27:05Z vboxsync $ */
/** @file
* hfs_format.h
*/
/*
* Copyright (C) 2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*
* This code is based on:
*
* Copyright (c) 2000-2007 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* 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.
*
* 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef __HFS_FORMAT__
#define __HFS_FORMAT__
//#if !defined(VBOX) && !defined(HOST_POSIX)
//#include <sys/types.h>
//#include <sys/appleapiopts.h>
//#endif
#ifdef _MSC_VER
# pragma pack(push,2)
# define HFS_ALIGNMENT
#else
#define HFS_ALIGNMENT __attribute__((aligned(2), packed))
#endif
/*
* hfs_format.c
*
* This file describes the on-disk format for HFS and HFS Plus volumes.
* The HFS Plus volume format is described in detail in Apple Technote 1150.
*
* http://developer.apple.com/technotes/tn/tn1150.html
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/* some on-disk hfs structures have 68K alignment (misaligned) */
/* Signatures used to differentiate between HFS and HFS Plus volumes */
enum {
kHFSSigWord = 0x4244, /* 'BD' in ASCII */
kHFSPlusSigWord = 0x482B, /* 'H+' in ASCII */
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 */
};
#ifdef __APPLE_API_PRIVATE
/*
* Mac OS X has two special directories on HFS+ volumes for hardlinked files
* and hardlinked directories as well as for open-unlinked files.
*
* These directories and their contents are not exported from the filesystem
* under Mac OS X.
*/
#define HFSPLUSMETADATAFOLDER "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data"
#define HFSPLUS_DIR_METADATA_FOLDER ".HFS+ Private Directory Data\xd"
/*
* Files in the "HFS+ Private Data" folder have one of the following prefixes
* followed by a decimal number (no leading zeros) for the file ID.
*
* Note: Earlier version of Mac OS X used a 32 bit random number for the link
* ref number instead of the file id.
*
* e.g. iNode7182000 and temp3296
*/
#define HFS_INODE_PREFIX "iNode"
#define HFS_DELETE_PREFIX "temp"
/*
* Files in the ".HFS+ Private Directory Data" folder have the following
* prefix followed by a decimal number (no leading zeros) for the file ID.
*
* e.g. dir_555
*/
#define HFS_DIRINODE_PREFIX "dir_"
/*
* Hardlink inodes save the head of the link chain in
* an extended attribute named FIRST_LINK_XATTR_NAME.
* The attribute data is the decimal value in ASCII
* of the cnid for the first link in the chain.
*
* This extended attribute is private (i.e. its not
* exported in the getxattr/listxattr POSIX APIs).
*/
#define FIRST_LINK_XATTR_NAME "com.apple.system.hfs.firstlink"
#define FIRST_LINK_XATTR_REC_SIZE (sizeof(HFSPlusAttrData) - 2 + 12)
#endif /* __APPLE_API_PRIVATE */
/*
* Indirect link files (hard links) have the following type/creator.
*/
enum {
kHardLinkFileType = 0x686C6E6B, /* 'hlnk' */
kHFSPlusCreator = 0x6866732B /* 'hfs+' */
};
/*
* File type and creator for symbolic links
*/
enum {
kSymLinkFileType = 0x736C6E6B, /* 'slnk' */
kSymLinkCreator = 0x72686170 /* 'rhap' */
};
/* Finder Info's file type and creator for directory hard link alias */
enum {
kHFSAliasType = 0x66647270, /* 'fdrp' */
kHFSAliasCreator = 0x4D414353 /* 'MACS' */
};
#define HFS_LOOKUP_SYSFILE 0x1 /* If set, allow lookup of system files */
#define HFS_LOOKUP_HARDLINK 0x2 /* If set, allow lookup of hard link records and not resolve the hard links */
#define HFS_LOOKUP_CASESENSITIVE 0x4 /* If set, verify results of a file/directory record match input case */
#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 */
u_int16_t unicode[255]; /* unicode characters */
} HFS_ALIGNMENT;
typedef struct HFSUniStr255 HFSUniStr255;
typedef const HFSUniStr255 *ConstHFSUniStr255Param;
#endif /* _HFSUNISTR255_DEFINED_ */
enum {
kHFSMaxVolumeNameChars = 27,
kHFSMaxFileNameChars = 31,
kHFSPlusMaxFileNameChars = 255
};
/* Extent overflow file data structures */
/* HFS Extent key */
struct HFSExtentKey {
u_int8_t keyLength; /* length of key, excluding this field */
u_int8_t forkType; /* 0 = data fork, FF = resource fork */
u_int32_t fileID; /* file ID */
u_int16_t startBlock; /* first file allocation block number in this extent */
} HFS_ALIGNMENT;
typedef struct HFSExtentKey HFSExtentKey;
/* HFS Plus Extent key */
struct HFSPlusExtentKey {
u_int16_t keyLength; /* length of key, excluding this field */
u_int8_t forkType; /* 0 = data fork, FF = resource fork */
u_int8_t pad; /* make the other fields align on 32-bit boundary */
u_int32_t fileID; /* file ID */
u_int32_t startBlock; /* first file allocation block number in this extent */
} HFS_ALIGNMENT;
typedef struct HFSPlusExtentKey HFSPlusExtentKey;
/* Number of extent descriptors per extent record */
enum {
kHFSExtentDensity = 3,
kHFSPlusExtentDensity = 8
};
/* HFS extent descriptor */
struct HFSExtentDescriptor {
u_int16_t startBlock; /* first allocation block */
u_int16_t blockCount; /* number of allocation blocks */
} HFS_ALIGNMENT;
typedef struct HFSExtentDescriptor HFSExtentDescriptor;
/* HFS Plus extent descriptor */
struct HFSPlusExtentDescriptor {
u_int32_t startBlock; /* first allocation block */
u_int32_t blockCount; /* number of allocation blocks */
} HFS_ALIGNMENT;
typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor;
/* HFS extent record */
typedef HFSExtentDescriptor HFSExtentRecord[3];
/* HFS Plus extent record */
typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8];
/* Finder information */
struct FndrFileInfo {
u_int32_t fdType; /* file type */
u_int32_t fdCreator; /* file creator */
u_int16_t fdFlags; /* Finder flags */
struct {
int16_t v; /* file's location */
int16_t h;
} fdLocation;
int16_t opaque;
} HFS_ALIGNMENT;
typedef struct FndrFileInfo FndrFileInfo;
struct FndrDirInfo {
struct { /* folder's window rectangle */
int16_t top;
int16_t left;
int16_t bottom;
int16_t right;
} frRect;
unsigned short frFlags; /* Finder flags */
struct {
u_int16_t v; /* folder's location */
u_int16_t h;
} frLocation;
int16_t opaque;
} HFS_ALIGNMENT;
typedef struct FndrDirInfo FndrDirInfo;
struct FndrOpaqueInfo {
int8_t opaque[16];
} HFS_ALIGNMENT;
typedef struct FndrOpaqueInfo FndrOpaqueInfo;
/* HFS Plus Fork data info - 80 bytes */
struct HFSPlusForkData {
u_int64_t logicalSize; /* fork's logical size in bytes */
u_int32_t clumpSize; /* fork's clump size in bytes */
u_int32_t totalBlocks; /* total blocks used by this fork */
HFSPlusExtentRecord extents; /* initial set of extents */
} HFS_ALIGNMENT;
typedef struct HFSPlusForkData HFSPlusForkData;
/* Mac OS X has 16 bytes worth of "BSD" info.
*
* Note: Mac OS 9 implementations and applications
* should preserve, but not change, this information.
*/
struct HFSPlusBSDInfo {
u_int32_t ownerID; /* user-id of owner or hard link chain previous link */
u_int32_t groupID; /* group-id of owner or hard link chain next link */
u_int8_t adminFlags; /* super-user changeable flags */
u_int8_t ownerFlags; /* owner changeable flags */
u_int16_t fileMode; /* file type and permission bits */
union {
u_int32_t iNodeNum; /* indirect node number (hard links only) */
u_int32_t linkCount; /* links that refer to this indirect node */
u_int32_t rawDevice; /* special file device (FBLK and FCHR only) */
} special;
} HFS_ALIGNMENT;
typedef struct HFSPlusBSDInfo HFSPlusBSDInfo;
/*
* Hardlink "links" resolve to an inode
* and the actual uid/gid comes from that
* inode.
*
* We repurpose the links's uid/gid fields
* for the hardlink link chain. The chain
* consists of a doubly linked list of file
* ids.
*/
#define hl_firstLinkID reserved1 /* Valid only if HasLinkChain flag is set (indirect nodes only) */
#define hl_prevLinkID bsdInfo.ownerID /* Valid only if HasLinkChain flag is set */
#define hl_nextLinkID bsdInfo.groupID /* Valid only if HasLinkChain flag is set */
#define hl_linkReference bsdInfo.special.iNodeNum
#define hl_linkCount bsdInfo.special.linkCount
/* Catalog file data structures */
enum {
kHFSRootParentID = 1, /* Parent ID of the root folder */
kHFSRootFolderID = 2, /* Folder ID of the root folder */
kHFSExtentsFileID = 3, /* File ID of the extents file */
kHFSCatalogFileID = 4, /* File ID of the catalog file */
kHFSBadBlockFileID = 5, /* File ID of the bad allocation block file */
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) */
kHFSAttributeDataFileID = 13, /* Used in Mac OS X runtime for extent based attributes */
/* kHFSAttributeDataFileID is never stored on disk. */
kHFSRepairCatalogFileID = 14, /* Used when rebuilding Catalog B-tree */
kHFSBogusExtentFileID = 15, /* Used for exchanging extents in extents file */
kHFSFirstUserCatalogNodeID = 16
};
//.journal 16
//.journal_info_block 17
//\0\0\0\0HFS+ Private Data 18 (ascii name???) NO! Unicode
//.HFS+ Private Directory Data 19
//.Trashes 20
//.fseventsd 21
//
//System 23
/* HFS catalog key */
struct HFSCatalogKey {
u_int8_t keyLength; /* key length (in bytes) */
u_int8_t reserved; /* reserved (set to zero) */
u_int32_t parentID; /* parent folder ID */
u_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */
} HFS_ALIGNMENT;
typedef struct HFSCatalogKey HFSCatalogKey;
/* HFS Plus catalog key */
struct HFSPlusCatalogKey {
u_int16_t keyLength; /* key length (in bytes) */
u_int32_t parentID; /* parent folder ID */
HFSUniStr255 nodeName; /* catalog node name */
} HFS_ALIGNMENT;
typedef struct HFSPlusCatalogKey HFSPlusCatalogKey;
/* Catalog record types */
enum {
/* HFS Catalog Records */
kHFSFolderRecord = 0x0100, /* Folder record */
kHFSFileRecord = 0x0200, /* File record */
kHFSFolderThreadRecord = 0x0300, /* Folder thread record */
kHFSFileThreadRecord = 0x0400, /* File thread record */
/* HFS Plus Catalog Records */
kHFSPlusFolderRecord = 1, /* Folder record */
kHFSPlusFileRecord = 2, /* File record */
kHFSPlusFolderThreadRecord = 3, /* Folder thread record */
kHFSPlusFileThreadRecord = 4 /* File thread record */
};
/* Catalog file record flags */
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,
kHFSHasAttributesBit = 0x0002, /* object has extended attributes */
kHFSHasAttributesMask = 0x0004,
kHFSHasSecurityBit = 0x0003, /* object has security data (ACLs) */
kHFSHasSecurityMask = 0x0008,
kHFSHasFolderCountBit = 0x0004, /* only for HFSX, folder maintains a separate sub-folder count */
kHFSHasFolderCountMask = 0x0010, /* (sum of folder records and directory hard links) */
kHFSHasLinkChainBit = 0x0005, /* has hardlink chain (inode or link) */
kHFSHasLinkChainMask = 0x0020,
kHFSHasChildLinkBit = 0x0006, /* folder has a child that's a dir link */
kHFSHasChildLinkMask = 0x0040,
kHFSHasDateAddedBit = 0x0007, /* File/Folder has the date-added stored in the finder info. */
kHFSHasDateAddedMask = 0x0080
};
/* HFS catalog folder record - 70 bytes */
struct HFSCatalogFolder {
int16_t recordType; /* == kHFSFolderRecord */
u_int16_t flags; /* folder flags */
u_int16_t valence; /* folder valence */
u_int32_t folderID; /* folder ID */
u_int32_t createDate; /* date and time of creation */
u_int32_t modifyDate; /* date and time of last modification */
u_int32_t backupDate; /* date and time of last backup */
FndrDirInfo userInfo; /* Finder information */
FndrOpaqueInfo finderInfo; /* additional Finder information */
u_int32_t reserved[4]; /* reserved - initialized as zero */
} HFS_ALIGNMENT;
typedef struct HFSCatalogFolder HFSCatalogFolder;
/* HFS Plus catalog folder record - 88 bytes */
struct HFSPlusCatalogFolder {
int16_t recordType; /* == kHFSPlusFolderRecord */
u_int16_t flags; /* file flags */
u_int32_t valence; /* folder's item count */
u_int32_t folderID; /* folder ID */
u_int32_t createDate; /* date and time of creation */
u_int32_t contentModDate; /* date and time of last content modification */
u_int32_t attributeModDate; /* date and time of last attribute modification */
u_int32_t accessDate; /* date and time of last access (MacOS X only) */
u_int32_t backupDate; /* date and time of last backup */
HFSPlusBSDInfo bsdInfo; /* permissions (for MacOS X) */
FndrDirInfo userInfo; /* Finder information */
FndrOpaqueInfo finderInfo; /* additional Finder information */
u_int32_t textEncoding; /* hint for name conversions */
u_int32_t folderCount; /* number of enclosed folders, active when HasFolderCount is set */
} HFS_ALIGNMENT;
typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder;
/* HFS catalog file record - 102 bytes */
struct HFSCatalogFile {
int16_t recordType; /* == kHFSFileRecord */
u_int8_t flags; /* file flags */
int8_t fileType; /* file type (unused ?) */
FndrFileInfo userInfo; /* Finder information */
u_int32_t fileID; /* file ID */
u_int16_t dataStartBlock; /* not used - set to zero */
int32_t dataLogicalSize; /* logical EOF of data fork */
int32_t dataPhysicalSize; /* physical EOF of data fork */
u_int16_t rsrcStartBlock; /* not used - set to zero */
int32_t rsrcLogicalSize; /* logical EOF of resource fork */
int32_t rsrcPhysicalSize; /* physical EOF of resource fork */
u_int32_t createDate; /* date and time of creation */
u_int32_t modifyDate; /* date and time of last modification */
u_int32_t backupDate; /* date and time of last backup */
FndrOpaqueInfo finderInfo; /* additional Finder information */
u_int16_t clumpSize; /* file clump size (not used) */
HFSExtentRecord dataExtents; /* first data fork extent record */
HFSExtentRecord rsrcExtents; /* first resource fork extent record */
u_int32_t reserved; /* reserved - initialized as zero */
} HFS_ALIGNMENT;
typedef struct HFSCatalogFile HFSCatalogFile;
/* HFS Plus catalog file record - 248 bytes */
struct HFSPlusCatalogFile {
int16_t recordType; /* 0: kHFSPlusFileRecord == 2*/
u_int16_t flags; /* 2 file flags */
u_int32_t reserved1; /* 4 reserved - initialized as zero */
u_int32_t fileID; /* 8 file ID */
u_int32_t createDate; /* c date and time of creation */
u_int32_t contentModDate; /* 10 date and time of last content modification */
u_int32_t attributeModDate; /* 14 date and time of last attribute modification */
u_int32_t accessDate; /* 18 date and time of last access (MacOS X only) */
u_int32_t backupDate; /* 1c date and time of last backup */
HFSPlusBSDInfo bsdInfo; /* 20 permissions (for MacOS X) */
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 */
/* Note: these start on double long (64 bit) boundary */
HFSPlusForkData dataFork; /* size and block data for data fork */
HFSPlusForkData resourceFork; /* size and block data for resource fork */
} HFS_ALIGNMENT;
typedef struct HFSPlusCatalogFile HFSPlusCatalogFile;
/* HFS catalog thread record - 46 bytes */
struct HFSCatalogThread {
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_int8_t nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */
} HFS_ALIGNMENT;
typedef struct HFSCatalogThread HFSCatalogThread;
/* HFS Plus catalog thread record -- 264 bytes */
struct HFSPlusCatalogThread {
int16_t recordType; /* == kHFSPlusFolderThreadRecord or kHFSPlusFileThreadRecord */
int16_t reserved; /* reserved - initialized as zero */
u_int32_t parentID; /* parent ID for this catalog node */
HFSUniStr255 nodeName; /* name of this catalog node (variable length) */
} HFS_ALIGNMENT;
typedef struct HFSPlusCatalogThread HFSPlusCatalogThread;
#ifdef __APPLE_API_UNSTABLE
/*
These are the types of records in the attribute B-tree. The values were
chosen so that they wouldn't conflict with the catalog record types.
*/
enum {
kHFSPlusAttrInlineData = 0x10, /* attributes whose data fits in a b-tree node */
kHFSPlusAttrForkData = 0x20, /* extent based attributes (data lives in extents) */
kHFSPlusAttrExtents = 0x30 /* overflow extents for large attributes */
};
/*
HFSPlusAttrForkData
For larger attributes, whose value is stored in allocation blocks.
If the attribute has more than 8 extents, there will be additional
records (of type HFSPlusAttrExtents) for this attribute.
*/
struct HFSPlusAttrForkData {
u_int32_t recordType; /* == kHFSPlusAttrForkData*/
u_int32_t reserved;
HFSPlusForkData theFork; /* size and first extents of value*/
} HFS_ALIGNMENT;
typedef struct HFSPlusAttrForkData HFSPlusAttrForkData;
/*
HFSPlusAttrExtents
This record contains information about overflow extents for large,
fragmented attributes.
*/
struct HFSPlusAttrExtents {
u_int32_t recordType; /* == kHFSPlusAttrExtents*/
u_int32_t reserved;
HFSPlusExtentRecord extents; /* additional extents*/
} HFS_ALIGNMENT;
typedef struct HFSPlusAttrExtents HFSPlusAttrExtents;
/*
* Attributes 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 */
} HFS_ALIGNMENT;
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];
} HFS_ALIGNMENT;
typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData;
/* A generic Attribute Record*/
union HFSPlusAttrRecord {
u_int32_t recordType;
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 allocation block number for extents */
u_int16_t attrNameLen; /* number of unicode characters */
u_int16_t attrName[kHFSMaxAttrNameLen]; /* attribute name (Unicode) */
} HFS_ALIGNMENT;
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),
kHFSExtentKeyMaximumLength = sizeof(HFSExtentKey) - sizeof(u_int8_t),
kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(u_int16_t),
kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(u_int16_t),
kHFSCatalogKeyMaximumLength = sizeof(HFSCatalogKey) - sizeof(u_int8_t),
kHFSCatalogKeyMinimumLength = kHFSCatalogKeyMaximumLength - (kHFSMaxFileNameChars + 1) + sizeof(u_int8_t),
kHFSPlusCatalogMinNodeSize = 4096,
kHFSPlusExtentMinNodeSize = 512,
kHFSPlusAttrMinNodeSize = 4096
};
/* HFS and HFS Plus volume attribute bits */
enum {
/* Bits 0-6 are reserved (always cleared by MountVol call) */
kHFSVolumeHardwareLockBit = 7, /* volume is locked by hardware */
kHFSVolumeUnmountedBit = 8, /* volume was successfully unmounted */
kHFSVolumeSparedBlocksBit = 9, /* volume has bad blocks spared */
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,
kHFSVolumeJournaledBit = 13, /* this volume has a journal on it */
kHFSVolumeInconsistentBit = 14, /* serious inconsistencies detected at runtime */
kHFSVolumeSoftwareLockBit = 15, /* volume is locked by software */
/*
* HFS only has 16 bits of attributes in the MDB, but HFS Plus has 32 bits.
* Therefore, bits 16-31 can only be used on HFS Plus.
*/
kHFSUnusedNodeFixBit = 31, /* Unused nodes in the Catalog B-tree have been zero-filled. See Radar #6947811. */
kHFSContentProtectionBit = 30, /* Volume has per-file content protection */
kHFSVolumeHardwareLockMask = 1 << kHFSVolumeHardwareLockBit,
kHFSVolumeUnmountedMask = 1 << kHFSVolumeUnmountedBit,
kHFSVolumeSparedBlocksMask = 1 << kHFSVolumeSparedBlocksBit,
kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit,
kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit,
kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit,
kHFSVolumeJournaledMask = 1 << kHFSVolumeJournaledBit,
kHFSVolumeInconsistentMask = 1 << kHFSVolumeInconsistentBit,
kHFSVolumeSoftwareLockMask = 1 << kHFSVolumeSoftwareLockBit,
/* Bits 16-31 are allocated from high to low */
kHFSContentProtectionMask = 0x40000000,
kHFSUnusedNodeFixMask = 0x80000000,
kHFSMDBAttributesMask = 0x8380
};
enum {
kHFSUnusedNodesFixDate = 0xc5ef2480 /* March 25, 2009 */
};
/* HFS Master Directory Block - 162 bytes */
/* Stored at sector #2 (3rd sector) and second-to-last sector. */
struct HFSMasterDirectoryBlock {
u_int16_t drSigWord; /* == kHFSSigWord = 0x4244 = 'BD' or 'H+' or 'HX'*/
u_int32_t drCrDate; /* date and time of volume creation */
u_int32_t drLsMod; /* date and time of last modification */
u_int16_t drAtrb; /* volume attributes */
u_int16_t drNmFls; /* number of files in root folder */
u_int16_t drVBMSt; /* first block of volume bitmap */
u_int16_t drAllocPtr; /* start of next allocation search */
u_int16_t drNmAlBlks; /* number of allocation blocks in volume */
u_int32_t drAlBlkSiz; /* size (in bytes) of allocation blocks */
u_int32_t drClpSiz; /* default clump size */
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_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 */
u_int32_t drXTClpSiz; /* clump size for extents overflow file */
u_int32_t drCTClpSiz; /* clump size for catalog file */
u_int16_t drNmRtDirs; /* number of directories in root folder */
u_int32_t drFilCnt; /* number of files in volume */
u_int32_t drDirCnt; /* number of directories in volume */
u_int32_t drFndrInfo[8]; /* information used by the Finder */
u_int16_t drEmbedSigWord; /* embedded volume signature (formerly drVCSize) */
HFSExtentDescriptor drEmbedExtent; /* embedded volume location and size (formerly drVBMCSize and drCtlCSize) */
u_int32_t drXTFlSize; /* size of extents overflow file */
HFSExtentRecord drXTExtRec; /* extent record for extents overflow file */
u_int32_t drCTFlSize; /* size of catalog file */
HFSExtentRecord drCTExtRec; /* extent record for catalog file */
} HFS_ALIGNMENT;
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 */
/*
48 2B 00 04 80 00 20 00 48 46 53 4A 00 AD 7E 98 //H+ HFSJ
C9 12 D3 9E CB 84 F3 1D 00 00 00 00 C9 26 31 A8
00 12 1D 9D 00 03 66 B9 00 00 10 00 01 A1 2C CF
00 44 67 DF 01 35 EB A8 00 01 00 00 00 01 00 00
10 8B 1C EA 08 E4 9C 1B 00 00 00 00 02 00 00 8B
00 00 02 E7 10 3F CB 93 00 00 00 00 00 00 00 00
00 00 00 00 00 00 02 E7 6A 45 F3 37 EF 97 E9 A6
00 00 00 00 00 34 30 00 00 00 00 00 00 00 03 43
00 00 00 01 00 00 03 43 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 70 00 00 00 70 00 00 00 00 07 00
00 00 13 45 00 00 07 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 2A F8 00 00 01 90 00 00 00 02 AF 80
00 01 AA 55 00 01 90 00 00 14 5A C7 00 00 19 00
00 3D E4 E3 00 00 19 00 00 95 44 F7 00 00 19 00
00 9D 3B 18 00 00 32 00 00 E3 58 1C 00 00 19 00
00 48 1C 72 00 00 19 00 00 BB 6A 05 00 00 19 00
00 00 00 00 06 40 00 00 01 90 00 00 00 00 64 00
00 06 80 00 00 00 19 00 00 38 2A 2F 00 00 19 00
00 38 DB 2C 00 00 19 00 00 A6 A2 1F 00 00 19 00
*/
/* HFS Plus Volume Header - 512 bytes */
/* Stored at sector #2 (3rd sector) and second-to-last sector. */
struct HFSPlusVolumeHeader {
u_int16_t signature; /* == kHFSPlusSigWord */
u_int16_t version; /* == kHFSPlusVersion */
u_int32_t attributes; /* volume attributes */
u_int32_t lastMountedVersion; /* implementation version which last mounted volume */
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_int32_t backupDate; /* date and time of last backup */
u_int32_t checkedDate; /* date and time of last disk check */
u_int32_t fileCount; /* number of files in volume */
u_int32_t folderCount; /* number of directories in volume */
u_int32_t blockSize; /* size (in bytes) of allocation blocks */
u_int32_t totalBlocks; /* number of allocation blocks in volume (includes this header and VBM*/
u_int32_t freeBlocks; /* number of unused allocation blocks */
u_int32_t nextAllocation; /* start of next allocation search */
u_int32_t rsrcClumpSize; /* default resource fork clump size */
u_int32_t dataClumpSize; /* default data fork clump size */
u_int32_t nextCatalogID; /* next unused catalog node ID */
u_int32_t writeCount; /* volume write count */
u_int64_t encodingsBitmap; /* which encodings have been use on this volume */
u_int8_t finderInfo[32]; /* information used by the Finder */
HFSPlusForkData allocationFile; /* allocation bitmap file */
HFSPlusForkData extentsFile; /* extents B-tree file */
HFSPlusForkData catalogFile; /* catalog B-tree file */
HFSPlusForkData attributesFile; /* extended attributes B-tree file */
HFSPlusForkData startupFile; /* boot file (secondary loader) */
} HFS_ALIGNMENT;
typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader;
/* B-tree structures */
enum BTreeKeyLimits{
kMaxKeyLength = 520
};
union BTreeKey{
u_int8_t length8;
u_int16_t length16;
u_int8_t rawData[kMaxKeyLength + 2];
};
typedef union BTreeKey BTreeKey;
/* BTNodeDescriptor -- Every B-tree node starts with these fields. */
struct BTNodeDescriptor {
u_int32_t fLink; /* next node at this level*/
u_int32_t bLink; /* previous node at this level*/
int8_t kind; /* kind of node (leaf, index, header, map)*/
u_int8_t height; /* zero for header, map; child is one more than parent*/
u_int16_t numRecords; /* number of records in this node*/
u_int16_t reserved; /* reserved - initialized as zero */
} HFS_ALIGNMENT;
typedef struct BTNodeDescriptor BTNodeDescriptor;
/* Constants for BTNodeDescriptor kind */
enum {
kBTLeafNode = -1,
kBTIndexNode = 0,
kBTHeaderNode = 1,
kBTMapNode = 2
};
/* BTHeaderRec -- The first record of a B-tree header node */
struct BTHeaderRec {
u_int16_t treeDepth; /* maximum height (usually leaf nodes) */
u_int32_t rootNode; /* node number of root node */
u_int32_t leafRecords; /* number of leaf records in all leaf nodes */
u_int32_t firstLeafNode; /* node number of first leaf node */
u_int32_t lastLeafNode; /* node number of last leaf node */
u_int16_t nodeSize; /* size of a node, in bytes */
u_int16_t maxKeyLength; /* reserved */
u_int32_t totalNodes; /* total number of nodes in tree */
u_int32_t freeNodes; /* number of unused (free) nodes in tree */
u_int16_t reserved1; /* unused */
u_int32_t clumpSize; /* reserved HFSPlusForkData->clumpSize */
u_int8_t btreeType; /* enum from BTreeTypes */
u_int8_t keyCompareType; /* Key string Comparison Type */
u_int32_t attributes; /* persistent attributes about the tree */
u_int32_t reserved3[16]; /* reserved */
} HFS_ALIGNMENT;
typedef struct BTHeaderRec BTHeaderRec;
enum BTreeTypes{
kHFSBTreeType = 0, // control file
kUserBTreeType = 128, // user btree type starts from 128
kReservedBTreeType = 255
};
/* Constants for BTHeaderRec attributes */
enum {
kBTBadCloseMask = 0x00000001, /* reserved */
kBTBigKeysMask = 0x00000002, /* key length field is 16 bits */
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 */
// the original size of the reserved field in the JournalInfoBlock was
// 32*sizeof(u_int32_t). To keep the total size of the structure the
// same we subtract the size of new fields (currently: ext_jnl_uuid and
// machine_uuid). If you add additional fields, place them before the
// reserved field and subtract their size in this macro.
//
typedef EFI_GUID uuid_string_t;
#define JIB_RESERVED_SIZE ((32*sizeof(u_int32_t)) - sizeof(uuid_string_t) - 48)
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
uuid_string_t ext_jnl_uuid;
char machine_serial_num[48];
char reserved[JIB_RESERVED_SIZE];
} HFS_ALIGNMENT;
typedef struct JournalInfoBlock JournalInfoBlock;
enum {
kJIJournalInFSMask = 0x00000001,
kJIJournalOnOtherDeviceMask = 0x00000002,
kJIJournalNeedInitMask = 0x00000004
};
//
// This the content type uuid for "external journal" GPT
// partitions. Each instance of a partition also has a
// uuid that uniquely identifies that instance.
//
#define EXTJNL_CONTENT_TYPE_UUID "4A6F7572-6E61-11AA-AA11-00306543ECAC"
#define HFC_MAGIC 0xFF28FF26
#define HFC_VERSION 1
#define HFC_DEFAULT_DURATION (3600 * 60)
#define HFC_MINIMUM_TEMPERATURE 16
#define HFC_MAXIMUM_FILESIZE (10 * 1024 * 1024)
char hfc_tag[] = "CLUSTERED HOT FILES B-TREE ";
struct HotFilesInfo {
u_int32_t magic;
u_int32_t version;
u_int32_t duration; /* duration of sample period */
u_int32_t timebase; /* recording period start time */
u_int32_t timeleft; /* recording period stop time */
u_int32_t threshold;
u_int32_t maxfileblks;
u_int32_t maxfilecnt;
u_int8_t tag[32];
};
typedef struct HotFilesInfo HotFilesInfo;
struct HotFileKey {
u_int16_t keyLength;
u_int8_t forkType;
u_int8_t pad;
u_int32_t temperature;
u_int32_t fileID;
};
typedef struct HotFileKey HotFileKey;
#define HFC_LOOKUPTAG 0xFFFFFFFF
#define HFC_KEYLENGTH (sizeof(HotFileKey) - sizeof(u_int32_t))
#ifdef __cplusplus
}
#endif
#ifdef _MSC_VER
# pragma pack(pop)
#endif
#endif /* __HFS_FORMAT__ */