/** @file
  DXE capsule library.

  Caution: This module requires additional review when modified.
  This module will have external input - capsule image.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  SupportCapsuleImage(), ProcessCapsuleImage(), IsValidCapsuleHeader(),
  ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and
  performs basic validation.

  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>

#include <IndustryStandard/WindowsUxCapsule.h>

#include <Guid/FmpCapsule.h>
#include <Guid/SystemResourceTable.h>
#include <Guid/EventGroup.h>

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/CapsuleLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiLib.h>
#include <Library/BmpSupportLib.h>

#include <Protocol/GraphicsOutput.h>
#include <Protocol/EsrtManagement.h>
#include <Protocol/FirmwareManagement.h>
#include <Protocol/FirmwareManagementProgress.h>
#include <Protocol/DevicePath.h>

EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable                  = NULL;
BOOLEAN                   mIsVirtualAddrConverted      = FALSE;

BOOLEAN                   mDxeCapsuleLibEndOfDxe       = FALSE;
EFI_EVENT                 mDxeCapsuleLibEndOfDxeEvent  = NULL;

EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  *mFmpProgress = NULL;

/**
  Initialize capsule related variables.
**/
VOID
InitCapsuleVariable (
  VOID
  );

/**
  Record capsule status variable.

  @param[in] CapsuleHeader  The capsule image header
  @param[in] CapsuleStatus  The capsule process stauts

  @retval EFI_SUCCESS          The capsule status variable is recorded.
  @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.
**/
EFI_STATUS
RecordCapsuleStatusVariable (
  IN EFI_CAPSULE_HEADER                           *CapsuleHeader,
  IN EFI_STATUS                                   CapsuleStatus
  );

/**
  Record FMP capsule status variable.

  @param[in] CapsuleHeader  The capsule image header
  @param[in] CapsuleStatus  The capsule process stauts
  @param[in] PayloadIndex   FMP payload index
  @param[in] ImageHeader    FMP image header
  @param[in] FmpDevicePath  DevicePath associated with the FMP producer
  @param[in] CapFileName    Capsule file name

  @retval EFI_SUCCESS          The capsule status variable is recorded.
  @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.
**/
EFI_STATUS
RecordFmpCapsuleStatusVariable (
  IN EFI_CAPSULE_HEADER                            *CapsuleHeader,
  IN EFI_STATUS                                    CapsuleStatus,
  IN UINTN                                         PayloadIndex,
  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,
  IN EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath, OPTIONAL
  IN CHAR16                                        *CapFileName    OPTIONAL
  );

/**
  Function indicate the current completion progress of the firmware
  update. Platform may override with own specific progress function.

  @param[in]  Completion  A value between 1 and 100 indicating the current
                          completion progress of the firmware update

  @retval EFI_SUCESS             The capsule update progress was updated.
  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.
**/
EFI_STATUS
EFIAPI
UpdateImageProgress (
  IN UINTN  Completion
  );

/**
  Return if this capsule is a capsule name capsule, based upon CapsuleHeader.

  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER

  @retval TRUE  It is a capsule name capsule.
  @retval FALSE It is not a capsule name capsule.
**/
BOOLEAN
IsCapsuleNameCapsule (
  IN EFI_CAPSULE_HEADER         *CapsuleHeader
  )
{
  return CompareGuid (&CapsuleHeader->CapsuleGuid, &gEdkiiCapsuleOnDiskNameGuid);
}

/**
  Return if this CapsuleGuid is a FMP capsule GUID or not.

  @param[in] CapsuleGuid A pointer to EFI_GUID

  @retval TRUE  It is a FMP capsule GUID.
  @retval FALSE It is not a FMP capsule GUID.
**/
BOOLEAN
IsFmpCapsuleGuid (
  IN EFI_GUID  *CapsuleGuid
  )
{
  if (CompareGuid(&gEfiFmpCapsuleGuid, CapsuleGuid)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Validate if it is valid capsule header

  Caution: This function may receive untrusted input.

  This function assumes the caller provided correct CapsuleHeader pointer
  and CapsuleSize.

  This function validates the fields in EFI_CAPSULE_HEADER.

  @param[in]  CapsuleHeader    Points to a capsule header.
  @param[in]  CapsuleSize      Size of the whole capsule image.

**/
BOOLEAN
IsValidCapsuleHeader (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader,
  IN UINT64              CapsuleSize
  )
{
  if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {
    return FALSE;
  }
  if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
    return FALSE;
  }
  return TRUE;
}

/**
  Validate Fmp capsules layout.

  Caution: This function may receive untrusted input.

  This function assumes the caller validated the capsule by using
  IsValidCapsuleHeader(), so that all fields in EFI_CAPSULE_HEADER are correct.
  The capsule buffer size is CapsuleHeader->CapsuleImageSize.

  This function validates the fields in EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
  and EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.

  This function need support nested FMP capsule.

  @param[in]   CapsuleHeader        Points to a capsule header.
  @param[out]  EmbeddedDriverCount  The EmbeddedDriverCount in the FMP capsule.

  @retval EFI_SUCESS             Input capsule is a correct FMP capsule.
  @retval EFI_INVALID_PARAMETER  Input capsule is not a correct FMP capsule.
**/
EFI_STATUS
ValidateFmpCapsule (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader,
  OUT UINT16             *EmbeddedDriverCount OPTIONAL
  )
{
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER       *FmpCapsuleHeader;
  UINT8                                        *EndOfCapsule;
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;
  UINT8                                        *EndOfPayload;
  UINT64                                       *ItemOffsetList;
  UINT32                                       ItemNum;
  UINTN                                        Index;
  UINTN                                        FmpCapsuleSize;
  UINTN                                        FmpCapsuleHeaderSize;
  UINT64                                       FmpImageSize;
  UINTN                                        FmpImageHeaderSize;

  if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {
    return ValidateFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), EmbeddedDriverCount);
  }

  if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
    DEBUG((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
    return EFI_INVALID_PARAMETER;
  }

  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);
  EndOfCapsule     = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;
  FmpCapsuleSize   = (UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader;

  if (FmpCapsuleSize < sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {
    DEBUG((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));
    return EFI_INVALID_PARAMETER;
  }

  // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
  if (FmpCapsuleHeader->Version != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
    DEBUG((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));
    return EFI_INVALID_PARAMETER;
  }
  ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);

  // No overflow
  ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;

  if ((FmpCapsuleSize - sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof(UINT64) < ItemNum) {
    DEBUG((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));
    return EFI_INVALID_PARAMETER;
  }
  FmpCapsuleHeaderSize = sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof(UINT64)*ItemNum;

  // Check ItemOffsetList
  for (Index = 0; Index < ItemNum; Index++) {
    if (ItemOffsetList[Index] >= FmpCapsuleSize) {
      DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));
      return EFI_INVALID_PARAMETER;
    }
    if (ItemOffsetList[Index] < FmpCapsuleHeaderSize) {
      DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));
      return EFI_INVALID_PARAMETER;
    }
    //
    // All the address in ItemOffsetList must be stored in ascending order
    //
    if (Index > 0) {
      if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {
        DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index - 1, ItemOffsetList[Index - 1]));
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
  for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
    ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
    if (Index == ItemNum - 1) {
      EndOfPayload = (UINT8 *)((UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader);
    } else {
      EndOfPayload = (UINT8 *)(UINTN)ItemOffsetList[Index+1];
    }
    FmpImageSize = (UINTN)EndOfPayload - ItemOffsetList[Index];

    FmpImageHeaderSize = sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);
    if ((ImageHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) ||
        (ImageHeader->Version < 1)) {
      DEBUG((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));
      return EFI_INVALID_PARAMETER;
    }
    if (ImageHeader->Version == 1) {
      FmpImageHeaderSize = OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
    } else if (ImageHeader->Version == 2) {
      FmpImageHeaderSize = OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
    }
    if (FmpImageSize < FmpImageHeaderSize) {
      DEBUG((DEBUG_ERROR, "FmpImageSize(0x%lx) < FmpImageHeaderSize(0x%x)\n", FmpImageSize, FmpImageHeaderSize));
      return EFI_INVALID_PARAMETER;
    }

    // No overflow
    if (FmpImageSize != (UINT64)FmpImageHeaderSize + (UINT64)ImageHeader->UpdateImageSize + (UINT64)ImageHeader->UpdateVendorCodeSize) {
      DEBUG((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));
      return EFI_INVALID_PARAMETER;
    }
  }

  if (ItemNum == 0) {
    //
    // No driver & payload element in FMP
    //
    EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);
    if (EndOfPayload != EndOfCapsule) {
      DEBUG((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));
      return EFI_INVALID_PARAMETER;
    }
    return EFI_UNSUPPORTED;
  }

  if (EmbeddedDriverCount != NULL) {
    *EmbeddedDriverCount = FmpCapsuleHeader->EmbeddedDriverCount;
  }

  return EFI_SUCCESS;
}

