4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2012 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lba The starting Lba of the Partition Table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] PartHeader Stores the partition table that is read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The partition table is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The partition table is not valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the CRC field in the Partition table header is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Partition entry array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE the CRC is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE the CRC is invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE Restoring succeeds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Restoring failed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartEntry The partition entry array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] PEntryStatus the partition entry status array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync recording the status of each partition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Handle Parent Handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Parent DiskIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo2 Parent BlockIo2 interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DevicePath Parent Device Path.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Valid GPT disk.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_MEDIA_CHANGED Media changed Detected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Not a valid GPT disk.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a buffer for the Protective MBR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the Protective MBR from LBA #0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the Protective MBR is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ProtectiveMbr->Partition[Index].BootIndicator == 0x00 &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtectiveMbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UNPACK_UINT32 (ProtectiveMbr->Partition[Index].StartingLBA) == 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the GPT structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check primary and backup partition tables
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, " Partition Entry ReadDisk error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the integrity of partition entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If we got this far the GPT layout of the disk is valid and we should return true
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create child device handles
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartEntry + Index * PrimaryHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't use null EFI Partition Entries, Invalid Partition Entries or OS specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.PartitionSize = Entry->EndingLBA - Entry->StartingLBA + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (HdDev.Signature, &Entry->UniquePartitionGUID, sizeof (EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Index : %d\n", (UINT32) Index));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Start LBA : %lx\n", (UINT64) HdDev.PartitionStart));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " End LBA : %lx\n", (UINT64) Entry->EndingLBA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Partition size: %lx\n", (UINT64) HdDev.PartitionSize));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Start : %lx", MultU64x32 (Entry->StartingLBA, BlockSize)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " End : %lx\n", MultU64x32 (Entry->EndingLBA, BlockSize)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CompareGuid(&Entry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lba The starting Lba of the Partition Table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] PartHeader Stores the partition table that is read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The partition table is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The partition table is not valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Table Header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "Invalid efi partition table header\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the CRC field in the Partition table header is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Partition entry array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE the CRC is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE the CRC is invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE Restoring succeeds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Restoring failed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PartHeader->PartitionEntryLBA, (UINT32) BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartEntry The partition entry array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] PEntryStatus the partition entry status array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync recording the status of each partition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " start check partition entries\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartEntry + Index1 * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Bit 1 is set, this indicate that this is an OS specific GUID partition.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartEntry + Index2 * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Entry->EndingLBA >= StartingLBA && Entry->StartingLBA <= EndingLBA) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This region overlaps with the Index1'th region
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " End check partition entries\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Size == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If header size is 0 CRC will pass so return FALSE here
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // clear old crc from header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // set results
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // return status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));