According to UEFI spec, capsule report variable should include a null terminator for capsule name and capsule target, if they are not present. Cc: Feng Tian <feng.tian@intel.com> Cc: Star Zeng <star.zeng@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
		
			
				
	
	
		
			955 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			955 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Dump Capsule image information.
 | 
						|
 | 
						|
  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <PiDxe.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/UefiRuntimeServicesTableLib.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/PrintLib.h>
 | 
						|
#include <Protocol/FirmwareManagement.h>
 | 
						|
#include <Guid/ImageAuthentication.h>
 | 
						|
#include <Guid/CapsuleReport.h>
 | 
						|
#include <Guid/SystemResourceTable.h>
 | 
						|
#include <Guid/FmpCapsule.h>
 | 
						|
#include <IndustryStandard/WindowsUxCapsule.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Read a file.
 | 
						|
 | 
						|
  @param[in]  FileName        The file to be read.
 | 
						|
  @param[out] BufferSize      The file buffer size
 | 
						|
  @param[out] Buffer          The file buffer
 | 
						|
 | 
						|
  @retval EFI_SUCCESS    Read file successfully
 | 
						|
  @retval EFI_NOT_FOUND  File not found
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
ReadFileToBuffer (
 | 
						|
  IN  CHAR16                               *FileName,
 | 
						|
  OUT UINTN                                *BufferSize,
 | 
						|
  OUT VOID                                 **Buffer
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Write a file.
 | 
						|
 | 
						|
  @param[in] FileName        The file to be written.
 | 
						|
  @param[in] BufferSize      The file buffer size
 | 
						|
  @param[in] Buffer          The file buffer
 | 
						|
 | 
						|
  @retval EFI_SUCCESS    Write file successfully
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
WriteFileFromBuffer (
 | 
						|
  IN  CHAR16                               *FileName,
 | 
						|
  IN  UINTN                                BufferSize,
 | 
						|
  IN  VOID                                 *Buffer
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  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"[UxCapusule]\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 FMP image authentication information.
 | 
						|
 | 
						|
  @param[in] Image      The FMP capsule image
 | 
						|
  @param[in] ImageSize  The size of the FMP capsule image in bytes.
 | 
						|
 | 
						|
  @return the size of FMP authentication.
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
DumpImageAuthentication (
 | 
						|
  IN VOID   *Image,
 | 
						|
  IN UINTN  ImageSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_FIRMWARE_IMAGE_AUTHENTICATION             *ImageAuthentication;
 | 
						|
 | 
						|
  ImageAuthentication = Image;
 | 
						|
  if (CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertPkcs7Guid) ||
 | 
						|
      CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {
 | 
						|
    Print(L"[ImageAuthentication]\n");
 | 
						|
    Print(L"  MonotonicCount   - 0x%lx\n", ImageAuthentication->MonotonicCount);
 | 
						|
    Print(L"WIN_CERTIFICATE:\n");
 | 
						|
    Print(L"  dwLength         - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.dwLength);
 | 
						|
    Print(L"  wRevision        - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wRevision);
 | 
						|
    Print(L"  wCertificateType - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wCertificateType);
 | 
						|
    Print(L"  CertType         - %g\n", &ImageAuthentication->AuthInfo.CertType);
 | 
						|
    return sizeof(ImageAuthentication->MonotonicCount) + ImageAuthentication->AuthInfo.Hdr.dwLength;
 | 
						|
  } else {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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"[FmpCapusule]\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 >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
 | 
						|
      Print(L"  UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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->HeaderSize - (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;
 | 
						|
 | 
						|
  Status = ReadFileToBuffer(CapsuleName, &FileSize, &Buffer);
 | 
						|
  if (EFI_ERROR(Status)) {
 | 
						|
    Print(L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);
 | 
						|
    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"[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));
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  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
 | 
						|
DmpCapsuleStatusVariable (
 | 
						|
  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",
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  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"    PERSIST_ACROSS_RESET   - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET);
 | 
						|
  Print(L"    POPULATE_SYSTEM_TABLE  - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE);
 | 
						|
  Print(L"    INITIATE_RESET         - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_INITIATE_RESET);
 | 
						|
  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 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;
 | 
						|
 | 
						|
  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);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // 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);
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 |