/**
  Those capsules supported by the firmwares.

  Caution: This function may receive untrusted input.

  @param[in]  CapsuleHeader    Points to a capsule header.

  @retval EFI_SUCESS       Input capsule is supported by firmware.
  @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.
**/
EFI_STATUS
DisplayCapsuleImage (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  DISPLAY_DISPLAY_PAYLOAD       *ImagePayload;
  UINTN                         PayloadSize;
  EFI_STATUS                    Status;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
  UINTN                         BltSize;
  UINTN                         Height;
  UINTN                         Width;
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;

  //
  // UX capsule doesn't have extended header entries.
  //
  if (CapsuleHeader->HeaderSize != sizeof (EFI_CAPSULE_HEADER)) {
    return EFI_UNSUPPORTED;
  }
  ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)((UINTN) CapsuleHeader + CapsuleHeader->HeaderSize);
  //
  // (CapsuleImageSize > HeaderSize) is guaranteed by IsValidCapsuleHeader().
  //
  PayloadSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;

  //
  // Make sure the image payload at least contain the DISPLAY_DISPLAY_PAYLOAD header.
  // Further size check is performed by the logic translating BMP to GOP BLT.
  //
  if (PayloadSize <= sizeof (DISPLAY_DISPLAY_PAYLOAD)) {
    return EFI_INVALID_PARAMETER;
  }

  if (ImagePayload->Version != 1) {
    return EFI_UNSUPPORTED;
  }
  if (CalculateCheckSum8((UINT8 *)CapsuleHeader, CapsuleHeader->CapsuleImageSize) != 0) {
    return EFI_UNSUPPORTED;
  }
  //
  // Only Support Bitmap by now
  //
  if (ImagePayload->ImageType != 0) {
    return EFI_UNSUPPORTED;
  }

  //
  // Try to open GOP
  //
  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
  if (EFI_ERROR (Status)) {
    Status = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&GraphicsOutput);
    if (EFI_ERROR(Status)) {
      return EFI_UNSUPPORTED;
    }
  }

  if (GraphicsOutput->Mode->Mode != ImagePayload->Mode) {
    return EFI_UNSUPPORTED;
  }

  Blt = NULL;
  Width = 0;
  Height = 0;
  Status = TranslateBmpToGopBlt (
             ImagePayload + 1,
             PayloadSize - sizeof(DISPLAY_DISPLAY_PAYLOAD),
             &Blt,
             &BltSize,
             &Height,
             &Width
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = GraphicsOutput->Blt (
                             GraphicsOutput,
                             Blt,
                             EfiBltBufferToVideo,
                             0,
                             0,
                             (UINTN) ImagePayload->OffsetX,
                             (UINTN) ImagePayload->OffsetY,
                             Width,
                             Height,
                             Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
                             );

  FreePool(Blt);

  return Status;
}

