/** @file
  Dump Capsule image information.

  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "CapsuleApp.h"

/**
  Validate if it is valid capsule header

  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
  );

/**
  Dump UX capsule information.

  @param[in] CapsuleHeader      The UX capsule header
**/
VOID
DumpUxCapsule (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  EFI_DISPLAY_CAPSULE  *DisplayCapsule;

  DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;
  Print (L"[UxCapsule]\n");
  Print (L"CapsuleHeader:\n");
  Print (L"  CapsuleGuid      - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);
  Print (L"  HeaderSize       - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);
  Print (L"  Flags            - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);
  Print (L"  CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);
  Print (L"ImagePayload:\n");
  Print (L"  Version          - 0x%x\n", DisplayCapsule->ImagePayload.Version);
  Print (L"  Checksum         - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);
  Print (L"  ImageType        - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);
  Print (L"  Mode             - 0x%x\n", DisplayCapsule->ImagePayload.Mode);
  Print (L"  OffsetX          - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);
  Print (L"  OffsetY          - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);
}

/**
  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;
  UINT64                                        *ItemOffsetList;
  UINTN                                         Index;
  UINTN                                         Count;
  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *FmpImageHeader;

  Print (L"[FmpCapsule]\n");
  Print (L"CapsuleHeader:\n");
  Print (L"  CapsuleGuid      - %g\n", &CapsuleHeader->CapsuleGuid);
  Print (L"  HeaderSize       - 0x%x\n", CapsuleHeader->HeaderSize);
  Print (L"  Flags            - 0x%x\n", CapsuleHeader->Flags);
  Print (L"  CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);

  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
  ItemOffsetList   = (UINT64 *)(FmpCapsuleHeader + 1);
  Print (L"FmpHeader:\n");
  Print (L"  Version             - 0x%x\n", FmpCapsuleHeader->Version);
  Print (L"  EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);
  Print (L"  PayloadItemCount    - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);
  Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
  for (Index = 0; Index < Count; Index++) {
    Print (L"  Offset[%d]           - 0x%x\n", Index, ItemOffsetList[Index]);
  }

  for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {
    Print (L"FmpPayload[%d] ImageHeader:\n", Index);
    FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
    Print (L"  Version                - 0x%x\n", FmpImageHeader->Version);
    Print (L"  UpdateImageTypeId      - %g\n", &FmpImageHeader->UpdateImageTypeId);
    Print (L"  UpdateImageIndex       - 0x%x\n", FmpImageHeader->UpdateImageIndex);
    Print (L"  UpdateImageSize        - 0x%x\n", FmpImageHeader->UpdateImageSize);
    Print (L"  UpdateVendorCodeSize   - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);
    if (FmpImageHeader->Version >= 2) {
      Print (L"  UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);
      if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
        Print (L"  ImageCapsuleSupport    - 0x%lx\n", FmpImageHeader->ImageCapsuleSupport);
      }
    }
  }
}

/**
  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_TABLE  *Esrt;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;
  UINTN                      Index;
  BOOLEAN                    EsrtGuidFound;
  EFI_CAPSULE_HEADER         *NestedCapsuleHeader;
  UINTN                      NestedCapsuleSize;

  //
  // Check ESRT
  //
  EsrtGuidFound = FALSE;
  Status        = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
  if (!EFI_ERROR (Status)) {
    ASSERT (Esrt != NULL);
    EsrtEntry = (VOID *)(Esrt + 1);
    for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {
      if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
        EsrtGuidFound = TRUE;
        break;
      }
    }
  }

  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 (!CompareGuid (&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
    return FALSE;
  }

  return TRUE;
}

/**
  Dump capsule information

  @param[in] CapsuleName  The name of the capsule image.

  @retval EFI_SUCCESS            The capsule information is dumped.
  @retval EFI_UNSUPPORTED        Input parameter is not valid.
**/
EFI_STATUS
DumpCapsule (
  IN CHAR16  *CapsuleName
  )
{
  VOID                *Buffer;
  UINTN               FileSize;
  EFI_CAPSULE_HEADER  *CapsuleHeader;
  EFI_STATUS          Status;

  Buffer = NULL;
  Status = ReadFileToBuffer (CapsuleName, &FileSize, &Buffer);
  if (EFI_ERROR (Status)) {
    Print (L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);
    goto Done;
  }

  if (!IsValidCapsuleHeader (Buffer, FileSize)) {
    Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  CapsuleHeader = Buffer;
  if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {
    DumpUxCapsule (CapsuleHeader);
    Status = EFI_SUCCESS;
    goto Done;
  }

  if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
    DumpFmpCapsule (CapsuleHeader);
  }

  if (IsNestedFmpCapsule (CapsuleHeader)) {
    Print (L"[NestedCapsule]\n");
    Print (L"CapsuleHeader:\n");
    Print (L"  CapsuleGuid      - %g\n", &CapsuleHeader->CapsuleGuid);
    Print (L"  HeaderSize       - 0x%x\n", CapsuleHeader->HeaderSize);
    Print (L"  Flags            - 0x%x\n", CapsuleHeader->Flags);
    Print (L"  CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);
    DumpFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));
  }

Done:
  if (Buffer != NULL) {
    FreePool (Buffer);
  }

  return Status;
}

/**
  Dump capsule status variable.

  @retval EFI_SUCCESS            The capsule status variable is dumped.
  @retval EFI_UNSUPPORTED        Input parameter is not valid.
**/
EFI_STATUS
DumpCapsuleStatusVariable (
  VOID
  )
{
  EFI_STATUS                          Status;
  UINT32                              Index;
  CHAR16                              CapsuleVarName[20];
  CHAR16                              *TempVarName;
  EFI_CAPSULE_RESULT_VARIABLE_HEADER  *CapsuleResult;
  EFI_CAPSULE_RESULT_VARIABLE_FMP     *CapsuleResultFmp;
  UINTN                               CapsuleFileNameSize;
  CHAR16                              CapsuleIndexData[12];
  CHAR16                              *CapsuleIndex;
  CHAR16                              *CapsuleFileName;
  CHAR16                              *CapsuleTarget;

  Status = GetVariable2 (
             L"CapsuleMax",
             &gEfiCapsuleReportGuid,
             (VOID **)&CapsuleIndex,
             NULL
             );
  if (!EFI_ERROR (Status)) {
    ASSERT (CapsuleIndex != NULL);
    CopyMem (CapsuleIndexData, CapsuleIndex, 11 * sizeof (CHAR16));
    CapsuleIndexData[11] = 0;
    Print (L"CapsuleMax - %s\n", CapsuleIndexData);
    FreePool (CapsuleIndex);
  }

  Status = GetVariable2 (
             L"CapsuleLast",
             &gEfiCapsuleReportGuid,
             (VOID **)&CapsuleIndex,
             NULL
             );
  if (!EFI_ERROR (Status)) {
    ASSERT (CapsuleIndex != NULL);
    CopyMem (CapsuleIndexData, CapsuleIndex, 11 * sizeof (CHAR16));
    CapsuleIndexData[11] = 0;
    Print (L"CapsuleLast - %s\n", CapsuleIndexData);
    FreePool (CapsuleIndex);
  }

  StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CapsuleVarName[0]), L"Capsule");
  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
  Index       = 0;

  while (TRUE) {
    UnicodeSPrint (TempVarName, 5 * sizeof (CHAR16), L"%04x", Index);

    Status = GetVariable2 (
               CapsuleVarName,
               &gEfiCapsuleReportGuid,
               (VOID **)&CapsuleResult,
               NULL
               );
    if (Status == EFI_NOT_FOUND) {
      break;
    } else if (EFI_ERROR (Status)) {
      continue;
    }

    ASSERT (CapsuleResult != NULL);

    //
    // display capsule process status
    //
    if (CapsuleResult->VariableTotalSize >= sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {
      Print (L"CapsuleName: %s\n", CapsuleVarName);
      Print (L"  Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);
      Print (L"  Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);
      Print (L"  Capsule Status: %r\n", CapsuleResult->CapsuleStatus);
    }

    if (CompareGuid (&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
      if (CapsuleResult->VariableTotalSize >= sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof (EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof (CHAR16) * 2) {
        CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);
        Print (L"  Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);
        Print (L"  Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);
        Print (L"  Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);
        Print (L"  Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);
        CapsuleFileName = (CHAR16 *)(CapsuleResultFmp + 1);
        Print (L"  Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName);
        CapsuleFileNameSize = StrSize (CapsuleFileName);
        CapsuleTarget       = (CHAR16 *)((UINTN)CapsuleFileName + CapsuleFileNameSize);
        Print (L"  Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget);
      }
    }

    FreePool (CapsuleResult);

    Index++;
    if (Index > 0xFFFF) {
      break;
    }
  }

  return EFI_SUCCESS;
}

CHAR8  *mFwTypeString[] = {
  "Unknown",
  "SystemFirmware",
  "DeviceFirmware",
  "UefiDriver",
};

CHAR8  *mLastAttemptStatusString[] = {
  "Success",
  "Error: Unsuccessful",
  "Error: Insufficient Resources",
  "Error: Incorrect Version",
  "Error: Invalid Format",
  "Error: Auth Error",
  "Error: Power Event AC",
  "Error: Power Event Battery",
  "Error: Unsatisfied Dependencies",
};

/**
  Convert FwType to a string.

  @param[in] FwType  FwType in ESRT

  @return a string for FwType.
**/
CHAR8 *
FwTypeToString (
  IN UINT32  FwType
  )
{
  if (FwType < sizeof (mFwTypeString) / sizeof (mFwTypeString[0])) {
    return mFwTypeString[FwType];
  } else {
    return "Invalid";
  }
}

/**
  Convert LastAttemptStatus to a string.

  @param[in] LastAttemptStatus  LastAttemptStatus in FMP or ESRT

  @return a string for LastAttemptStatus.
**/
CHAR8 *
LastAttemptStatusToString (
  IN UINT32  LastAttemptStatus
  )
{
  if (LastAttemptStatus < sizeof (mLastAttemptStatusString) / sizeof (mLastAttemptStatusString[0])) {
    return mLastAttemptStatusString[LastAttemptStatus];
  } else {
    return "Error: Unknown";
  }
}

/**
  Dump ESRT entry.

  @param[in] EsrtEntry  ESRT entry
**/
VOID
DumpEsrtEntry (
  IN EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry
  )
{
  Print (L"  FwClass                  - %g\n", &EsrtEntry->FwClass);
  Print (L"  FwType                   - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString (EsrtEntry->FwType));
  Print (L"  FwVersion                - 0x%x\n", EsrtEntry->FwVersion);
  Print (L"  LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);
  Print (L"  CapsuleFlags             - 0x%x\n", EsrtEntry->CapsuleFlags);
  Print (L"  LastAttemptVersion       - 0x%x\n", EsrtEntry->LastAttemptVersion);
  Print (L"  LastAttemptStatus        - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString (EsrtEntry->LastAttemptStatus));
}

/**
  Dump ESRT table.

  @param[in] Esrt  ESRT table
**/
VOID
DumpEsrt (
  IN EFI_SYSTEM_RESOURCE_TABLE  *Esrt
  )
{
  UINTN                      Index;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;

  if (Esrt == NULL) {
    return;
  }

  Print (L"EFI_SYSTEM_RESOURCE_TABLE:\n");
  Print (L"FwResourceCount    - 0x%x\n", Esrt->FwResourceCount);
  Print (L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);
  Print (L"FwResourceVersion  - 0x%lx\n", Esrt->FwResourceVersion);

  EsrtEntry = (VOID *)(Esrt + 1);
  for (Index = 0; Index < Esrt->FwResourceCount; Index++) {
    Print (L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);
    DumpEsrtEntry (EsrtEntry);
    EsrtEntry++;
  }
}

/**
  Dump ESRT info.
**/
VOID
DumpEsrtData (
  VOID
  )
{
  EFI_STATUS                 Status;
  EFI_SYSTEM_RESOURCE_TABLE  *Esrt;

  Print (L"##############\n");
  Print (L"# ESRT TABLE #\n");
  Print (L"##############\n");

  Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
  if (EFI_ERROR (Status)) {
    Print (L"ESRT - %r\n", Status);
    return;
  }

  DumpEsrt (Esrt);
  Print (L"\n");
}

/**
  Dump capsule information from CapsuleHeader

  @param[in] CapsuleHeader       The CapsuleHeader of the capsule image.

  @retval EFI_SUCCESS            The capsule information is dumped.

**/
EFI_STATUS
DumpCapsuleFromBuffer (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {
    DumpUxCapsule (CapsuleHeader);
    return EFI_SUCCESS;
  }

  if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
    DumpFmpCapsule (CapsuleHeader);
  }

  if (IsNestedFmpCapsule (CapsuleHeader)) {
    Print (L"[NestedCapusule]\n");
    Print (L"CapsuleHeader:\n");
    Print (L"  CapsuleGuid      - %g\n", &CapsuleHeader->CapsuleGuid);
    Print (L"  HeaderSize       - 0x%x\n", CapsuleHeader->HeaderSize);
    Print (L"  Flags            - 0x%x\n", CapsuleHeader->Flags);
    Print (L"  CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);
    DumpFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));
  }

  return EFI_SUCCESS;
}

/**
  This routine is called to upper case given unicode string.

  @param[in]   Str              String to upper case

  @retval upper cased string after process

**/
STATIC
CHAR16 *
UpperCaseString (
  IN CHAR16  *Str
  )
{
  CHAR16  *Cptr;

  for (Cptr = Str; *Cptr != L'\0'; Cptr++) {
    if ((L'a' <= *Cptr) && (*Cptr <= L'z')) {
      *Cptr = *Cptr - L'a' + L'A';
    }
  }

  return Str;
}

/**
  This routine is used to return substring before period '.' or '\0'
  Caller should respsonsible of substr space allocation & free

  @param[in]   Str              String to check
  @param[out]  SubStr           First part of string before period or '\0'
  @param[out]  SubStrLen        Length of first part of string

**/
STATIC
VOID
GetSubStringBeforePeriod (
  IN  CHAR16  *Str,
  OUT CHAR16  *SubStr,
  OUT UINTN   *SubStrLen
  )
{
  UINTN  Index;

  for (Index = 0; Str[Index] != L'.' && Str[Index] != L'\0'; Index++) {
    SubStr[Index] = Str[Index];
  }

  SubStr[Index] = L'\0';
  *SubStrLen    = Index;
}

/**
  This routine pad the string in tail with input character.

  @param[in]   StrBuf            Str buffer to be padded, should be enough room for
  @param[in]   PadLen            Expected padding length
  @param[in]   Character         Character used to pad

**/
STATIC
VOID
PadStrInTail (
  IN CHAR16  *StrBuf,
  IN UINTN   PadLen,
  IN CHAR16  Character
  )
{
  UINTN  Index;

  for (Index = 0; StrBuf[Index] != L'\0'; Index++) {
  }

  while (PadLen != 0) {
    StrBuf[Index] = Character;
    Index++;
    PadLen--;
  }

  StrBuf[Index] = L'\0';
}

/**
  This routine find the offset of the last period '.' of string. if No period exists
  function FileNameExtension is set to L'\0'

  @param[in]   FileName           File name to split between last period
  @param[out]  FileNameFirst      First FileName before last period
  @param[out]  FileNameExtension  FileName after last period

**/
STATIC
VOID
SplitFileNameExtension (
  IN  CHAR16  *FileName,
  OUT CHAR16  *FileNameFirst,
  OUT CHAR16  *FileNameExtension
  )
{
  UINTN  Index;
  UINTN  StringLen;

  StringLen = StrLen (FileName);
  for (Index = StringLen; Index > 0 && FileName[Index] != L'.'; Index--) {
  }

  //
  // No period exists. No FileName Extension
  //
  if ((Index == 0) && (FileName[Index] != L'.')) {
    FileNameExtension[0] = L'\0';
    Index                = StringLen;
  } else {
    StrCpyS (FileNameExtension, MAX_FILE_NAME_LEN, &FileName[Index+1]);
  }

  //
  // Copy First file name
  //
  StrnCpyS (FileNameFirst, MAX_FILE_NAME_LEN, FileName, Index);
  FileNameFirst[Index] = L'\0';
}

/**
  The function is called by PerformQuickSort to sort file name in alphabet.

  @param[in] Left            The pointer to first buffer.
  @param[in] Right           The pointer to second buffer.

  @retval 0                  Buffer1 equal to Buffer2.
  @return <0                 Buffer1 is less than Buffer2.
  @return >0                 Buffer1 is greater than Buffer2.

**/
INTN
CompareFileNameInAlphabet (
  IN VOID  *Left,
  IN VOID  *Right
  )
{
  EFI_FILE_INFO  *FileInfo1;
  EFI_FILE_INFO  *FileInfo2;
  CHAR16         FileName1[MAX_FILE_NAME_SIZE];
  CHAR16         FileExtension1[MAX_FILE_NAME_SIZE];
  CHAR16         FileName2[MAX_FILE_NAME_SIZE];
  CHAR16         FileExtension2[MAX_FILE_NAME_SIZE];
  CHAR16         TempSubStr1[MAX_FILE_NAME_SIZE];
  CHAR16         TempSubStr2[MAX_FILE_NAME_SIZE];
  UINTN          SubStrLen1;
  UINTN          SubStrLen2;
  INTN           SubStrCmpResult;

  FileInfo1 = (EFI_FILE_INFO *)(*(UINTN *)Left);
  FileInfo2 = (EFI_FILE_INFO *)(*(UINTN *)Right);

  SplitFileNameExtension (FileInfo1->FileName, FileName1, FileExtension1);
  SplitFileNameExtension (FileInfo2->FileName, FileName2, FileExtension2);

  UpperCaseString (FileName1);
  UpperCaseString (FileName2);

  GetSubStringBeforePeriod (FileName1, TempSubStr1, &SubStrLen1);
  GetSubStringBeforePeriod (FileName2, TempSubStr2, &SubStrLen2);

  if (SubStrLen1 > SubStrLen2) {
    //
    // Substr in NewFileName is longer.  Pad tail with SPACE
    //
    PadStrInTail (TempSubStr2, SubStrLen1 - SubStrLen2, L' ');
  } else if (SubStrLen1 < SubStrLen2) {
    //
    // Substr in ListedFileName is longer. Pad tail with SPACE
    //
    PadStrInTail (TempSubStr1, SubStrLen2 - SubStrLen1, L' ');
  }

  SubStrCmpResult = StrnCmp (TempSubStr1, TempSubStr2, MAX_FILE_NAME_LEN);
  if (SubStrCmpResult != 0) {
    return SubStrCmpResult;
  }

  UpperCaseString (FileExtension1);
  UpperCaseString (FileExtension2);

  return StrnCmp (FileExtension1, FileExtension2, MAX_FILE_NAME_LEN);
}

/**
  Dump capsule information from disk.

  @param[in] Fs                  The device path of disk.
  @param[in] DumpCapsuleInfo     The flag to indicate whether to dump the capsule inforomation.

  @retval EFI_SUCCESS            The capsule information is dumped.

**/
EFI_STATUS
DumpCapsuleFromDisk (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs,
  IN BOOLEAN                          DumpCapsuleInfo
  )
{
  EFI_STATUS     Status;
  EFI_FILE       *Root;
  EFI_FILE       *DirHandle;
  EFI_FILE       *FileHandle;
  UINTN          Index;
  UINTN          FileSize;
  VOID           *FileBuffer;
  EFI_FILE_INFO  **FileInfoBuffer;
  EFI_FILE_INFO  *FileInfo;
  UINTN          FileCount;
  BOOLEAN        NoFile;

  DirHandle      = NULL;
  FileHandle     = NULL;
  Index          = 0;
  FileInfoBuffer = NULL;
  FileInfo       = NULL;
  FileCount      = 0;
  NoFile         = FALSE;

  Status = Fs->OpenVolume (Fs, &Root);
  if (EFI_ERROR (Status)) {
    Print (L"Cannot open volume. Status = %r\n", Status);
    goto Done;
  }

  Status = Root->Open (Root, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
  if (EFI_ERROR (Status)) {
    Print (L"Cannot open %s. Status = %r\n", EFI_CAPSULE_FILE_DIRECTORY, Status);
    goto Done;
  }

  //
  // Get file count first
  //
  Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
  do {
    if (EFI_ERROR (Status) || (FileInfo == NULL)) {
      Print (L"Get File Info Fail. Status = %r\n", Status);
      goto Done;
    }

    if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {
      FileCount++;
    }

    Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);
    if (EFI_ERROR (Status)) {
      Print (L"Get Next File Fail. Status = %r\n", Status);
      goto Done;
    }
  } while (!NoFile);

  if (FileCount == 0) {
    Print (L"Error: No capsule file found!\n");
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  FileInfoBuffer = AllocateZeroPool (sizeof (FileInfo) * FileCount);
  if (FileInfoBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  NoFile = FALSE;

  //
  // Get all file info
  //
  Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
  do {
    if (EFI_ERROR (Status) || (FileInfo == NULL)) {
      Print (L"Get File Info Fail. Status = %r\n", Status);
      goto Done;
    }

    if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {
      FileInfoBuffer[Index++] = AllocateCopyPool ((UINTN)FileInfo->Size, FileInfo);
    }

    Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);
    if (EFI_ERROR (Status)) {
      Print (L"Get Next File Fail. Status = %r\n", Status);
      goto Done;
    }
  } while (!NoFile);

  //
  // Sort FileInfoBuffer by alphabet order
  //
  PerformQuickSort (
    FileInfoBuffer,
    FileCount,
    sizeof (FileInfo),
    (SORT_COMPARE)CompareFileNameInAlphabet
    );

  Print (L"The capsules will be performed by following order:\n");

  for (Index = 0; Index < FileCount; Index++) {
    Print (L"  %d.%s\n", Index + 1, FileInfoBuffer[Index]->FileName);
  }

  if (!DumpCapsuleInfo) {
    Status = EFI_SUCCESS;
    goto Done;
  }

  Print (L"The infomation of the capsules:\n");

  for (Index = 0; Index < FileCount; Index++) {
    FileHandle = NULL;
    Status     = DirHandle->Open (DirHandle, &FileHandle, FileInfoBuffer[Index]->FileName, EFI_FILE_MODE_READ, 0);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    Status = FileHandleGetSize (FileHandle, (UINT64 *)&FileSize);
    if (EFI_ERROR (Status)) {
      Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);
      FileHandleClose (FileHandle);
      goto Done;
    }

    FileBuffer = AllocatePool (FileSize);
    if (FileBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
    if (EFI_ERROR (Status)) {
      Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);
      FileHandleClose (FileHandle);
      FreePool (FileBuffer);
      goto Done;
    }

    Print (L"**************************\n");
    Print (L"  %d.%s:\n", Index + 1, FileInfoBuffer[Index]->FileName);
    Print (L"**************************\n");
    DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *)FileBuffer);
    FileHandleClose (FileHandle);
    FreePool (FileBuffer);
  }

Done:
  if (FileInfoBuffer != NULL) {
    for (Index = 0; Index < FileCount; Index++) {
      if (FileInfoBuffer[Index] != NULL) {
        FreePool (FileInfoBuffer[Index]);
      }
    }

    FreePool (FileInfoBuffer);
  }

  return Status;
}

/**
  Dump capsule inforomation form Gather list.

  @param[in]  BlockDescriptors The block descriptors for the capsule images
  @param[in]  DumpCapsuleInfo  The flag to indicate whether to dump the capsule inforomation.

**/
VOID
DumpBlockDescriptors (
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptors,
  IN BOOLEAN                       DumpCapsuleInfo
  )
{
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *TempBlockPtr;

  TempBlockPtr = BlockDescriptors;

  while (TRUE) {
    if (TempBlockPtr->Length != 0) {
      if (DumpCapsuleInfo) {
        Print (L"******************************************************\n");
      }

      Print (L"Capsule data starts at 0x%08x with size 0x%08x\n", TempBlockPtr->Union.DataBlock, TempBlockPtr->Length);
      if (DumpCapsuleInfo) {
        Print (L"******************************************************\n");
        DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *)(UINTN)TempBlockPtr->Union.DataBlock);
      }

      TempBlockPtr += 1;
    } else {
      if (TempBlockPtr->Union.ContinuationPointer == (UINTN)NULL) {
        break;
      } else {
        TempBlockPtr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)TempBlockPtr->Union.ContinuationPointer;
      }
    }
  }
}

/**
  Dump Provisioned Capsule.

  @param[in]  DumpCapsuleInfo  The flag to indicate whether to dump the capsule inforomation.

**/
VOID
DumpProvisionedCapsule (
  IN BOOLEAN  DumpCapsuleInfo
  )
{
  EFI_STATUS                       Status;
  CHAR16                           CapsuleVarName[30];
  CHAR16                           *TempVarName;
  UINTN                            Index;
  EFI_PHYSICAL_ADDRESS             *CapsuleDataPtr64;
  UINT16                           *BootNext;
  CHAR16                           BootOptionName[20];
  EFI_BOOT_MANAGER_LOAD_OPTION     BootNextOptionEntry;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
  EFI_SHELL_PROTOCOL               *ShellProtocol;

  Index            = 0;
  CapsuleDataPtr64 = NULL;
  BootNext         = NULL;

  ShellProtocol = GetShellProtocol ();
  if (ShellProtocol == NULL) {
    Print (L"Get Shell Protocol Fail\n");
    return;
  }

  //
  // Dump capsule provisioned on Memory
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Memory ###\n");
  Print (L"#########################\n");
  StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
  while (TRUE) {
    if (Index > 0) {
      UnicodeValueToStringS (
        TempVarName,
        sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
        0,
        Index,
        0
        );
    }

    Status = GetVariable2 (
               CapsuleVarName,
               &gEfiCapsuleVendorGuid,
               (VOID **)&CapsuleDataPtr64,
               NULL
               );
    if (EFI_ERROR (Status) || (CapsuleDataPtr64 == NULL)) {
      if (Index == 0) {
        Print (L"No data.\n");
      }

      break;
    }

    Index++;
    Print (L"Capsule Description at 0x%08x\n", *CapsuleDataPtr64);
    DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)*CapsuleDataPtr64, DumpCapsuleInfo);
  }

  //
  // Dump capsule provisioned on Disk
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Disk #####\n");
  Print (L"#########################\n");
  Status = GetVariable2 (
             L"BootNext",
             &gEfiGlobalVariableGuid,
             (VOID **)&BootNext,
             NULL
             );
  if (EFI_ERROR (Status) || (BootNext == NULL)) {
    Print (L"Get BootNext Variable Fail. Status = %r\n", Status);
  } else {
    UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNext);
    Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry);
    if (!EFI_ERROR (Status)) {
      //
      // Display description and device path
      //
      GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry.FilePath, &DevicePath, &Fs);
      if (!EFI_ERROR (Status)) {
        Print (L"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry.Description);
        Print (L"    %s %s\n", ShellProtocol->GetMapFromDevicePath (&DevicePath), ConvertDevicePathToText (DevicePath, TRUE, TRUE));
        DumpCapsuleFromDisk (Fs, DumpCapsuleInfo);
      }
    }
  }
}

/**
  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;
  UINTN                          Index2;

  Print (L"  DescriptorVersion  - 0x%x\n", DescriptorVersion);
  Print (L"  DescriptorCount    - 0x%x\n", DescriptorCount);
  Print (L"  DescriptorSize     - 0x%x\n", DescriptorSize);
  Print (L"  PackageVersion     - 0x%x\n", PackageVersion);
  Print (L"  PackageVersionName - \"%s\"\n", PackageVersionName);
  CurrentImageInfo = ImageInfo;
  for (Index = 0; Index < DescriptorCount; Index++) {
    Print (L"  ImageDescriptor (%d)\n", Index);
    Print (L"    ImageIndex                  - 0x%x\n", CurrentImageInfo->ImageIndex);
    Print (L"    ImageTypeId                 - %g\n", &CurrentImageInfo->ImageTypeId);
    Print (L"    ImageId                     - 0x%lx\n", CurrentImageInfo->ImageId);
    Print (L"    ImageIdName                 - \"%s\"\n", CurrentImageInfo->ImageIdName);
    Print (L"    Version                     - 0x%x\n", CurrentImageInfo->Version);
    Print (L"    VersionName                 - \"%s\"\n", CurrentImageInfo->VersionName);
    Print (L"    Size                        - 0x%x\n", CurrentImageInfo->Size);
    Print (L"    AttributesSupported         - 0x%lx\n", CurrentImageInfo->AttributesSupported);
    Print (L"      IMAGE_UPDATABLE           - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
    Print (L"      RESET_REQUIRED            - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
    Print (L"      AUTHENTICATION_REQUIRED   - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
    Print (L"      IN_USE                    - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);
    Print (L"      UEFI_IMAGE                - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);
    Print (L"    AttributesSetting           - 0x%lx\n", CurrentImageInfo->AttributesSetting);
    Print (L"      IMAGE_UPDATABLE           - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
    Print (L"      RESET_REQUIRED            - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
    Print (L"      AUTHENTICATION_REQUIRED   - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
    Print (L"      IN_USE                    - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);
    Print (L"      UEFI_IMAGE                - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);
    Print (L"    Compatibilities             - 0x%lx\n", CurrentImageInfo->Compatibilities);
    Print (L"      COMPATIB_CHECK_SUPPORTED  - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);
    if (DescriptorVersion > 1) {
      Print (L"    LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);
      if (DescriptorVersion > 2) {
        Print (L"    LastAttemptVersion          - 0x%x\n", CurrentImageInfo->LastAttemptVersion);
        Print (L"    LastAttemptStatus           - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString (CurrentImageInfo->LastAttemptStatus));
        Print (L"    HardwareInstance            - 0x%lx\n", CurrentImageInfo->HardwareInstance);
        if (DescriptorVersion > 3) {
          Print (L"    Dependencies                - ");
          if (CurrentImageInfo->Dependencies == NULL) {
            Print (L"NULL\n");
          } else {
            Index2 = 0;
            do {
              Print (L"%02x ", CurrentImageInfo->Dependencies->Dependencies[Index2]);
            } while (CurrentImageInfo->Dependencies->Dependencies[Index2++] != EFI_FMP_DEP_END);

            Print (L"\n");
          }
        }
      }
    }

    //
    // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
    //
    CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
  }
}

/**
  Dump FMP package information.

  @param[in] PackageVersion             The version of package.
  @param[in] PackageVersionName         The version name of package.
  @param[in] PackageVersionNameMaxLen   The maximum length of PackageVersionName.
  @param[in] AttributesSupported        Package attributes that are supported by this device.
  @param[in] AttributesSetting          Package attributes.
**/
VOID
DumpFmpPackageInfo (
  IN UINT32  PackageVersion,
  IN CHAR16  *PackageVersionName,
  IN UINT32  PackageVersionNameMaxLen,
  IN UINT64  AttributesSupported,
  IN UINT64  AttributesSetting
  )
{
  Print (L"  PackageVersion              - 0x%x\n", PackageVersion);
  Print (L"  PackageVersionName          - \"%s\"\n", PackageVersionName);
  Print (L"  PackageVersionNameMaxLen    - 0x%x\n", PackageVersionNameMaxLen);
  Print (L"  AttributesSupported         - 0x%lx\n", AttributesSupported);
  Print (L"    IMAGE_UPDATABLE           - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
  Print (L"    RESET_REQUIRED            - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
  Print (L"    AUTHENTICATION_REQUIRED   - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
  Print (L"  AttributesSetting           - 0x%lx\n", AttributesSetting);
  Print (L"    IMAGE_UPDATABLE           - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
  Print (L"    RESET_REQUIRED            - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
  Print (L"    AUTHENTICATION_REQUIRED   - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
}

/**
  Dump FMP protocol info.
**/
VOID
DumpFmpData (
  VOID
  )
{
  EFI_STATUS                        Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
  EFI_HANDLE                        *HandleBuffer;
  UINTN                             NumberOfHandles;
  UINTN                             Index;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;
  UINTN                             ImageInfoSize;
  UINT32                            FmpImageInfoDescriptorVer;
  UINT8                             FmpImageInfoCount;
  UINTN                             DescriptorSize;
  UINT32                            PackageVersion;
  CHAR16                            *PackageVersionName;
  UINT32                            PackageVersionNameMaxLen;
  UINT64                            AttributesSupported;
  UINT64                            AttributesSetting;

  Print (L"############\n");
  Print (L"# FMP DATA #\n");
  Print (L"############\n");
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareManagementProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    Print (L"FMP protocol - %r\n", EFI_NOT_FOUND);
    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 = NULL;
    FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
    if (FmpImageInfoBuf == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    PackageVersionName = NULL;
    Status             = Fmp->GetImageInfo (
                                Fmp,
                                &ImageInfoSize,             // ImageInfoSize
                                FmpImageInfoBuf,            // ImageInfo
                                &FmpImageInfoDescriptorVer, // DescriptorVersion
                                &FmpImageInfoCount,         // DescriptorCount
                                &DescriptorSize,            // DescriptorSize
                                &PackageVersion,            // PackageVersion
                                &PackageVersionName         // PackageVersionName
                                );

    //
    // If FMP GetInformation interface failed, skip this resource
    //
    if (EFI_ERROR (Status)) {
      Print (L"FMP (%d) ImageInfo - %r\n", Index, Status);
      FreePool (FmpImageInfoBuf);
      continue;
    }

    Print (L"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);

    //
    // Get package info
    //
    PackageVersionName = NULL;
    Status             = Fmp->GetPackageInfo (
                                Fmp,
                                &PackageVersion,           // PackageVersion
                                &PackageVersionName,       // PackageVersionName
                                &PackageVersionNameMaxLen, // PackageVersionNameMaxLen
                                &AttributesSupported,      // AttributesSupported
                                &AttributesSetting         // AttributesSetting
                                );
    if (EFI_ERROR (Status)) {
      Print (L"FMP (%d) PackageInfo - %r\n", Index, Status);
    } else {
      Print (L"FMP (%d) ImageInfo:\n", Index);
      DumpFmpPackageInfo (
        PackageVersion,              // PackageVersion
        PackageVersionName,          // PackageVersionName
        PackageVersionNameMaxLen,    // PackageVersionNameMaxLen
        AttributesSupported,         // AttributesSupported
        AttributesSetting            // AttributesSetting
        );

      if (PackageVersionName != NULL) {
        FreePool (PackageVersionName);
      }
    }
  }

  Print (L"\n");

EXIT:
  FreePool (HandleBuffer);
}

/**
  Check if the ImageInfo includes the ImageTypeId.

  @param[in] ImageInfo           A pointer to 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] ImageTypeId         A unique GUID identifying the firmware image type.

  @return TRUE  This ImageInfo includes the ImageTypeId
  @return FALSE This ImageInfo does not include the ImageTypeId
**/
BOOLEAN
IsThisFmpImageInfo (
  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR  *ImageInfo,
  IN UINT8                          DescriptorCount,
  IN UINTN                          DescriptorSize,
  IN EFI_GUID                       *ImageTypeId
  )
{
  EFI_FIRMWARE_IMAGE_DESCRIPTOR  *CurrentImageInfo;
  UINTN                          Index;

  CurrentImageInfo = ImageInfo;
  for (Index = 0; Index < DescriptorCount; Index++) {
    if (CompareGuid (&CurrentImageInfo->ImageTypeId, ImageTypeId)) {
      return TRUE;
    }

    CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
  }

  return FALSE;
}

/**
  return the FMP whoes ImageInfo includes the ImageTypeId.

  @param[in] ImageTypeId         A unique GUID identifying the firmware image type.

  @return The FMP whoes ImageInfo includes the ImageTypeId
**/
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *
FindFmpFromImageTypeId (
  IN EFI_GUID  *ImageTypeId
  )
{
  EFI_STATUS                        Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *TargetFmp;
  EFI_HANDLE                        *HandleBuffer;
  UINTN                             NumberOfHandles;
  UINTN                             Index;
  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;
  UINTN                             ImageInfoSize;
  UINT32                            FmpImageInfoDescriptorVer;
  UINT8                             FmpImageInfoCount;
  UINTN                             DescriptorSize;
  UINT32                            PackageVersion;
  CHAR16                            *PackageVersionName;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareManagementProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    Print (L"FMP protocol - %r\n", EFI_NOT_FOUND);
    return NULL;
  }

  TargetFmp = NULL;
  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 = NULL;
    FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
    if (FmpImageInfoBuf == NULL) {
      FreePool (HandleBuffer);
      Print (L"Out of resource\n");
      return NULL;
    }

    PackageVersionName = NULL;
    Status             = Fmp->GetImageInfo (
                                Fmp,
                                &ImageInfoSize,             // ImageInfoSize
                                FmpImageInfoBuf,            // ImageInfo
                                &FmpImageInfoDescriptorVer, // DescriptorVersion
                                &FmpImageInfoCount,         // DescriptorCount
                                &DescriptorSize,            // DescriptorSize
                                &PackageVersion,            // PackageVersion
                                &PackageVersionName         // PackageVersionName
                                );

    //
    // If FMP GetInformation interface failed, skip this resource
    //
    if (EFI_ERROR (Status)) {
      FreePool (FmpImageInfoBuf);
      continue;
    }

    if (PackageVersionName != NULL) {
      FreePool (PackageVersionName);
    }

    if (IsThisFmpImageInfo (FmpImageInfoBuf, FmpImageInfoCount, DescriptorSize, ImageTypeId)) {
      TargetFmp = Fmp;
    }

    FreePool (FmpImageInfoBuf);
    if (TargetFmp != NULL) {
      break;
    }
  }

  FreePool (HandleBuffer);
  return TargetFmp;
}

/**
  Dump FMP image data.

  @param[in]  ImageTypeId   The ImageTypeId of the FMP image.
                            It is used to identify the FMP protocol.
  @param[in]  ImageIndex    The ImageIndex of the FMP image.
                            It is the input parameter for FMP->GetImage().
  @param[in]  ImageName     The file name to hold the output FMP image.
**/
VOID
DumpFmpImage (
  IN EFI_GUID  *ImageTypeId,
  IN UINTN     ImageIndex,
  IN CHAR16    *ImageName
  )
{
  EFI_STATUS                        Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
  VOID                              *Image;
  UINTN                             ImageSize;

  Fmp = FindFmpFromImageTypeId (ImageTypeId);
  if (Fmp == NULL) {
    Print (L"No FMP include ImageTypeId %g\n", ImageTypeId);
    return;
  }

  if (ImageIndex > 0xFF) {
    Print (L"ImageIndex 0x%x too big\n", ImageIndex);
    return;
  }

  Image     = Fmp;
  ImageSize = 0;
  Status    = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    Print (L"Fmp->GetImage - %r\n", Status);
    return;
  }

  Image = AllocatePool (ImageSize);
  if (Image == NULL) {
    Print (L"Allocate FmpImage 0x%x - %r\n", ImageSize, EFI_OUT_OF_RESOURCES);
    return;
  }

  Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);
  if (EFI_ERROR (Status)) {
    Print (L"Fmp->GetImage - %r\n", Status);
    return;
  }

  Status = WriteFileFromBuffer (ImageName, ImageSize, Image);
  Print (L"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId, ImageIndex, ImageName, Status);

  FreePool (Image);

  return;
}
