#pragma once #include <stdint.h> #include "utils/uid.h" // GNU GRUB "Hah!IdontNeedEFI" #define EFI_SIG 0x5452415020494645 // "EFI PART" #define EFI_SIG_LOW 0x20494645 #define EFI_SIG_HIGH 0x54524150 #define EFI_PART_NAME_LENGTH 36 // // GPT flags // // Sections // * EFI flags // * Google flags // * Microsoft flags // // Bits Description // 2:0 EFI/General flags // 47:3 Reserved // 63:48 OS specifics (Google, Microsoft) // /** * The computing platform requires this partition to function properly. */ static const uint64_t GPT_FLAG_PLATFORM_REQUIRED = 1; /** * The EFI firmware should ignore this partition and its data, and avoid * reading from it. */ static const uint64_t GPT_FLAG_EFI_FIRMWARE_IGNORE = 2; /** * Indicates that a legacy BIOS may boot from this partition. */ static const uint64_t GPT_FLAG_LEGACY_BIOS_BOOTABLE = 4; // // Google flags // /** * Google flag for ChromeOS (bit 56) * * Likely set when the OS booted successfully from the partition. */ static const uint64_t GPT_FLAG_SUCCESSFUL_BOOT = 0x100000000000000; /** * Google flag mask for ChromeOS (bits 55:52) * * Likely the number of tries remaining to boot from the partition. */ static const uint64_t GPT_FLAG_TRIES_REMAINING_MASK = 0xF0000000000000; static const uint64_t GPT_FLAG_TRIES_REMAINING_SHIFT = 52; /** * Google flag mask for ChromeOS (bits 51:48) * * Likely denotes a priority, 15 being the high, 1 lowest, and 0 not bootable. */ static const uint64_t GPT_FLAG_PRIORITY_MASK = 0xF000000000000; static const uint64_t GPT_FLAG_PRIORITY_SHIFT = 48; // // Microsoft flags // // Source: https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-partition_information_gpt // /** * Microsoft flag: GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY (bit 60) * * If this attribute is set, the partition is read-only. * * Writes to the partition will fail. IOCTL_DISK_IS_WRITABLE will fail with the * ERROR_WRITE_PROTECT Win32 error code, which causes the file system to mount * as read only, if a file system is present. * * VSS uses this attribute. * * Do not set this attribute for dynamic disks. Setting it can cause I/O errors * and prevent the file system from mounting properly. */ static const uint64_t GPT_FLAG_READ_ONLY = 0x1000000000000000; /** * Microsoft flag: GPT_BASIC_DATA_ATTRIBUTE_SHADOW_COPY (bit 61) * * If this attribute is set, the partition is a shadow copy of another partition. * * VSS uses this attribute. This attribute is an indication for file system * filter driver-based software (such as antivirus programs) to avoid * attaching to the volume. * * An application can use the attribute to differentiate a shadow copy volume * from a production volume. An application that does a fast recovery, for * example, will break a shadow copy LUN and clear the read-only and hidden * attributes and this attribute. This attribute is set when the shadow copy is * created and cleared when the shadow copy is broken. * * Despite its name, this attribute can be set for basic and dynamic disks. * * Windows Server 2003: This attribute is not supported before Windows Server * 2003 with SP1. */ static const uint64_t GPT_FLAG_SHADOW_COPY = 0x2000000000000000; /** * Microsoft flag: GPT_BASIC_DATA_ATTRIBUTE_HIDDEN (bit 62) * * If this attribute is set, the partition is not detected by the Mount Manager. * * As a result, the partition does not receive a drive letter, does not receive * a volume GUID path, does not host mounted folders (also called volume mount * points), and is not enumerated by calls to FindFirstVolume and * FindNextVolume. This ensures that applications such as Disk Defragmenter do * not access the partition. The Volume Shadow Copy Service (VSS) uses this * attribute. * * Despite its name, this attribute can be set for basic and dynamic disks. */ static const uint64_t GPT_FLAG_HIDDEN = 0x4000000000000000; /** * Microsoft flag: GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER (bit 63) * * If this attribute is set, the partition does not receive a drive letter by * default when the disk is moved to another computer or when the disk is seen * for the first time by a computer. */ static const uint64_t GPT_FLAG_NO_DRIVE_LETTER = 0x8000000000000000; // // Structures // typedef struct LBA64 { union { uint64_t lba; struct { uint32_t lowlba, highlba; }; }; } LBA64; // Protective MBRs have type of EEH, and the header is usually found at LBA 1 typedef struct { // v1.0 union { uint64_t sig; // "EFI PART" struct { uint32_t siglow, sighigh; }; }; uint16_t minorver; uint16_t majorver; uint32_t headersize; // usually 92 bytes (v1.0) uint32_t headercrc32; uint32_t reserved; // reserved LBA64 current; LBA64 backup; // Backup LBA index LBA64 first; // First LBA index LBA64 last; // Last LBA index UID guid; // Unique disk GUID LBA64 pt_location; // (partition table) location uint32_t pt_entries; // (partition table) maximum number of entries uint32_t pt_esize; // (partition entry) structure size uint32_t pt_crc32; // (partition table) CRC32 uint8_t pad[420]; } GPT; // GPT entry structure typedef struct { UID type; // Partition type GUID UID part; // Unique partition GUID LBA64 first; LBA64 last; uint64_t flags; uint16_t partname[36]; // 72 bytes, 36 UTF-16LE characters uint8_t pad[384]; } GPT_ENTRY; const char* gpt_part_type_str(UID *uid);