/**
  Dump FMP information.

  @param[in] ImageInfoSize       The size of ImageInfo, in bytes.
  @param[in] ImageInfo           A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.
  @param[in] DescriptorVersion   The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
  @param[in] DescriptorCount     The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
  @param[in] DescriptorSize      The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.
  @param[in] PackageVersion      The version of package.
  @param[in] PackageVersionName  The version name of package.
**/
VOID
DumpFmpImageInfo (
  IN UINTN                           ImageInfoSize,
  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR   *ImageInfo,
  IN UINT32                          DescriptorVersion,
  IN UINT8                           DescriptorCount,
  IN UINTN                           DescriptorSize,
  IN UINT32                          PackageVersion,
  IN CHAR16                          *PackageVersionName
  )
{
  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *CurrentImageInfo;
  UINTN                                         Index;

  DEBUG((DEBUG_VERBOSE, "  DescriptorVersion  - 0x%x\n", DescriptorVersion));
  DEBUG((DEBUG_VERBOSE, "  DescriptorCount    - 0x%x\n", DescriptorCount));
  DEBUG((DEBUG_VERBOSE, "  DescriptorSize     - 0x%x\n", DescriptorSize));
  DEBUG((DEBUG_VERBOSE, "  PackageVersion     - 0x%x\n", PackageVersion));
  DEBUG((DEBUG_VERBOSE, "  PackageVersionName - %s\n\n", PackageVersionName));
  CurrentImageInfo = ImageInfo;
  for (Index = 0; Index < DescriptorCount; Index++) {
    DEBUG((DEBUG_VERBOSE, "  ImageDescriptor (%d)\n", Index));
    DEBUG((DEBUG_VERBOSE, "    ImageIndex                  - 0x%x\n", CurrentImageInfo->ImageIndex));
    DEBUG((DEBUG_VERBOSE, "    ImageTypeId                 - %g\n", &CurrentImageInfo->ImageTypeId));
    DEBUG((DEBUG_VERBOSE, "    ImageId                     - 0x%lx\n", CurrentImageInfo->ImageId));
    DEBUG((DEBUG_VERBOSE, "    ImageIdName                 - %s\n", CurrentImageInfo->ImageIdName));
    DEBUG((DEBUG_VERBOSE, "    Version                     - 0x%x\n", CurrentImageInfo->Version));
    DEBUG((DEBUG_VERBOSE, "    VersionName                 - %s\n", CurrentImageInfo->VersionName));
    DEBUG((DEBUG_VERBOSE, "    Size                        - 0x%x\n", CurrentImageInfo->Size));
    DEBUG((DEBUG_VERBOSE, "    AttributesSupported         - 0x%lx\n", CurrentImageInfo->AttributesSupported));
    DEBUG((DEBUG_VERBOSE, "    AttributesSetting           - 0x%lx\n", CurrentImageInfo->AttributesSetting));
    DEBUG((DEBUG_VERBOSE, "    Compatibilities             - 0x%lx\n", CurrentImageInfo->Compatibilities));
    if (DescriptorVersion > 1) {
      DEBUG((DEBUG_VERBOSE, "    LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion));
      if (DescriptorVersion > 2) {
        DEBUG((DEBUG_VERBOSE, "    LastAttemptVersion          - 0x%x\n", CurrentImageInfo->LastAttemptVersion));
        DEBUG((DEBUG_VERBOSE, "    LastAttemptStatus           - 0x%x\n", CurrentImageInfo->LastAttemptStatus));
        DEBUG((DEBUG_VERBOSE, "    HardwareInstance            - 0x%lx\n", CurrentImageInfo->HardwareInstance));
      }
    }
    //
    // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
    //
    CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
  }
}

/**
  Dump a non-nested FMP capsule.

  @param[in]  CapsuleHeader  A pointer to CapsuleHeader
**/
VOID
DumpFmpCapsule (
  IN EFI_CAPSULE_HEADER                *CapsuleHeader
  )
{
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER        *FmpCapsuleHeader;
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader;
  UINTN                                         Index;
  UINT64                                        *ItemOffsetList;

  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);

  DEBUG((DEBUG_VERBOSE, "FmpCapsule:\n"));
  DEBUG((DEBUG_VERBOSE, "  Version                - 0x%x\n", FmpCapsuleHeader->Version));
  DEBUG((DEBUG_VERBOSE, "  EmbeddedDriverCount    - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount));
  DEBUG((DEBUG_VERBOSE, "  PayloadItemCount       - 0x%x\n", FmpCapsuleHeader->PayloadItemCount));

  ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
  for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {
    DEBUG((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));
  }
  for (; Index < (UINT32)FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount; Index++) {
    DEBUG((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));
    ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);

    DEBUG((DEBUG_VERBOSE, "  ImageHeader:\n"));
    DEBUG((DEBUG_VERBOSE, "    Version                - 0x%x\n", ImageHeader->Version));
    DEBUG((DEBUG_VERBOSE, "    UpdateImageTypeId      - %g\n", &ImageHeader->UpdateImageTypeId));
    DEBUG((DEBUG_VERBOSE, "    UpdateImageIndex       - 0x%x\n", ImageHeader->UpdateImageIndex));
    DEBUG((DEBUG_VERBOSE, "    UpdateImageSize        - 0x%x\n", ImageHeader->UpdateImageSize));
    DEBUG((DEBUG_VERBOSE, "    UpdateVendorCodeSize   - 0x%x\n", ImageHeader->UpdateVendorCodeSize));
    if (ImageHeader->Version >= 2) {
      DEBUG((DEBUG_VERBOSE, "    UpdateHardwareInstance - 0x%lx\n", ImageHeader->UpdateHardwareInstance));
      if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
        DEBUG((DEBUG_VERBOSE, "    ImageCapsuleSupport    - 0x%lx\n",  ImageHeader->ImageCapsuleSupport));
      }
    }
  }
}

/**
  Dump all FMP information.
**/
VOID
DumpAllFmpInfo (
  VOID
  )
{
  EFI_STATUS                                    Status;
  EFI_HANDLE                                    *HandleBuffer;
  UINTN                                         NumberOfHandles;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;
  UINTN                                         Index;
  UINTN                                         ImageInfoSize;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;
  UINT32                                        FmpImageInfoDescriptorVer;
  UINT8                                         FmpImageInfoCount;
  UINTN                                         DescriptorSize;
  UINT32                                        PackageVersion;
  CHAR16                                        *PackageVersionName;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareManagementProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR(Status)) {
    return ;
  }

  for (Index = 0; Index < NumberOfHandles; Index++) {
    Status = gBS->HandleProtocol(
                    HandleBuffer[Index],
                    &gEfiFirmwareManagementProtocolGuid,
                    (VOID **)&Fmp
                    );
    if (EFI_ERROR(Status)) {
      continue;
    }

    ImageInfoSize = 0;
    Status = Fmp->GetImageInfo (
                    Fmp,
                    &ImageInfoSize,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL
                    );
    if (Status != EFI_BUFFER_TOO_SMALL) {
      continue;
    }

    FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
    if (FmpImageInfoBuf == NULL) {
      continue;
    }

    PackageVersionName = NULL;
    Status = Fmp->GetImageInfo (
                    Fmp,
                    &ImageInfoSize,               // ImageInfoSize
                    FmpImageInfoBuf,              // ImageInfo
                    &FmpImageInfoDescriptorVer,   // DescriptorVersion
                    &FmpImageInfoCount,           // DescriptorCount
                    &DescriptorSize,              // DescriptorSize
                    &PackageVersion,              // PackageVersion
                    &PackageVersionName           // PackageVersionName
                    );
    if (EFI_ERROR(Status)) {
      FreePool(FmpImageInfoBuf);
      continue;
    }

    DEBUG((DEBUG_INFO, "FMP (%d) ImageInfo:\n", Index));
    DumpFmpImageInfo(
      ImageInfoSize,               // ImageInfoSize
      FmpImageInfoBuf,             // ImageInfo
      FmpImageInfoDescriptorVer,   // DescriptorVersion
      FmpImageInfoCount,           // DescriptorCount
      DescriptorSize,              // DescriptorSize
      PackageVersion,              // PackageVersion
      PackageVersionName           // PackageVersionName
      );

    if (PackageVersionName != NULL) {
      FreePool(PackageVersionName);
    }

    FreePool(FmpImageInfoBuf);
  }

  FreePool (HandleBuffer);

  return ;
}

