-// TODO: Add more tests, like a CRC check.
-// Returns TRUE if the GPT header data appear valid, FALSE otherwise.
-static BOOLEAN GptHeaderValid(GPT_HEADER *Header) {
- BOOLEAN IsValid = TRUE;
-
- if ((Header->signature != 0x5452415020494645ULL) || (Header->entry_count > 2048))
- IsValid = FALSE;
+// TODO: Make this work on big-endian systems; at the moment, it contains
+// little-endian assumptions!
+// Returns TRUE if the GPT protective MBR and header data appear valid,
+// FALSE otherwise.
+static BOOLEAN GptHeaderValid(GPT_DATA *GptData) {
+ BOOLEAN IsValid;
+ UINT32 CrcValue, StoredCrcValue;
+ UINTN HeaderSize = sizeof(GPT_HEADER);
+
+ if ((GptData == NULL) || (GptData->ProtectiveMBR == NULL) || (GptData->Header == NULL))
+ return FALSE;
+
+ IsValid = (GptData->ProtectiveMBR->MBRSignature == 0xAA55);
+ IsValid = IsValid && ((GptData->ProtectiveMBR->partitions[0].type == 0xEE) ||
+ (GptData->ProtectiveMBR->partitions[1].type == 0xEE) ||
+ (GptData->ProtectiveMBR->partitions[2].type == 0xEE) ||
+ (GptData->ProtectiveMBR->partitions[3].type == 0xEE));
+
+ IsValid = IsValid && ((GptData->Header->signature == 0x5452415020494645ULL) &&
+ (GptData->Header->spec_revision == 0x00010000) &&
+ (GptData->Header->entry_size == 128));
+
+ // Looks good so far; check CRC value....
+ if (IsValid) {
+ if (GptData->Header->header_size < HeaderSize)
+ HeaderSize = GptData->Header->header_size;
+ StoredCrcValue = GptData->Header->header_crc32;
+ GptData->Header->header_crc32 = 0;
+ CrcValue = crc32(0x0, GptData->Header, HeaderSize);
+ if (CrcValue != StoredCrcValue)
+ IsValid = FALSE;
+ GptData->Header->header_crc32 = StoredCrcValue;
+ } // if