350 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** @file
Copyright (C) 2020, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APFS_H
#define APFS_H
//
// APFS object types.
//
#define APFS_OBJECT_TYPE_NX_SUPERBLOCK 0x00000001U
#define APFS_OBJECT_TYPE_BTREE 0x00000002U
#define APFS_OBJECT_TYPE_BTREE_NODE 0x00000003U
#define APFS_OBJECT_TYPE_SPACEMAN 0x00000005U
#define APFS_OBJECT_TYPE_SPACEMAN_CAB 0x00000006U
#define APFS_OBJECT_TYPE_SPACEMAN_CIB 0x00000007U
#define APFS_OBJECT_TYPE_SPACEMAN_BITMAP 0x00000008U
#define APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x00000009U
#define APFS_OBJECT_TYPE_EXTENT_LIST_TREE 0x0000000aU
#define APFS_OBJECT_TYPE_OMAP 0x0000000bU
#define APFS_OBJECT_TYPE_CHECKPOINT_MAP 0x0000000cU
#define APFS_OBJECT_TYPE_FS 0x0000000dU
#define APFS_OBJECT_TYPE_FSTREE 0x0000000eU
#define APFS_OBJECT_TYPE_BLOCKREFTREE 0x0000000fU
#define APFS_OBJECT_TYPE_SNAPMETATREE 0x00000010U
#define APFS_OBJECT_TYPE_NX_REAPER 0x00000011U
#define APFS_OBJECT_TYPE_NX_REAP_LIST 0x00000012U
#define APFS_OBJECT_TYPE_OMAP_SNAPSHOT 0x00000013U
#define APFS_OBJECT_TYPE_EFI_JUMPSTART 0x00000014U
#define APFS_OBJECT_TYPE_FUSION_MIDDLE_TREE 0x00000015U
#define APFS_OBJECT_TYPE_NX_FUSION_WBC 0x00000016U
#define APFS_OBJECT_TYPE_NX_FUSION_WBC_LIST 0x00000017U
#define APFS_OBJECT_TYPE_ER_STATE 0x00000018U
#define APFS_OBJECT_TYPE_GBITMAP 0x00000019U
#define APFS_OBJECT_TYPE_GBITMAP_TREE 0x0000001aU
#define APFS_OBJECT_TYPE_GBITMAP_BLOCK 0x0000001bU
#define APFS_OBJECT_TYPE_INVALID 0x00000000U
#define APFS_OBJECT_TYPE_TEST 0x000000ffU
//
// APFS object flags.
//
#define APFS_OBJ_VIRTUAL 0x00000000U
#define APFS_OBJ_EPHEMERAL 0x80000000U
#define APFS_OBJ_PHYSICAL 0x40000000U
#define APFS_OBJ_NOHEADER 0x20000000U
#define APFS_OBJ_ENCRYPTED 0x10000000U
#define APFS_OBJ_NONPERSISTENT 0x08000000U
//
// Container Superblock definitions
//
#define APFS_NX_SIGNATURE SIGNATURE_32 ('N', 'X', 'S', 'B')
#define APFS_NX_MAX_FILE_SYSTEMS 100
#define APFS_NX_EPH_INFO_COUNT 4
#define APFS_NX_EPH_MIN_BLOCK_COUNT 8
#define APFS_NX_MAX_FILE_SYSTEM_EPH_STRUCTS 4
#define APFS_NX_TX_MIN_CHECKPOINT_COUNT 4
#define APFS_NX_EPH_INFO_VERSION_1 1
#define APFS_NX_NUM_COUNTERS 32
#define APFS_NX_MINIMUM_BLOCK_SIZE BASE_4KB
#define APFS_NX_DEFAULT_BLOCK_SIZE BASE_4KB
#define APFS_NX_MAXIMUM_BLOCK_SIZE BASE_64KB
//
// EfiBootRecord block definitions
//
#define APFS_NX_EFI_JUMPSTART_MAGIC SIGNATURE_32 ('J', 'S', 'D', 'R')
#define APFS_NX_EFI_JUMPSTART_VERSION 1
#define APFS_MAX_HIST 8
#define APFS_MODIFIED_NAMELEN 32
#define APFS_VOLNAME_LEN 256
//
// Fusion things
//
#define APFS_FUSION_TIER2_DEVICE_BYTE_ADDR 0x4000000000000000ULL
//
// Driver version
//
#define APFS_DRIVER_VERSION_MAGIC SIGNATURE_32 ('A', 'P', 'F', 'S')
#pragma pack(push, 1)
/**
APFS driver version structure.
**/
typedef struct APFS_DRIVER_VERSION_ {
///
/// Matches APFS_DRIVER_VERSION_MAGIC.
///
UINT32 Magic;
///
/// Matches MajorImageVersion << 16 | MinorImageVersion.
///
UINT32 ImageVersion;
///
/// Actual driver version.
///
UINT64 Version;
///
/// In ISO format (YYYY/MM/DD), e.g. 2020/03/06.
///
CHAR8 Date[16];
///
/// In ISO format (HH:MM:SS), e.g. 23:26:03.
///
CHAR8 Time[16];
} APFS_DRIVER_VERSION;
/**
A range of physical addresses.
**/
typedef struct PhysicalRange_ {
INT64 StartPhysicalAddr;
UINT64 BlockCount;
} APFS_PHYSICAL_RANGE;
/**
Information about how the volume encryption key (VEK)
is used to encrypt a file.
**/
typedef struct {
UINT16 MajorVersion;
UINT16 MinorVersion;
UINT32 CpFlags;
UINT32 PersistentClass;
UINT32 KeyOsVersion;
UINT16 KeyRevision;
UINT16 KeyLength;
} APFS_WRAPPED_CRYPTO_STATE;
/**
Information about a program that modified the volume.
**/
typedef struct {
UINT8 Id[APFS_MODIFIED_NAMELEN];
UINT64 Timestamp;
UINT64 LastXid;
} APFS_MODIFIED_BY;
/**
Any object is prefixed with this header.
**/
typedef struct APFS_OBJ_PHYS_ {
//
// The Fletcher 64 checksum of the object.
//
UINT64 Checksum;
//
// The object's identifier.
// NXSB=01 00.
// APSB=02 04, 06 04, and 08 04.
//
UINT64 ObjectOid;
//
// The identifier of the most recent transaction that this object
// was modified in.
//
UINT64 ObjectXid;
//
// The object's type and flags.
//
UINT32 ObjectType;
//
// The object's subtype.
// Subtypes indicate the type of data stored in a data structure such as a
// B-tree. For example, a node in a B-tree that contains volume records has
// a type of OBJECT_TYPE_BTREE_NODE and a subtype of OBJECT_TYPE_FS.
//
UINT32 ObjectSubType;
} APFS_OBJ_PHYS;
/**
NXSB Container Superblock
The container superblock is the entry point to the filesystem.
Because of the structure with containers and flexible volumes,
allocation needs to handled on a container level.
The container superblock contains information on the blocksize,
the number of blocks and pointers to the spacemanager for this task.
Additionally the block IDs of all volumes are stored in the superblock.
To map block IDs to block offsets a pointer to a block map b-tree is stored.
This b-tree contains entries for each volume with its ID and offset.
**/
typedef struct APFS_NX_SUPERBLOCK_ {
APFS_OBJ_PHYS BlockHeader;
//
// Magic: NXSB
//
UINT32 Magic;
//
// The logical block size used in the Apple File System container.
// This size is often the same as the block size used by the underlying
// storage device, but it can also be an integer multiple of the deviceʼs block size.
//
UINT32 BlockSize;
//
// Number of blocks in the container
//
UINT64 TotalBlocks;
UINT64 Features;
UINT64 ReadOnlyCompatibleFeatures;
UINT64 IncompatibleFeatures;
EFI_GUID Uuid;
UINT64 NextOid;
UINT64 NextXid;
UINT32 XpDescBlocks;
UINT32 XpDataBlocks;
INT64 XpDescBase;
INT64 XpDataBase;
UINT32 XpDescNext;
UINT32 XpDataNext;
UINT32 XpDescIndex;
UINT32 XpDescLen;
UINT32 XpDataIndex;
UINT32 XpDataLen;
UINT64 SpacemanOid;
UINT64 ObjectMapOid;
UINT64 ReaperOid;
UINT32 TestType;
UINT32 MaxFileSystems;
UINT64 FileSystemOid[APFS_NX_MAX_FILE_SYSTEMS];
UINT64 Counters[APFS_NX_NUM_COUNTERS];
APFS_PHYSICAL_RANGE BlockedOutPhysicalRange;
UINT64 EvictMappingTreeOid;
UINT64 Flags;
//
// Pointer to JSDR block
//
UINT64 EfiJumpStart;
EFI_GUID FusionUuid;
APFS_PHYSICAL_RANGE KeyLocker;
UINT64 EphermalInfo[APFS_NX_EPH_INFO_COUNT];
UINT64 TestOid;
UINT64 FusionMtIod;
UINT64 FusionWbcOid;
APFS_PHYSICAL_RANGE FusionWbc;
} APFS_NX_SUPERBLOCK;
STATIC_ASSERT (sizeof (APFS_NX_SUPERBLOCK) == 1384, "APFS_NX_SUPERBLOCK has unexpected size");
/**
APSB volume header structure
**/
typedef struct APFS_APFS_SUPERBLOCK_ {
APFS_OBJ_PHYS BlockHeader;
//
// Volume Superblock magic
// Magic: APSB
//
UINT32 Magic;
//
// Volume#. First volume start with 0, (0x00)
//
UINT32 FsIndex;
UINT64 Features;
UINT64 ReadOnlyCompatibleFeatures;
UINT64 IncompatibleFeatures;
UINT64 UnmountTime;
//
// Size of volume in blocks. Last volume has no
// size set and has available the rest of the blocks
//
UINT64 FsReserveBlockCount;
UINT64 FsQuotaBlockCount;
//
// Blocks in use in this volume.
//
UINT64 FsAllocCount;
APFS_WRAPPED_CRYPTO_STATE MetaCrypto;
UINT32 RootTreeType;
UINT32 ExtentrefTreeType;
UINT32 SnapMetaTreeType;
UINT64 OmapOid;
UINT64 RootTreeId;
UINT64 ExtentrefTreeOid;
UINT64 SnapMetaTreeOid;
UINT64 RevertToXid;
UINT64 RevertToSblockOid;
UINT64 NextObjId;
UINT64 NumFiles;
UINT64 NumDirectories;
UINT64 NumSymlinks;
UINT64 NumOtherFsObjects;
UINT64 NumSnapshots;
UINT64 TotalBlocksAllocated;
UINT64 TotalBlocksFreed;
GUID VolumeUuid;
UINT64 LastModTime;
UINT64 FsFlags;
APFS_MODIFIED_BY FormattedBy;
APFS_MODIFIED_BY ModifiedBy[APFS_MAX_HIST];
UINT8 VolumeName[APFS_VOLNAME_LEN];
UINT32 NextDocId;
UINT16 Role;
UINT16 Reserved;
UINT64 RootToXid;
UINT64 ErStateOid;
} APFS_APFS_SUPERBLOCK;
/**
JSDR block structure
**/
typedef struct APFS_NX_EFI_JUMPSTART_ {
APFS_OBJ_PHYS BlockHeader;
//
// A number that can be used to verify that you're reading an instance of
// APFS_EFI_BOOT_RECORD
//
UINT32 Magic;
//
// The version of this data structure
//
UINT32 Version;
//
// The length in bytes, of the embedded EFI driver
//
UINT32 EfiFileLen;
//
// Num of extents in the array
//
UINT32 NumExtents;
//
// Reserved
// Populate this field with 0 when you create a new instance,
// and preserve its value when you modify an existing instance.
//
UINT64 Reserved[16];
//
// Apfs driver physical range location
//
APFS_PHYSICAL_RANGE RecordExtents[];
} APFS_NX_EFI_JUMPSTART;
#pragma pack(pop)
#endif // APFS_H