/**
  Get FMP handle by ImageTypeId and HardwareInstance.

  @param[in]     UpdateImageTypeId       Used to identify device firmware targeted by this update.
  @param[in]     UpdateHardwareInstance  The HardwareInstance to target with this update.
  @param[out]    NoHandles               The number of handles returned in HandleBuf.
  @param[out]    HandleBuf               A pointer to the buffer to return the requested array of handles.
  @param[out]    ResetRequiredBuf        A pointer to the buffer to return reset required flag for
                                         the requested array of handles.

  @retval EFI_SUCCESS            The array of handles and their reset required flag were returned in
                                 HandleBuf and ResetRequiredBuf, and the number of handles in HandleBuf
                                 was returned in NoHandles.
  @retval EFI_NOT_FOUND          No handles match the search.
  @retval EFI_OUT_OF_RESOURCES   There is not enough pool memory to store the matching results.
**/
EFI_STATUS
GetFmpHandleBufferByType (
  IN     EFI_GUID                     *UpdateImageTypeId,
  IN     UINT64                       UpdateHardwareInstance,
  OUT    UINTN                        *NoHandles, OPTIONAL
  OUT    EFI_HANDLE                   **HandleBuf, OPTIONAL
  OUT    BOOLEAN                      **ResetRequiredBuf OPTIONAL
  )
{
  EFI_STATUS                                    Status;
  EFI_HANDLE                                    *HandleBuffer;
  UINTN                                         NumberOfHandles;
  EFI_HANDLE                                    *MatchedHandleBuffer;
  BOOLEAN                                       *MatchedResetRequiredBuffer;
  UINTN                                         MatchedNumberOfHandles;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;
  UINTN                                         Index;
  UINTN                                         ImageInfoSize;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;
  UINT32                                        FmpImageInfoDescriptorVer;
  UINT8                                         FmpImageInfoCount;
  UINTN                                         DescriptorSize;
  UINT32                                        PackageVersion;
  CHAR16                                        *PackageVersionName;
  UINTN                                         Index2;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *TempFmpImageInfo;

  if (NoHandles != NULL) {
    *NoHandles = 0;
  }
  if (HandleBuf != NULL) {
    *HandleBuf = NULL;
  }
  if (ResetRequiredBuf != NULL) {
    *ResetRequiredBuf = NULL;
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareManagementProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  MatchedNumberOfHandles = 0;

  MatchedHandleBuffer = NULL;
  if (HandleBuf != NULL) {
    MatchedHandleBuffer = AllocateZeroPool (sizeof(EFI_HANDLE) * NumberOfHandles);
    if (MatchedHandleBuffer == NULL) {
      FreePool (HandleBuffer);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  MatchedResetRequiredBuffer = NULL;
  if (ResetRequiredBuf != NULL) {
    MatchedResetRequiredBuffer = AllocateZeroPool (sizeof(BOOLEAN) * NumberOfHandles);
    if (MatchedResetRequiredBuffer == NULL) {
      if (MatchedHandleBuffer != NULL) {
        FreePool (MatchedHandleBuffer);
      }
      FreePool (HandleBuffer);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  for (Index = 0; Index < NumberOfHandles; Index++) {
    Status = gBS->HandleProtocol(
                    HandleBuffer[Index],
                    &gEfiFirmwareManagementProtocolGuid,
                    (VOID **)&Fmp
                    );
    if (EFI_ERROR(Status)) {
      continue;
    }

    ImageInfoSize = 0;
    Status = Fmp->GetImageInfo (
                    Fmp,
                    &ImageInfoSize,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL
                    );
    if (Status != EFI_BUFFER_TOO_SMALL) {
      continue;
    }

    FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
    if (FmpImageInfoBuf == NULL) {
      continue;
    }

    PackageVersionName = NULL;
    Status = Fmp->GetImageInfo (
                    Fmp,
                    &ImageInfoSize,               // ImageInfoSize
                    FmpImageInfoBuf,              // ImageInfo
                    &FmpImageInfoDescriptorVer,   // DescriptorVersion
                    &FmpImageInfoCount,           // DescriptorCount
                    &DescriptorSize,              // DescriptorSize
                    &PackageVersion,              // PackageVersion
                    &PackageVersionName           // PackageVersionName
                    );
    if (EFI_ERROR(Status)) {
      FreePool(FmpImageInfoBuf);
      continue;
    }

    if (PackageVersionName != NULL) {
      FreePool(PackageVersionName);
    }

    TempFmpImageInfo = FmpImageInfoBuf;
    for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {
      //
      // Check if this FMP instance matches
      //
      if (CompareGuid(UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId)) {
        if ((UpdateHardwareInstance == 0) ||
            ((FmpImageInfoDescriptorVer >= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) &&
             (UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance))) {
          if (MatchedHandleBuffer != NULL) {
            MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];
          }
          if (MatchedResetRequiredBuffer != NULL) {
            MatchedResetRequiredBuffer[MatchedNumberOfHandles] = (((TempFmpImageInfo->AttributesSupported &
                                                                 IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) &&
                                                                 ((TempFmpImageInfo->AttributesSetting &
                                                                 IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0));
          }
          MatchedNumberOfHandles++;
          break;
        }
      }
      TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);
    }
    FreePool(FmpImageInfoBuf);
  }

  FreePool (HandleBuffer);

  if (MatchedNumberOfHandles == 0) {
    return EFI_NOT_FOUND;
  }

  if (NoHandles != NULL) {
    *NoHandles = MatchedNumberOfHandles;
  }
  if (HandleBuf != NULL) {
    *HandleBuf = MatchedHandleBuffer;
  }
  if (ResetRequiredBuf != NULL) {
    *ResetRequiredBuf = MatchedResetRequiredBuffer;
  }

  return EFI_SUCCESS;
}

/**
  Return FmpImageInfoDescriptorVer by an FMP handle.

  @param[in]  Handle   A FMP handle.

  @return FmpImageInfoDescriptorVer associated with the FMP.
**/
UINT32
GetFmpImageInfoDescriptorVer (
  IN EFI_HANDLE                                   Handle
  )
{
  EFI_STATUS                                    Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;
  UINTN                                         ImageInfoSize;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;
  UINT32                                        FmpImageInfoDescriptorVer;
  UINT8                                         FmpImageInfoCount;
  UINTN                                         DescriptorSize;
  UINT32                                        PackageVersion;
  CHAR16                                        *PackageVersionName;

  Status = gBS->HandleProtocol(
                  Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  (VOID **)&Fmp
                  );
  if (EFI_ERROR(Status)) {
    return 0;
  }

  ImageInfoSize = 0;
  Status = Fmp->GetImageInfo (
                  Fmp,
                  &ImageInfoSize,
                  NULL,
                  NULL,
                  NULL,
                  NULL,
                  NULL,
                  NULL
                  );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return 0;
  }

  FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
  if (FmpImageInfoBuf == NULL) {
    return 0;
  }

  PackageVersionName = NULL;
  Status = Fmp->GetImageInfo (
                  Fmp,
                  &ImageInfoSize,               // ImageInfoSize
                  FmpImageInfoBuf,              // ImageInfo
                  &FmpImageInfoDescriptorVer,   // DescriptorVersion
                  &FmpImageInfoCount,           // DescriptorCount
                  &DescriptorSize,              // DescriptorSize
                  &PackageVersion,              // PackageVersion
                  &PackageVersionName           // PackageVersionName
                  );
  if (EFI_ERROR(Status)) {
    FreePool(FmpImageInfoBuf);
    return 0;
  }
  return FmpImageInfoDescriptorVer;
}

/**
  Set FMP image data.

  @param[in]  Handle        A FMP handle.
  @param[in]  ImageHeader   The payload image header.
  @param[in]  PayloadIndex  The index of the payload.

  @return The status of FMP->SetImage.
**/
EFI_STATUS
SetFmpImageData (
  IN EFI_HANDLE                                   Handle,
  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader,
  IN UINTN                                        PayloadIndex
  )
{
  EFI_STATUS                                    Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;
  UINT8                                         *Image;
  VOID                                          *VendorCode;
  CHAR16                                        *AbortReason;
  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS ProgressCallback;

  Status = gBS->HandleProtocol(
                  Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  (VOID **)&Fmp
                  );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Lookup Firmware Management Progress Protocol before SetImage() is called
  // This is an optional protocol that may not be present on Handle.
  //
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEdkiiFirmwareManagementProgressProtocolGuid,
                  (VOID **)&mFmpProgress
                  );
  if (EFI_ERROR (Status)) {
    mFmpProgress = NULL;
  }

  if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
    Image = (UINT8 *)(ImageHeader + 1);
  } else {
    //
    // If the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER is version 1,
    // Header should exclude UpdateHardwareInstance field, and
    // ImageCapsuleSupport field if version is 2.
    //
    if (ImageHeader->Version == 1) {
      Image = (UINT8 *)ImageHeader + OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
    } else {
      Image = (UINT8 *)ImageHeader + OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
    }
  }

  if (ImageHeader->UpdateVendorCodeSize == 0) {
    VendorCode = NULL;
  } else {
    VendorCode = Image + ImageHeader->UpdateImageSize;
  }
  AbortReason = NULL;
  DEBUG((DEBUG_INFO, "Fmp->SetImage ...\n"));
  DEBUG((DEBUG_INFO, "ImageTypeId - %g, ", &ImageHeader->UpdateImageTypeId));
  DEBUG((DEBUG_INFO, "PayloadIndex - 0x%x, ", PayloadIndex));
  DEBUG((DEBUG_INFO, "ImageIndex - 0x%x ", ImageHeader->UpdateImageIndex));
  if (ImageHeader->Version >= 2) {
    DEBUG((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));
    if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
      DEBUG((DEBUG_INFO, "(ImageCapsuleSupport - 0x%x)", ImageHeader->ImageCapsuleSupport));
    }
  }
  DEBUG((DEBUG_INFO, "\n"));

  //
  // Before calling SetImage(), reset the progress bar to 0%
  //
  ProgressCallback = UpdateImageProgress;
  Status = UpdateImageProgress (0);
  if (EFI_ERROR (Status)) {
    ProgressCallback = NULL;
  }

  Status = Fmp->SetImage(
                  Fmp,
                  ImageHeader->UpdateImageIndex,          // ImageIndex
                  Image,                                  // Image
                  ImageHeader->UpdateImageSize,           // ImageSize
                  VendorCode,                             // VendorCode
                  ProgressCallback,                       // Progress
                  &AbortReason                            // AbortReason
                  );
  //
  // Set the progress bar to 100% after returning from SetImage()
  //
  if (ProgressCallback != NULL) {
    UpdateImageProgress (100);
  }

  DEBUG((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));
  if (AbortReason != NULL) {
    DEBUG ((DEBUG_ERROR, "%s\n", AbortReason));
    FreePool(AbortReason);
  }

  //
  // Clear mFmpProgress after SetImage() returns
  //
  mFmpProgress = NULL;

  return Status;
}

/**
  Start a UEFI image in the FMP payload.

  @param[in]  ImageBuffer   A pointer to the memory location containing a copy of the image to be loaded..
  @param[in]  ImageSize     The size in bytes of ImageBuffer.

  @return The status of gBS->LoadImage and gBS->StartImage.
**/
EFI_STATUS
StartFmpImage (
  IN VOID   *ImageBuffer,
  IN UINTN  ImageSize
  )
{
  MEMMAP_DEVICE_PATH                            MemMapNode;
  EFI_STATUS                                    Status;
  EFI_HANDLE                                    ImageHandle;
  EFI_DEVICE_PATH_PROTOCOL                      *DriverDevicePath;
  UINTN                                         ExitDataSize;

  SetDevicePathNodeLength (&MemMapNode.Header, sizeof (MemMapNode));
  MemMapNode.Header.Type     = HARDWARE_DEVICE_PATH;
  MemMapNode.Header.SubType  = HW_MEMMAP_DP;
  MemMapNode.MemoryType      = EfiBootServicesCode;
  MemMapNode.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBuffer;
  MemMapNode.EndingAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN)((UINT8 *)ImageBuffer + ImageSize - 1);

  DriverDevicePath = AppendDevicePathNode (NULL, &MemMapNode.Header);
  if (DriverDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DEBUG((DEBUG_INFO, "FmpCapsule: LoadImage ...\n"));
  Status = gBS->LoadImage(
                  FALSE,
                  gImageHandle,
                  DriverDevicePath,
                  ImageBuffer,
                  ImageSize,
                  &ImageHandle
                  );
  DEBUG((DEBUG_INFO, "FmpCapsule: LoadImage - %r\n", Status));
  if (EFI_ERROR(Status)) {
    //
    // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
    // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
    // If the caller doesn't have the option to defer the execution of an image, we should
    // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
    //
    if (Status == EFI_SECURITY_VIOLATION) {
      gBS->UnloadImage (ImageHandle);
    }
    FreePool(DriverDevicePath);
    return Status;
  }

  DEBUG((DEBUG_INFO, "FmpCapsule: StartImage ...\n"));
  Status = gBS->StartImage(
                  ImageHandle,
                  &ExitDataSize,
                  NULL
                  );
  DEBUG((DEBUG_INFO, "FmpCapsule: StartImage - %r\n", Status));
  if (EFI_ERROR(Status)) {
    DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));
  }

  FreePool(DriverDevicePath);
  return Status;
}

