/** @file APFS Driver Loader - loads apfs.efi from EfiBootRecord block Copyright (c) 2017-2018, savvas 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_DRIVER_LOADER_H_ #define APFS_DRIVER_LOADER_H_ #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #define APFS_DRIVER_INFO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('A', 'F', 'J', 'S') // // Container Superblock definitions // #define APFS_CSB_SIGNATURE SIGNATURE_32 ('N', 'X', 'S', 'B') #define APFS_CSB_MAX_FILE_SYSTEMS 100 #define APFS_CSB_EPH_INFO_COUNT 4 #define APFS_CSB_EPH_MIN_BLOCK_COUNT 8 #define APFS_CSB_MAX_FILE_SYSTEM_EPH_STRUCTS 4 #define APFS_CSB_TX_MIN_CHECKPOINT_COUNT 4 #define APFS_CSB_EPH_INFO_VERSION_1 1 #define APFS_CSB_NUM_COUNTERS 32 // // Volume Superblock definitions // #define APFS_VSB_SIGNATURE SIGNATURE_32 ('A', 'P', 'S', 'B') #define APFS_VSB_MAX_HIST 8 #define APFS_VSB_VOLNAME_LEN 256 #define APFS_VSB_MODIFIED_NAMELEN 32 // // EfiBootRecord block definitions // #define APFS_EFIBOOTRECORD_SIGNATURE SIGNATURE_32 ('J', 'S', 'D', 'R') #define APFS_EFIBOOTRECORD_VERSION 1 typedef struct PhysicalRange_ { INT64 StartPhysicalAddr; UINT64 BlockCount; } PhysicalRange; typedef struct UNKNOWNFIELD_ { UINT32 Unknown1; EFI_HANDLE Handle; EFI_HANDLE AgentHandle; UINT8 Unknown2[88]; UINT64 Unknown3; } UNKNOWNFIELD; // // Private ApfsJumpStart structure // typedef struct _APFS_DRIVER_INFO_PRIVATE_DATA { UINT32 Magic; EFI_HANDLE ControllerHandle; EFI_HANDLE DriverBindingHandle; APFS_EFIBOOTRECORD_LOCATION_INFO EfiBootRecordLocationInfo; UINT8 Unknown1[24]; EFI_EVENT NotifyEvent; VOID *ApfsDriverPtr; UINT32 ApfsDriverSize; UINT32 ContainerBlockSize; UINT64 ContainerTotalBlocks; UINT8 Unknown2[4]; UINT32 Unknown3; EFI_BLOCK_IO_PROTOCOL *BlockIoInterface; UNKNOWNFIELD *Unknown4; UINT64 UnknownAddress; } APFS_DRIVER_INFO_PRIVATE_DATA; #define APFS_EFIBOOTRECORD_INFO_PRIVATE_DATA_FROM_THIS(a) \ CR(a, APFS_DRIVER_INFO_PRIVATE_DATA, EfiBootRecordLocationInfo, APFS_DRIVER_INFO_PRIVATE_DATA_SIGNATURE) #pragma pack(push, 1) typedef struct APFS_BLOCK_HEADER_ { // // Fletcher checksum, 64-bit. All metadata blocks // UINT64 Checksum; // // The object's identifier // Probably plays a role in the Btree structure NXSB=01 00 // APSB=02 04, 06 04 and 08 04 // nid // UINT64 ObjectOid; // // The identifier of the most recent transaction that this object // was modified in. // UINT64 ObjectXid; // // The objectʼs type and flags. // #define OBJ_VIRTUAL 0x00000000 // #define OBJ_EPHEMERAL 0x80000000 // #define OBJ_PHYSICAL 0x40000000 // #define OBJ_NOHEADER 0x20000000 // #define OBJ_ENCRYPTED 0x10000000 // #define OBJ_NONPERSISTENT 0x08000000 // 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_BLOCK_HEADER; #pragma pack(pop) /** 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. **/ #pragma pack(push, 1) typedef struct APFS_CSB_ { APFS_BLOCK_HEADER BlockHeader; // // Magic: NXSB // UINT32 Magic; // // Size of each allocation unit: 4096 bytes // (by default) // 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_CSB_MAX_FILE_SYSTEMS]; UINT64 Counters[APFS_CSB_NUM_COUNTERS]; PhysicalRange BlockedOutPhysicalRange; UINT64 EvictMappingTreeOid; UINT64 Flags; // // Pointer to JSDR block (EfiBootRecordBlock) // INT64 EfiBootRecordBlock; EFI_GUID FusionUuid; PhysicalRange KeyLocker; UINT64 EphermalInfo[APFS_CSB_EPH_INFO_COUNT]; UINT64 TestOid; UINT64 FusionMtIod; UINT64 FusionWbcOid; PhysicalRange FusionWbc; } APFS_CSB; #pragma pack(pop) #pragma pack(push, 1) typedef struct APFS_WRAPPED_META_CRYPTO_STATE_ { UINT16 MajorVersion; UINT16 MinorVersion; UINT32 Cpflags; UINT32 PersistentClass; UINT32 KeyOsVersion; UINT16 KeyRevision; UINT16 Unused; } /* __attribute__((aligned(2))) */ APFS_WRAPPED_META_CRYPTO_STATE; #pragma pack(pop) #pragma pack(push, 1) typedef struct APFS_MODIFIED_BY_ { UINT8 Id[APFS_VSB_MODIFIED_NAMELEN]; UINT64 Timestamp; UINT64 LastXid; } APFS_MODIFIED_BY; #pragma pack(pop) // // APSB volume header structure // #pragma pack(push, 1) typedef struct APFS_APSB_ { APFS_BLOCK_HEADER BlockHeader; // // Volume Superblock magic // Magic: APSB // UINT32 Magic; // // Volume#. First volume start with 0, (0x00) // UINT32 VolumeNumber; UINT64 Features; UINT64 ReadonlyCompatibleFeatures; // // #define APFS_INCOMPAT_CASE_INSENSITIVE 0x00000001LL // #define APFS_INCOMPAT_DATALESS_SNAPS 0x00000002LL // #define APFS_INCOMPAT_ENC_ROLLED 0x00000004LL // #define APFS_INCOMPAT_NORMALIZATION_INSENSITIVE 0x00000008LL // UINT64 IncompatibleFeatures; UINT64 UnmountTime; UINT64 ReserveBlockCount; UINT64 QuotaBlockCount; UINT64 AllocCount; APFS_WRAPPED_META_CRYPTO_STATE MetaCrypto; UINT32 RootTreeType; UINT32 ExtentrefTreeType; UINT32 SnapMetaTreeType; UINT64 OmapOid; UINT64 RootTreeOid; UINT64 ExtentrefTreeOid; UINT64 SnapMetaTreeOid; UINT64 RevertToXid; UINT64 RevertToSblockOid; // // Next CNID // UINT64 NextObjId; // // Number of files on the volume // UINT64 NumberOfFiles; // // Number of folders on the volume // UINT64 NumberOfDirectories; UINT64 NumberOfSymLinks; UINT64 NumberOfOtherFsobjects; UINT64 NumberOfSnapshots; UINT64 TotalBlocksAlloced; UINT64 TotalBlocksFreed; // // Volume UUID // EFI_GUID VolumeUuid; // // Time Volume last written/modified // UINT64 LastModTime; UINT64 FsFlags; // // Creator/APFS-version // Ex. (hfs_convert (apfs- 687.0.0.1.7)) // APFS_MODIFIED_BY FormattedBy; APFS_MODIFIED_BY ModifiedBy[APFS_VSB_MAX_HIST]; UINT8 VolName[APFS_VSB_VOLNAME_LEN]; UINT32 NextDocId; UINT16 Role; UINT16 Reserved; UINT64 RootToXid; UINT64 ErStateOid; // } APFS_APSB; #pragma pack(pop) // // JSDR block structure // #pragma pack(push, 1) typedef struct APFS_EFI_BOOT_RECORD_ { APFS_BLOCK_HEADER 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 NumOfExtents; // // 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 // PhysicalRange RecordExtents[]; } APFS_EFI_BOOT_RECORD; #pragma pack(pop) #endif // APFS_DRIVER_LOADER_H_