4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $Id$ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Gpt.c
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2012 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
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 *
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 *
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 */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specification.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Partition.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The partition table is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The partition table is not valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionValidGptTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_LBA Lba,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the CRC field in the Partition table header is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Partition entry array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE the CRC is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE the CRC is invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckGptEntryArrayCRC (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE Restoring succeeds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Restoring failed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionRestoreGptTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckGptEntry (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_ENTRY *PartEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckCrcAltSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN MaxSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckCrc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN MaxSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionSetCrcAltSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionSetCrc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Valid GPT disk.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_MEDIA_CHANGED Media changed Detected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Not a valid GPT disk.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionInstallGptChildHandles (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LBA LastBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MASTER_BOOT_RECORD *ProtectiveMbr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_TABLE_HEADER *BackupHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_ENTRY *PartEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_ENTRY *Entry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_ENTRY_STATUS *PEntryStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS GptValidStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HARDDRIVE_DEVICE_PATH HdDev;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
76a9bce2b9ca58813ae03900c71fa04b93a04f1avboxsync VBoxLogFlowFuncMarkDP(DevicePath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtectiveMbr = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrimaryHeader = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BackupHeader = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartEntry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize = BlockIo->Media->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LastBlock = BlockIo->Media->LastBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId = BlockIo->Media->MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GptValidStatus = EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a buffer for the Protective MBR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtectiveMbr = AllocatePool (BlockSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ProtectiveMbr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the Protective MBR from LBA #0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProtectiveMbr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GptValidStatus = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify that the Protective MBR is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
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 ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index == MAX_MBR_PARTITIONS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the GPT structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrimaryHeader == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BackupHeader == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check primary and backup partition tables
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
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 }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
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 }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartEntry == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GptValidStatus = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, " Partition Entry ReadDisk error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PEntryStatus == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the integrity of partition entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If we got this far the GPT layout of the disk is valid and we should return true
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GptValidStatus = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create child device handles
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
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 PEntryStatus[Index].OutOfRange ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index].Overlap ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index].OsSpecific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't use null EFI Partition Entries, Invalid Partition Entries or OS specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&HdDev, sizeof (HdDev));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.Header.Type = MEDIA_DEVICE_PATH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.PartitionNumber = (UINT32) Index + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.SignatureType = SIGNATURE_TYPE_GUID;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.PartitionStart = Entry->StartingLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HdDev.PartitionSize = Entry->EndingLBA - Entry->StartingLBA + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (HdDev.Signature, &Entry->UniquePartitionGUID, sizeof (EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PartitionInstallChildHandle (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockIo2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry->StartingLBA,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry->EndingLBA,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CompareGuid(&Entry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ProtectiveMbr != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (ProtectiveMbr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrimaryHeader != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PrimaryHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BackupHeader != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BackupHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartEntry != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PEntryStatus != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PEntryStatus);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return GptValidStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports GPT partition structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The partition table is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The partition table is not valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionValidGptTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_LBA Lba,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_TABLE_HEADER *PartHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize = BlockIo->Media->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId = BlockIo->Media->MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr = AllocateZeroPool (BlockSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartHdr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Table Header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (Lba, BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr->MyLBA != Lba
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "Invalid efi partition table header\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the CRC field in the Partition table header is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Partition entry array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE the CRC is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE the CRC is invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckGptEntryArrayCRC (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Crc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Size;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the EFI Partition Entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ptr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockIo->Media->MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CalculateCrc32 (Ptr, Size, &Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Disk Io Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PartHeader Partition table header structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE Restoring succeeds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Restoring failed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionRestoreGptTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_TABLE_HEADER *PartHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LBA PEntryLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize = BlockIo->Media->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId = BlockIo->Media->MediaId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr = AllocateZeroPool (BlockSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PartHdr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PartHeader->LastUsableLBA + 1) : \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PRIMARY_PART_HEADER_LBA + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr->MyLBA = PartHeader->AlternateLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr->AlternateLBA = PartHeader->MyLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr->PartitionEntryLBA = PEntryLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->WriteDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (PartHdr->MyLBA, (UINT32) BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ptr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PartHeader->PartitionEntryLBA, (UINT32) BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->WriteDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32(PEntryLBA, (UINT32) BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (PartHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ptr != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore Partition Table to its alternate place.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Primary -> Backup or Backup -> Primary)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckGptEntry (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_TABLE_HEADER *PartHeader,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PARTITION_ENTRY *PartEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LBA StartingLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LBA EndingLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PARTITION_ENTRY *Entry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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 continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StartingLBA = Entry->StartingLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndingLBA = Entry->EndingLBA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StartingLBA > EndingLBA ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StartingLBA < PartHeader->FirstUsableLBA ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StartingLBA > PartHeader->LastUsableLBA ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndingLBA < PartHeader->FirstUsableLBA ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndingLBA > PartHeader->LastUsableLBA
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index1].OutOfRange = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Entry->Attributes & BIT1) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Bit 1 is set, this indicate that this is an OS specific GUID partition.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index1].OsSpecific = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
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 continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Entry->EndingLBA >= StartingLBA && Entry->StartingLBA <= EndingLBA) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This region overlaps with the Index1'th region
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index1].Overlap = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEntryStatus[Index2].Overlap = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, " End check partition entries\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionSetCrc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updates the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionSetCrcAltSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Crc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Hdr->CRC32 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Hdr->CRC32 = Crc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckCrc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN MaxSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the CRC32 value in the table header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MaxSize Max Size limit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The size of the table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Hdr Table to check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return TRUE CRC Valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return FALSE CRC Invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionCheckCrcAltSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN MaxSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_TABLE_HEADER *Hdr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Crc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OrgCrc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Crc = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Size == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If header size is 0 CRC will pass so return FALSE here
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((MaxSize != 0) && (Size > MaxSize)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // clear old crc from header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OrgCrc = Hdr->CRC32;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Hdr->CRC32 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // set results
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Hdr->CRC32 = Crc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // return status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_BEGIN ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OrgCrc != Crc) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_END ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (BOOLEAN) (OrgCrc == Crc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}