/**
  Record FMP capsule status.

  @param[in] Handle         A FMP handle.
  @param[in] CapsuleHeader  The capsule image header
  @param[in] CapsuleStatus  The capsule process stauts
  @param[in] PayloadIndex   FMP payload index
  @param[in] ImageHeader    FMP image header
  @param[in] CapFileName    Capsule file name
**/
VOID
RecordFmpCapsuleStatus (
  IN EFI_HANDLE                                    Handle,  OPTIONAL
  IN EFI_CAPSULE_HEADER                            *CapsuleHeader,
  IN EFI_STATUS                                    CapsuleStatus,
  IN UINTN                                         PayloadIndex,
  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,
  IN CHAR16                                        *CapFileName   OPTIONAL
  )
{
  EFI_STATUS                                    Status;
  EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath;
  UINT32                                        FmpImageInfoDescriptorVer;
  EFI_STATUS                                    StatusEsrt;
  ESRT_MANAGEMENT_PROTOCOL                      *EsrtProtocol;
  EFI_SYSTEM_RESOURCE_ENTRY                     EsrtEntry;

  FmpDevicePath = NULL;
  if (Handle != NULL) {
    gBS->HandleProtocol(
           Handle,
           &gEfiDevicePathProtocolGuid,
           (VOID **)&FmpDevicePath
           );
  }

  RecordFmpCapsuleStatusVariable (
    CapsuleHeader,
    CapsuleStatus,
    PayloadIndex,
    ImageHeader,
    FmpDevicePath,
    CapFileName
    );

  //
  // Update corresponding ESRT entry LastAttemp Status
  //
  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);
  if (EFI_ERROR (Status)) {
    return ;
  }

  if (Handle == NULL) {
    return ;
  }

  //
  // Update EsrtEntry For V1, V2 FMP instance.
  // V3 FMP ESRT cache will be synced up through SyncEsrtFmp interface
  //
  FmpImageInfoDescriptorVer = GetFmpImageInfoDescriptorVer (Handle);
  if (FmpImageInfoDescriptorVer < EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) {
    StatusEsrt = EsrtProtocol->GetEsrtEntry(&ImageHeader->UpdateImageTypeId, &EsrtEntry);
    if (!EFI_ERROR(StatusEsrt)){
      if (!EFI_ERROR(CapsuleStatus)) {
        EsrtEntry.LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
      } else {
        EsrtEntry.LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
      }
      EsrtEntry.LastAttemptVersion = 0;
      EsrtProtocol->UpdateEsrtEntry(&EsrtEntry);
    }
  }
}

