gpt.hpp
00001 #if !defined(__GPT_HPP__)
00002 #define __GPT_HPP__
00003
00004
00005
00006
00007 #include "efi.hpp"
00008
00012 struct gpt : public efi
00013 {
00014 static const uint64_t SIGNATURE = 0x5452415020494645ull;
00015 static const uint32_t REVISION = 0x00010000ul;
00016 static const uint16_t HEADER_SIZE = 128;
00017
00021 struct __packed(header_fields)
00022 {
00023 le_uint64_t signature;
00024 le_uint32_t revision;
00025 le_uint32_t header_size;
00026 le_uint32_t header_crc32;
00027 le_uint32_t reserved0;
00028 le_uint64_t header_lba;
00029 le_uint64_t alternate_header_lba;
00030 le_uint64_t first_usable_lba;
00031 le_uint64_t last_usable_lba;
00032 guid_t disk_guid;
00033 le_uint64_t entries_lba;
00034 le_uint32_t entries_number;
00035 le_uint32_t entries_size;
00036 le_uint32_t entries_crc32;
00037 };
00038
00042 struct __packed(header) : public header_fields
00043 {
00045 uint8_t fill5c[HEADER_SIZE - sizeof(header_fields)];
00046
00050 inline header(void)
00051 {
00052 memset(this, 0, sizeof(header));
00053 }
00054
00058 header(const guid_t disk_guid, uint64_t header_lba, uint64_t alternate_header_lba,
00059 uint64_t first_usable_lba, uint64_t last_usable_lba,
00060 uint64_t entries_lba, uint32_t entries_number, uint32_t entries_crc32);
00061
00062 inline bool is_valid(void) const
00063 {
00064 return (signature == SIGNATURE) && (revision == REVISION);
00065 }
00066 };
00067
00068
00069 static_assert(sizeof(header) == HEADER_SIZE, "wrong header size");
00070
00071 static_assert(sizeof(header) <= 512, "header size must be smaller than or equal to a sector");
00072 static_assert((512 % sizeof(header)) == 0, "wrong header size");
00073
00077 struct __packed(entry)
00078 {
00079 guid_t type_guid;
00080 guid_t partition_guid;
00081 le_uint64_t start_lba;
00082 le_uint64_t end_lba;
00083 le_uint64_t attributes;
00084
00085 uchar_t name[72 / sizeof(uchar_t)];
00086
00090 inline entry(void)
00091 {
00092 memset(this, 0, sizeof(entry));
00093 }
00094
00098 entry(const guid_t type_guid, const guid_t partition_guid, uint64_t start_lba,
00099 uint64_t end_lba, uint64_t attributes=0, const uchar_t *name=nullptr);
00100
00101 inline bool is_used(void) const
00102 {
00103 return !is_null_guid(type_guid);
00104 }
00105
00106 inline bool is_valid(const uint64_t first_lba, const uint64_t last_lba) const
00107 {
00108
00109 return (start_lba >= first_lba) && (start_lba <= last_lba) &&
00110 (end_lba >= first_lba) && (end_lba <= last_lba) && (start_lba <= end_lba);
00111 }
00112
00113 inline bool overlaps(const entry &other) const
00114 {
00115 return (start_lba <= other.end_lba) && (other.start_lba <= end_lba);
00116 }
00117 };
00118
00119
00120 static_assert((512 % sizeof(entry)) == 0, "wrong entry size");
00121 };
00122
00123 #endif
00124
00125
00126