/**
  Process Firmware management protocol data capsule.

  This function assumes the caller validated the capsule by using
  ValidateFmpCapsule(), so that all fields in EFI_CAPSULE_HEADER,
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER are correct.

  This function need support nested FMP capsule.

  @param[in]  CapsuleHeader         Points to a capsule header.
  @param[in]  CapFileName           Capsule file name.
  @param[out] ResetRequired         Indicates whether reset is required or not.

  @retval EFI_SUCESS            Process Capsule Image successfully.
  @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.
  @retval EFI_VOLUME_CORRUPTED  FV volume in the capsule is corrupted.
  @retval EFI_OUT_OF_RESOURCES  Not enough memory.
  @retval EFI_NOT_READY         No FMP protocol to handle this FMP capsule.
**/
EFI_STATUS
ProcessFmpCapsuleImage (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader,
  IN CHAR16              *CapFileName,  OPTIONAL
  OUT BOOLEAN            *ResetRequired OPTIONAL
  )
{
  EFI_STATUS                                    Status;
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER        *FmpCapsuleHeader;
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader;
  UINT64                                        *ItemOffsetList;
  UINT32                                        ItemNum;
  UINTN                                         Index;
  EFI_HANDLE                                    *HandleBuffer;
  BOOLEAN                                       *ResetRequiredBuffer;
  UINTN                                         NumberOfHandles;
  UINTN                                         DriverLen;
  UINT64                                        UpdateHardwareInstance;
  UINTN                                         Index2;
  BOOLEAN                                       NotReady;
  BOOLEAN                                       Abort;

  if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {
    return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), CapFileName, ResetRequired);
  }

  NotReady = FALSE;
  Abort = FALSE;

  DumpFmpCapsule(CapsuleHeader);

  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);

  if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
    return EFI_INVALID_PARAMETER;
  }
  ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);

  ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;

  //
  // capsule in which driver count and payload count are both zero is not processed.
  //
  if (ItemNum == 0) {
    return EFI_SUCCESS;
  }

  //
  // 1. Try to load & start all the drivers within capsule
  //
  for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {
    if ((FmpCapsuleHeader->PayloadItemCount == 0) &&
        (Index == (UINTN)FmpCapsuleHeader->EmbeddedDriverCount - 1)) {
      //
      // When driver is last element in the ItemOffsetList array, the driver size is calculated by reference CapsuleImageSize in EFI_CAPSULE_HEADER
      //
      DriverLen = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize - (UINTN)ItemOffsetList[Index];
    } else {
      DriverLen = (UINTN)ItemOffsetList[Index + 1] - (UINTN)ItemOffsetList[Index];
    }

    Status = StartFmpImage (
               (UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index],
               DriverLen
               );
    if (EFI_ERROR(Status)) {
      DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));
      return Status;
    }
  }

  //
  // 2. Route payload to right FMP instance
  //
  DEBUG((DEBUG_INFO, "FmpCapsule: route payload to right FMP instance ...\n"));

  DumpAllFmpInfo ();

  //
  // Check all the payload entry in capsule payload list
  //
  for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
    ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);

    UpdateHardwareInstance = 0;
    ///
    /// UpdateHardwareInstance field was added in Version 2
    ///
    if (ImageHeader->Version >= 2) {
      UpdateHardwareInstance = ImageHeader->UpdateHardwareInstance;
    }

    Status = GetFmpHandleBufferByType (
               &ImageHeader->UpdateImageTypeId,
               UpdateHardwareInstance,
               &NumberOfHandles,
               &HandleBuffer,
               &ResetRequiredBuffer
               );
    if (EFI_ERROR(Status) ||
        (HandleBuffer == NULL) ||
        (ResetRequiredBuffer == NULL)) {
      NotReady = TRUE;
      RecordFmpCapsuleStatus (
        NULL,
        CapsuleHeader,
        EFI_NOT_READY,
        Index - FmpCapsuleHeader->EmbeddedDriverCount,
        ImageHeader,
        CapFileName
        );
      continue;
    }

    for (Index2 = 0; Index2 < NumberOfHandles; Index2++) {
      if (Abort) {
        RecordFmpCapsuleStatus (
          HandleBuffer[Index2],
          CapsuleHeader,
          EFI_ABORTED,
          Index - FmpCapsuleHeader->EmbeddedDriverCount,
          ImageHeader,
          CapFileName
          );
        continue;
      }

      Status = SetFmpImageData (
                 HandleBuffer[Index2],
                 ImageHeader,
                 Index - FmpCapsuleHeader->EmbeddedDriverCount
                 );
      if (Status != EFI_SUCCESS) {
        Abort = TRUE;
      } else {
        if (ResetRequired != NULL) {
          *ResetRequired |= ResetRequiredBuffer[Index2];
        }
      }

      RecordFmpCapsuleStatus (
        HandleBuffer[Index2],
        CapsuleHeader,
        Status,
        Index - FmpCapsuleHeader->EmbeddedDriverCount,
        ImageHeader,
        CapFileName
        );
    }
    if (HandleBuffer != NULL) {
      FreePool(HandleBuffer);
    }
    if (ResetRequiredBuffer != NULL) {
      FreePool(ResetRequiredBuffer);
    }
  }

  if (NotReady) {
    return EFI_NOT_READY;
  }

  //
  // always return SUCCESS to indicate this capsule is processed.
  // The status of SetImage is recorded in capsule result variable.
  //
  return EFI_SUCCESS;
}

/**
  Return if there is a FMP header below capsule header.

  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER

  @retval TRUE  There is a FMP header below capsule header.
  @retval FALSE There is not a FMP header below capsule header
**/
BOOLEAN
IsNestedFmpCapsule (
  IN EFI_CAPSULE_HEADER         *CapsuleHeader
  )
{
  EFI_STATUS                 Status;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;
  UINTN                      Index;
  BOOLEAN                    EsrtGuidFound;
  EFI_CAPSULE_HEADER         *NestedCapsuleHeader;
  UINTN                      NestedCapsuleSize;
  ESRT_MANAGEMENT_PROTOCOL   *EsrtProtocol;
  EFI_SYSTEM_RESOURCE_ENTRY  Entry;

  EsrtGuidFound = FALSE;
  if (mIsVirtualAddrConverted) {
    if(mEsrtTable != NULL) {
      EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
      for (Index = 0; Index < mEsrtTable->FwResourceCount ; Index++, EsrtEntry++) {
        if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
          EsrtGuidFound = TRUE;
          break;
        }
      }
    }
  } else {
    //
    // Check ESRT protocol
    //
    Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);
    if (!EFI_ERROR(Status)) {
      Status = EsrtProtocol->GetEsrtEntry(&CapsuleHeader->CapsuleGuid, &Entry);
      if (!EFI_ERROR(Status)) {
        EsrtGuidFound = TRUE;
      }
    }

    //
    // Check Firmware Management Protocols
    //
    if (!EsrtGuidFound) {
      Status = GetFmpHandleBufferByType (
                 &CapsuleHeader->CapsuleGuid,
                 0,
                 NULL,
                 NULL,
                 NULL
                 );
      if (!EFI_ERROR(Status)) {
        EsrtGuidFound = TRUE;
      }
    }
  }
  if (!EsrtGuidFound) {
    return FALSE;
  }

  //
  // Check nested capsule header
  // FMP GUID after ESRT one
  //
  NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
  NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize - (UINTN)NestedCapsuleHeader;
  if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {
    return FALSE;
  }
  if (!IsValidCapsuleHeader(NestedCapsuleHeader, NestedCapsuleSize)) {
    return FALSE;
  }
  if (!IsFmpCapsuleGuid(&NestedCapsuleHeader->CapsuleGuid)) {
    return FALSE;
  }
  DEBUG ((DEBUG_INFO, "IsNestedFmpCapsule\n"));
  return TRUE;
}

/**
  Return if this FMP is a system FMP or a device FMP, based upon CapsuleHeader.

  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER

  @retval TRUE  It is a system FMP.
  @retval FALSE It is a device FMP.
**/
BOOLEAN
IsFmpCapsule (
  IN EFI_CAPSULE_HEADER         *CapsuleHeader
  )
{
  if (IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {
    return TRUE;
  }
  if (IsNestedFmpCapsule(CapsuleHeader)) {
    return TRUE;
  }
  return FALSE;
}

/**
  Those capsules supported by the firmwares.

  Caution: This function may receive untrusted input.

  @param[in]  CapsuleHeader    Points to a capsule header.

  @retval EFI_SUCESS       Input capsule is supported by firmware.
  @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.
  @retval EFI_INVALID_PARAMETER Input capsule layout is not correct
**/
EFI_STATUS
EFIAPI
SupportCapsuleImage (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  //
  // check Display Capsule Guid
  //
  if (CompareGuid (&gWindowsUxCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {
    return EFI_SUCCESS;
  }

  //
  // Check capsule file name capsule
  //
  if (IsCapsuleNameCapsule(CapsuleHeader)) {
    return EFI_SUCCESS;
  }

  if (IsFmpCapsule(CapsuleHeader)) {
    //
    // Fake capsule header is valid case in QueryCapsuleCpapbilities().
    //
    if (CapsuleHeader->HeaderSize == CapsuleHeader->CapsuleImageSize) {
      return EFI_SUCCESS;
    }
    //
    // Check layout of FMP capsule
    //
    return ValidateFmpCapsule(CapsuleHeader, NULL);
  }
  DEBUG((DEBUG_ERROR, "Unknown Capsule Guid - %g\n", &CapsuleHeader->CapsuleGuid));
  return EFI_UNSUPPORTED;
}

/**
  The firmware implements to process the capsule image.

  Caution: This function may receive untrusted input.

  @param[in]  CapsuleHeader         Points to a capsule header.
  @param[in]  CapFileName           Capsule file name.
  @param[out] ResetRequired         Indicates whether reset is required or not.

  @retval EFI_SUCESS            Process Capsule Image successfully.
  @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.
  @retval EFI_VOLUME_CORRUPTED  FV volume in the capsule is corrupted.
  @retval EFI_OUT_OF_RESOURCES  Not enough memory.
**/
EFI_STATUS
EFIAPI
ProcessThisCapsuleImage (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader,
  IN CHAR16              *CapFileName,  OPTIONAL
  OUT BOOLEAN            *ResetRequired OPTIONAL
  )
{
  EFI_STATUS                   Status;

  if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) {
    RecordCapsuleStatusVariable(CapsuleHeader, EFI_UNSUPPORTED);
    return EFI_UNSUPPORTED;
  }

  //
  // Display image in firmware update display capsule
  //
  if (CompareGuid (&gWindowsUxCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {
    DEBUG((DEBUG_INFO, "ProcessCapsuleImage for WindowsUxCapsule ...\n"));
    Status = DisplayCapsuleImage(CapsuleHeader);
    RecordCapsuleStatusVariable(CapsuleHeader, Status);
    return Status;
  }

  //
  // Check FMP capsule layout
  //
  if (IsFmpCapsule (CapsuleHeader)) {
    DEBUG((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));
    DEBUG((DEBUG_INFO, "ValidateFmpCapsule ...\n"));
    Status = ValidateFmpCapsule(CapsuleHeader, NULL);
    DEBUG((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));
    if (EFI_ERROR(Status)) {
      RecordCapsuleStatusVariable(CapsuleHeader, Status);
      return Status;
    }

    //
    // Process EFI FMP Capsule
    //
    DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));
    Status = ProcessFmpCapsuleImage(CapsuleHeader, CapFileName, ResetRequired);
    DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));

    return Status;
  }

  return EFI_UNSUPPORTED;
}

/**
  The firmware implements to process the capsule image.

  Caution: This function may receive untrusted input.

  @param[in]  CapsuleHeader         Points to a capsule header.

  @retval EFI_SUCESS            Process Capsule Image successfully.
  @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.
  @retval EFI_VOLUME_CORRUPTED  FV volume in the capsule is corrupted.
  @retval EFI_OUT_OF_RESOURCES  Not enough memory.
**/
EFI_STATUS
EFIAPI
ProcessCapsuleImage (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  return ProcessThisCapsuleImage (CapsuleHeader, NULL, NULL);
}

/**
  Callback function executed when the EndOfDxe event group is signaled.

  @param[in] Event      Event whose notification function is being invoked.
  @param[in] Context    The pointer to the notification function's context, which
                        is implementation-dependent.
**/
VOID
EFIAPI
DxeCapsuleLibEndOfDxe (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  mDxeCapsuleLibEndOfDxe = TRUE;
}

/**
  The constructor function.

  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
  @param[in]  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor successfully .
**/
EFI_STATUS
EFIAPI
DxeCapsuleLibConstructor (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS    Status;

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  DxeCapsuleLibEndOfDxe,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &mDxeCapsuleLibEndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  InitCapsuleVariable();

  return EFI_SUCCESS;
}

/**
  The destructor function closes the End of DXE event.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The destructor completed successfully.
**/
EFI_STATUS
EFIAPI
DxeCapsuleLibDestructor (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS    Status;

  //
  // Close the End of DXE event.
  //
  Status = gBS->CloseEvent (mDxeCapsuleLibEndOfDxeEvent);
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
