]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Library / DxeCapsuleLibFmp / DxeCapsuleLib.c
index d7abcc879b5abdba7a520efc8f705ae90b38c7ad..197af267aff30269fc616d1aa5d358068b2bd9b0 100644 (file)
@@ -7,23 +7,16 @@
   buffer overflow, integer overflow.\r
 \r
   SupportCapsuleImage(), ProcessCapsuleImage(), IsValidCapsuleHeader(),\r
-  ValidateFmpCapsule(), DisplayCapsuleImage(), ConvertBmpToGopBlt() will\r
-  receive untrusted input and do basic validation.\r
+  ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and\r
+  performs basic validation.\r
 \r
-  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <PiDxe.h>\r
 \r
-#include <IndustryStandard/Bmp.h>\r
 #include <IndustryStandard/WindowsUxCapsule.h>\r
 \r
 #include <Guid/FmpCapsule.h>\r
 #include <Library/CapsuleLib.h>\r
 #include <Library/DevicePathLib.h>\r
 #include <Library/UefiLib.h>\r
-#include <Library/PcdLib.h>\r
+#include <Library/BmpSupportLib.h>\r
 \r
 #include <Protocol/GraphicsOutput.h>\r
 #include <Protocol/EsrtManagement.h>\r
 #include <Protocol/FirmwareManagement.h>\r
+#include <Protocol/FirmwareManagementProgress.h>\r
 #include <Protocol/DevicePath.h>\r
 \r
-EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable              = NULL;\r
-BOOLEAN                   mIsVirtualAddrConverted  = FALSE;\r
-BOOLEAN                   mDxeCapsuleLibEndOfDxe   = FALSE;\r
+EFI_SYSTEM_RESOURCE_TABLE  *mEsrtTable             = NULL;\r
+BOOLEAN                    mIsVirtualAddrConverted = FALSE;\r
+\r
+BOOLEAN    mDxeCapsuleLibEndOfDxe      = FALSE;\r
+EFI_EVENT  mDxeCapsuleLibEndOfDxeEvent = NULL;\r
+\r
+EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  *mFmpProgress = NULL;\r
 \r
 /**\r
   Initialize capsule related variables.\r
@@ -70,8 +68,8 @@ InitCapsuleVariable (
 **/\r
 EFI_STATUS\r
 RecordCapsuleStatusVariable (\r
-  IN EFI_CAPSULE_HEADER                           *CapsuleHeader,\r
-  IN EFI_STATUS                                   CapsuleStatus\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader,\r
+  IN EFI_STATUS          CapsuleStatus\r
   );\r
 \r
 /**\r
@@ -82,6 +80,7 @@ RecordCapsuleStatusVariable (
   @param[in] PayloadIndex   FMP payload index\r
   @param[in] ImageHeader    FMP image header\r
   @param[in] FmpDevicePath  DevicePath associated with the FMP producer\r
+  @param[in] CapFileName    Capsule file name\r
 \r
   @retval EFI_SUCCESS          The capsule status variable is recorded.\r
   @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.\r
@@ -92,24 +91,40 @@ RecordFmpCapsuleStatusVariable (
   IN EFI_STATUS                                    CapsuleStatus,\r
   IN UINTN                                         PayloadIndex,\r
   IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,\r
-  IN EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath OPTIONAL\r
+  IN EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath  OPTIONAL,\r
+  IN CHAR16                                        *CapFileName    OPTIONAL\r
   );\r
 \r
 /**\r
   Function indicate the current completion progress of the firmware\r
   update. Platform may override with own specific progress function.\r
 \r
-  @param[in]  Completion    A value between 1 and 100 indicating the current completion progress of the firmware update\r
+  @param[in]  Completion  A value between 1 and 100 indicating the current\r
+                          completion progress of the firmware update\r
 \r
-  @retval EFI_SUCESS    Input capsule is a correct FMP capsule.\r
+  @retval EFI_SUCESS             The capsule update progress was updated.\r
+  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-Update_Image_Progress (\r
+UpdateImageProgress (\r
   IN UINTN  Completion\r
+  );\r
+\r
+/**\r
+  Return if this capsule is a capsule name capsule, based upon CapsuleHeader.\r
+\r
+  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
+\r
+  @retval TRUE  It is a capsule name capsule.\r
+  @retval FALSE It is not a capsule name capsule.\r
+**/\r
+BOOLEAN\r
+IsCapsuleNameCapsule (\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
   )\r
 {\r
-  return EFI_SUCCESS;\r
+  return CompareGuid (&CapsuleHeader->CapsuleGuid, &gEdkiiCapsuleOnDiskNameGuid);\r
 }\r
 \r
 /**\r
@@ -125,7 +140,7 @@ IsFmpCapsuleGuid (
   IN EFI_GUID  *CapsuleGuid\r
   )\r
 {\r
-  if (CompareGuid(&gEfiFmpCapsuleGuid, CapsuleGuid)) {\r
+  if (CompareGuid (&gEfiFmpCapsuleGuid, CapsuleGuid)) {\r
     return TRUE;\r
   }\r
 \r
@@ -155,9 +170,11 @@ IsValidCapsuleHeader (
   if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {\r
     return FALSE;\r
   }\r
+\r
   if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {\r
     return FALSE;\r
   }\r
+\r
   return TRUE;\r
 }\r
 \r
@@ -187,68 +204,72 @@ ValidateFmpCapsule (
   OUT UINT16             *EmbeddedDriverCount OPTIONAL\r
   )\r
 {\r
-  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER       *FmpCapsuleHeader;\r
-  UINT8                                        *EndOfCapsule;\r
-  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;\r
-  UINT8                                        *EndOfPayload;\r
-  UINT64                                       *ItemOffsetList;\r
-  UINT32                                       ItemNum;\r
-  UINTN                                        Index;\r
-  UINTN                                        FmpCapsuleSize;\r
-  UINTN                                        FmpCapsuleHeaderSize;\r
-  UINT64                                       FmpImageSize;\r
-  UINTN                                        FmpImageHeaderSize;\r
-\r
-  if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER        *FmpCapsuleHeader;\r
+  UINT8                                         *EndOfCapsule;\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader;\r
+  UINT8                                         *EndOfPayload;\r
+  UINT64                                        *ItemOffsetList;\r
+  UINT32                                        ItemNum;\r
+  UINTN                                         Index;\r
+  UINTN                                         FmpCapsuleSize;\r
+  UINTN                                         FmpCapsuleHeaderSize;\r
+  UINT64                                        FmpImageSize;\r
+  UINTN                                         FmpImageHeaderSize;\r
+\r
+  if (!IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {\r
     return ValidateFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), EmbeddedDriverCount);\r
   }\r
 \r
   if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {\r
-    DEBUG((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));\r
+    DEBUG ((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
-  EndOfCapsule     = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;\r
+  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  EndOfCapsule     = (UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize;\r
   FmpCapsuleSize   = (UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader;\r
 \r
-  if (FmpCapsuleSize < sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {\r
-    DEBUG((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));\r
+  if (FmpCapsuleSize < sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {\r
+    DEBUG ((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\r
   if (FmpCapsuleHeader->Version != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {\r
-    DEBUG((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));\r
+    DEBUG ((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
 \r
   // No overflow\r
   ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
 \r
-  if ((FmpCapsuleSize - sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof(UINT64) < ItemNum) {\r
-    DEBUG((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));\r
+  if ((FmpCapsuleSize - sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof (UINT64) < ItemNum) {\r
+    DEBUG ((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  FmpCapsuleHeaderSize = sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof(UINT64)*ItemNum;\r
+\r
+  FmpCapsuleHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof (UINT64)*ItemNum;\r
 \r
   // Check ItemOffsetList\r
   for (Index = 0; Index < ItemNum; Index++) {\r
     if (ItemOffsetList[Index] >= FmpCapsuleSize) {\r
-      DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));\r
+      DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     if (ItemOffsetList[Index] < FmpCapsuleHeaderSize) {\r
-      DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));\r
+      DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     //\r
     // All the address in ItemOffsetList must be stored in ascending order\r
     //\r
     if (Index > 0) {\r
       if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {\r
-        DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index, ItemOffsetList[Index - 1]));\r
+        DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index - 1, ItemOffsetList[Index - 1]));\r
         return EFI_INVALID_PARAMETER;\r
       }\r
     }\r
@@ -256,31 +277,37 @@ ValidateFmpCapsule (
 \r
   // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER\r
   for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {\r
-    ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
+    ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
     if (Index == ItemNum - 1) {\r
       EndOfPayload = (UINT8 *)((UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader);\r
     } else {\r
       EndOfPayload = (UINT8 *)(UINTN)ItemOffsetList[Index+1];\r
     }\r
+\r
     FmpImageSize = (UINTN)EndOfPayload - ItemOffsetList[Index];\r
 \r
-    if (FmpImageSize < OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance)) {\r
-      DEBUG((DEBUG_ERROR, "FmpImageSize(0x%lx) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER\n", FmpImageSize));\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-    FmpImageHeaderSize = sizeof(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);\r
+    FmpImageHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);\r
     if ((ImageHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) ||\r
-        (ImageHeader->Version < 1)) {\r
-      DEBUG((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));\r
+        (ImageHeader->Version < 1))\r
+    {\r
+      DEBUG ((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    if (ImageHeader->Version < EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
-      FmpImageHeaderSize = OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);\r
+\r
+    if (ImageHeader->Version == 1) {\r
+      FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);\r
+    } else if (ImageHeader->Version == 2) {\r
+      FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);\r
+    }\r
+\r
+    if (FmpImageSize < FmpImageHeaderSize) {\r
+      DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) < FmpImageHeaderSize(0x%x)\n", FmpImageSize, FmpImageHeaderSize));\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
 \r
     // No overflow\r
     if (FmpImageSize != (UINT64)FmpImageHeaderSize + (UINT64)ImageHeader->UpdateImageSize + (UINT64)ImageHeader->UpdateVendorCodeSize) {\r
-      DEBUG((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));\r
+      DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -291,9 +318,10 @@ ValidateFmpCapsule (
     //\r
     EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);\r
     if (EndOfPayload != EndOfCapsule) {\r
-      DEBUG((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));\r
+      DEBUG ((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -305,294 +333,58 @@ ValidateFmpCapsule (
 }\r
 \r
 /**\r
-  Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
-  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
-  buffer is passed in it will be used if it is big enough.\r
+  Those capsules supported by the firmwares.\r
 \r
   Caution: This function may receive untrusted input.\r
 \r
-  @param[in]       BmpImage      Pointer to BMP file\r
-  @param[in]       BmpImageSize  Number of bytes in BmpImage\r
-  @param[in, out]  GopBlt        Buffer containing GOP version of BmpImage.\r
-  @param[in, out]  GopBltSize    Size of GopBlt in bytes.\r
-  @param[out]      PixelHeight   Height of GopBlt/BmpImage in pixels\r
-  @param[out]      PixelWidth    Width of GopBlt/BmpImage in pixels\r
-\r
-  @retval EFI_SUCCESS           GopBlt and GopBltSize are returned.\r
-  @retval EFI_UNSUPPORTED       BmpImage is not a valid *.BMP image\r
-  @retval EFI_BUFFER_TOO_SMALL  The passed in GopBlt buffer is not big enough.\r
-                                GopBltSize will contain the required size.\r
-  @retval EFI_OUT_OF_RESOURCES  No enough buffer to allocate.\r
+  @param[in]  CapsuleHeader    Points to a capsule header.\r
 \r
+  @retval EFI_SUCESS       Input capsule is supported by firmware.\r
+  @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.\r
 **/\r
-STATIC\r
 EFI_STATUS\r
-ConvertBmpToGopBlt (\r
-  IN     VOID      *BmpImage,\r
-  IN     UINTN     BmpImageSize,\r
-  IN OUT VOID      **GopBlt,\r
-  IN OUT UINTN     *GopBltSize,\r
-     OUT UINTN     *PixelHeight,\r
-     OUT UINTN     *PixelWidth\r
+DisplayCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
   )\r
 {\r
-  UINT8                         *Image;\r
-  UINT8                         *ImageHeader;\r
-  BMP_IMAGE_HEADER              *BmpHeader;\r
-  BMP_COLOR_MAP                 *BmpColorMap;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
-  UINT64                        BltBufferSize;\r
-  UINTN                         Index;\r
-  UINTN                         Height;\r
-  UINTN                         Width;\r
-  UINTN                         ImageIndex;\r
-  UINT32                        DataSizePerLine;\r
-  BOOLEAN                       IsAllocated;\r
-  UINT32                        ColorMapNum;\r
-\r
-  if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
-\r
-  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Doesn't support compress.\r
-  //\r
-  if (BmpHeader->CompressionType != 0) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
+  DISPLAY_DISPLAY_PAYLOAD        *ImagePayload;\r
+  UINTN                          PayloadSize;\r
+  EFI_STATUS                     Status;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Blt;\r
+  UINTN                          BltSize;\r
+  UINTN                          Height;\r
+  UINTN                          Width;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;\r
 \r
   //\r
-  // Only support BITMAPINFOHEADER format.\r
-  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
+  // UX capsule doesn't have extended header entries.\r
   //\r
-  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {\r
+  if (CapsuleHeader->HeaderSize != sizeof (EFI_CAPSULE_HEADER)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize);\r
   //\r
-  // The data size in each line must be 4 byte alignment.\r
+  // (CapsuleImageSize > HeaderSize) is guaranteed by IsValidCapsuleHeader().\r
   //\r
-  DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
-  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
-  if (BltBufferSize > (UINT32) ~0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((BmpHeader->Size != BmpImageSize) ||\r
-      (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
-      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * DataSizePerLine)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  PayloadSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
 \r
   //\r
-  // Calculate Color Map offset in the image.\r
+  // Make sure the image payload at least contain the DISPLAY_DISPLAY_PAYLOAD header.\r
+  // Further size check is performed by the logic translating BMP to GOP BLT.\r
   //\r
-  Image       = BmpImage;\r
-  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
-  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
+  if (PayloadSize <= sizeof (DISPLAY_DISPLAY_PAYLOAD)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
-    switch (BmpHeader->BitPerPixel) {\r
-      case 1:\r
-        ColorMapNum = 2;\r
-        break;\r
-      case 4:\r
-        ColorMapNum = 16;\r
-        break;\r
-      case 8:\r
-        ColorMapNum = 256;\r
-        break;\r
-      default:\r
-        ColorMapNum = 0;\r
-        break;\r
-      }\r
-    //\r
-    // BMP file may has padding data between the bmp header section and the bmp data section.\r
-    //\r
-    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Calculate graphics image data address in the image\r
-  //\r
-  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
-  ImageHeader   = Image;\r
-\r
-  //\r
-  // Calculate the BltBuffer needed size.\r
-  //\r
-  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
-  //\r
-  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
-  //\r
-  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-\r
-  IsAllocated   = FALSE;\r
-  if (*GopBlt == NULL) {\r
-    //\r
-    // GopBlt is not allocated by caller.\r
-    //\r
-    *GopBltSize = (UINTN) BltBufferSize;\r
-    *GopBlt     = AllocatePool (*GopBltSize);\r
-    IsAllocated = TRUE;\r
-    if (*GopBlt == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  } else {\r
-    //\r
-    // GopBlt has been allocated by caller.\r
-    //\r
-    if (*GopBltSize < (UINTN) BltBufferSize) {\r
-      *GopBltSize = (UINTN) BltBufferSize;\r
-      return EFI_BUFFER_TOO_SMALL;\r
-    }\r
-  }\r
-\r
-  *PixelWidth   = BmpHeader->PixelWidth;\r
-  *PixelHeight  = BmpHeader->PixelHeight;\r
-\r
-  //\r
-  // Convert image from BMP to Blt buffer format\r
-  //\r
-  BltBuffer = *GopBlt;\r
-  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
-    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
-    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
-      switch (BmpHeader->BitPerPixel) {\r
-      case 1:\r
-        //\r
-        // Convert 1-bit (2 colors) BMP to 24-bit color\r
-        //\r
-        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
-          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
-          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
-          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
-          Blt++;\r
-          Width++;\r
-        }\r
-\r
-        Blt--;\r
-        Width--;\r
-        break;\r
-\r
-      case 4:\r
-        //\r
-        // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
-        //\r
-        Index       = (*Image) >> 4;\r
-        Blt->Red    = BmpColorMap[Index].Red;\r
-        Blt->Green  = BmpColorMap[Index].Green;\r
-        Blt->Blue   = BmpColorMap[Index].Blue;\r
-        if (Width < (BmpHeader->PixelWidth - 1)) {\r
-          Blt++;\r
-          Width++;\r
-          Index       = (*Image) & 0x0f;\r
-          Blt->Red    = BmpColorMap[Index].Red;\r
-          Blt->Green  = BmpColorMap[Index].Green;\r
-          Blt->Blue   = BmpColorMap[Index].Blue;\r
-        }\r
-        break;\r
-\r
-      case 8:\r
-        //\r
-        // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
-        //\r
-        Blt->Red    = BmpColorMap[*Image].Red;\r
-        Blt->Green  = BmpColorMap[*Image].Green;\r
-        Blt->Blue   = BmpColorMap[*Image].Blue;\r
-        break;\r
-\r
-      case 24:\r
-        //\r
-        // It is 24-bit BMP.\r
-        //\r
-        Blt->Blue   = *Image++;\r
-        Blt->Green  = *Image++;\r
-        Blt->Red    = *Image;\r
-        break;\r
-\r
-      case 32:\r
-        //\r
-        // it is 32-bit BMP. Skip pixel's highest byte\r
-        //\r
-        Blt->Blue  = *Image++;\r
-        Blt->Green = *Image++;\r
-        Blt->Red   = *Image++;\r
-        break;\r
-\r
-      default:\r
-        //\r
-        // Other bit format BMP is not supported.\r
-        //\r
-        if (IsAllocated) {\r
-          FreePool (*GopBlt);\r
-          *GopBlt = NULL;\r
-        }\r
-        return EFI_UNSUPPORTED;\r
-      };\r
-\r
-    }\r
-\r
-    ImageIndex = (UINTN) Image - (UINTN) ImageHeader;\r
-    if ((ImageIndex % 4) != 0) {\r
-      //\r
-      // Bmp Image starts each row on a 32-bit boundary!\r
-      //\r
-      Image = Image + (4 - (ImageIndex % 4));\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Those capsules supported by the firmwares.\r
-\r
-  Caution: This function may receive untrusted input.\r
-\r
-  @param[in]  CapsuleHeader    Points to a capsule header.\r
-\r
-  @retval EFI_SUCESS       Input capsule is supported by firmware.\r
-  @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.\r
-**/\r
-EFI_STATUS\r
-DisplayCapsuleImage (\r
-  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
-  )\r
-{\r
-  DISPLAY_DISPLAY_PAYLOAD       *ImagePayload;\r
-  UINTN                         PayloadSize;\r
-  EFI_STATUS                    Status;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
-  UINTN                         BltSize;\r
-  UINTN                         Height;\r
-  UINTN                         Width;\r
-  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
-\r
-  ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)(CapsuleHeader + 1);\r
-  PayloadSize = (UINTN)(CapsuleHeader->CapsuleImageSize - sizeof(EFI_CAPSULE_HEADER));\r
-\r
   if (ImagePayload->Version != 1) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  if (CalculateCheckSum8((UINT8 *)CapsuleHeader, CapsuleHeader->CapsuleImageSize) != 0) {\r
+\r
+  if (CalculateCheckSum8 ((UINT8 *)CapsuleHeader, CapsuleHeader->CapsuleImageSize) != 0) {\r
     return EFI_UNSUPPORTED;\r
   }\r
+\r
   //\r
   // Only Support Bitmap by now\r
   //\r
@@ -605,8 +397,8 @@ DisplayCapsuleImage (
   //\r
   Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);\r
   if (EFI_ERROR (Status)) {\r
-    Status = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&GraphicsOutput);\r
-    if (EFI_ERROR(Status)) {\r
+    Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&GraphicsOutput);\r
+    if (EFI_ERROR (Status)) {\r
       return EFI_UNSUPPORTED;\r
     }\r
   }\r
@@ -615,13 +407,13 @@ DisplayCapsuleImage (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  Blt = NULL;\r
-  Width = 0;\r
+  Blt    = NULL;\r
+  Width  = 0;\r
   Height = 0;\r
-  Status = ConvertBmpToGopBlt (\r
+  Status = TranslateBmpToGopBlt (\r
              ImagePayload + 1,\r
-             PayloadSize - sizeof(DISPLAY_DISPLAY_PAYLOAD),\r
-             (VOID **)&Blt,\r
+             PayloadSize - sizeof (DISPLAY_DISPLAY_PAYLOAD),\r
+             &Blt,\r
              &BltSize,\r
              &Height,\r
              &Width\r
@@ -637,14 +429,14 @@ DisplayCapsuleImage (
                              EfiBltBufferToVideo,\r
                              0,\r
                              0,\r
-                             (UINTN) ImagePayload->OffsetX,\r
-                             (UINTN) ImagePayload->OffsetY,\r
+                             (UINTN)ImagePayload->OffsetX,\r
+                             (UINTN)ImagePayload->OffsetY,\r
                              Width,\r
                              Height,\r
                              Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
                              );\r
 \r
-  FreePool(Blt);\r
+  FreePool (Blt);\r
 \r
   return Status;\r
 }\r
@@ -662,44 +454,45 @@ DisplayCapsuleImage (
 **/\r
 VOID\r
 DumpFmpImageInfo (\r
-  IN UINTN                           ImageInfoSize,\r
-  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR   *ImageInfo,\r
-  IN UINT32                          DescriptorVersion,\r
-  IN UINT8                           DescriptorCount,\r
-  IN UINTN                           DescriptorSize,\r
-  IN UINT32                          PackageVersion,\r
-  IN CHAR16                          *PackageVersionName\r
+  IN UINTN                          ImageInfoSize,\r
+  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR  *ImageInfo,\r
+  IN UINT32                         DescriptorVersion,\r
+  IN UINT8                          DescriptorCount,\r
+  IN UINTN                          DescriptorSize,\r
+  IN UINT32                         PackageVersion,\r
+  IN CHAR16                         *PackageVersionName\r
   )\r
 {\r
-  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *CurrentImageInfo;\r
-  UINTN                                         Index;\r
-\r
-  DEBUG((DEBUG_VERBOSE, "  DescriptorVersion  - 0x%x\n", DescriptorVersion));\r
-  DEBUG((DEBUG_VERBOSE, "  DescriptorCount    - 0x%x\n", DescriptorCount));\r
-  DEBUG((DEBUG_VERBOSE, "  DescriptorSize     - 0x%x\n", DescriptorSize));\r
-  DEBUG((DEBUG_VERBOSE, "  PackageVersion     - 0x%x\n", PackageVersion));\r
-  DEBUG((DEBUG_VERBOSE, "  PackageVersionName - %s\n\n", PackageVersionName));\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR  *CurrentImageInfo;\r
+  UINTN                          Index;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "  DescriptorVersion  - 0x%x\n", DescriptorVersion));\r
+  DEBUG ((DEBUG_VERBOSE, "  DescriptorCount    - 0x%x\n", DescriptorCount));\r
+  DEBUG ((DEBUG_VERBOSE, "  DescriptorSize     - 0x%x\n", DescriptorSize));\r
+  DEBUG ((DEBUG_VERBOSE, "  PackageVersion     - 0x%x\n", PackageVersion));\r
+  DEBUG ((DEBUG_VERBOSE, "  PackageVersionName - %s\n\n", PackageVersionName));\r
   CurrentImageInfo = ImageInfo;\r
   for (Index = 0; Index < DescriptorCount; Index++) {\r
-    DEBUG((DEBUG_VERBOSE, "  ImageDescriptor (%d)\n", Index));\r
-    DEBUG((DEBUG_VERBOSE, "    ImageIndex                  - 0x%x\n", CurrentImageInfo->ImageIndex));\r
-    DEBUG((DEBUG_VERBOSE, "    ImageTypeId                 - %g\n", &CurrentImageInfo->ImageTypeId));\r
-    DEBUG((DEBUG_VERBOSE, "    ImageId                     - 0x%lx\n", CurrentImageInfo->ImageId));\r
-    DEBUG((DEBUG_VERBOSE, "    ImageIdName                 - %s\n", CurrentImageInfo->ImageIdName));\r
-    DEBUG((DEBUG_VERBOSE, "    Version                     - 0x%x\n", CurrentImageInfo->Version));\r
-    DEBUG((DEBUG_VERBOSE, "    VersionName                 - %s\n", CurrentImageInfo->VersionName));\r
-    DEBUG((DEBUG_VERBOSE, "    Size                        - 0x%x\n", CurrentImageInfo->Size));\r
-    DEBUG((DEBUG_VERBOSE, "    AttributesSupported         - 0x%lx\n", CurrentImageInfo->AttributesSupported));\r
-    DEBUG((DEBUG_VERBOSE, "    AttributesSetting           - 0x%lx\n", CurrentImageInfo->AttributesSetting));\r
-    DEBUG((DEBUG_VERBOSE, "    Compatibilities             - 0x%lx\n", CurrentImageInfo->Compatibilities));\r
+    DEBUG ((DEBUG_VERBOSE, "  ImageDescriptor (%d)\n", Index));\r
+    DEBUG ((DEBUG_VERBOSE, "    ImageIndex                  - 0x%x\n", CurrentImageInfo->ImageIndex));\r
+    DEBUG ((DEBUG_VERBOSE, "    ImageTypeId                 - %g\n", &CurrentImageInfo->ImageTypeId));\r
+    DEBUG ((DEBUG_VERBOSE, "    ImageId                     - 0x%lx\n", CurrentImageInfo->ImageId));\r
+    DEBUG ((DEBUG_VERBOSE, "    ImageIdName                 - %s\n", CurrentImageInfo->ImageIdName));\r
+    DEBUG ((DEBUG_VERBOSE, "    Version                     - 0x%x\n", CurrentImageInfo->Version));\r
+    DEBUG ((DEBUG_VERBOSE, "    VersionName                 - %s\n", CurrentImageInfo->VersionName));\r
+    DEBUG ((DEBUG_VERBOSE, "    Size                        - 0x%x\n", CurrentImageInfo->Size));\r
+    DEBUG ((DEBUG_VERBOSE, "    AttributesSupported         - 0x%lx\n", CurrentImageInfo->AttributesSupported));\r
+    DEBUG ((DEBUG_VERBOSE, "    AttributesSetting           - 0x%lx\n", CurrentImageInfo->AttributesSetting));\r
+    DEBUG ((DEBUG_VERBOSE, "    Compatibilities             - 0x%lx\n", CurrentImageInfo->Compatibilities));\r
     if (DescriptorVersion > 1) {\r
-      DEBUG((DEBUG_VERBOSE, "    LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion));\r
+      DEBUG ((DEBUG_VERBOSE, "    LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion));\r
       if (DescriptorVersion > 2) {\r
-        DEBUG((DEBUG_VERBOSE, "    LastAttemptVersion          - 0x%x\n", CurrentImageInfo->LastAttemptVersion));\r
-        DEBUG((DEBUG_VERBOSE, "    LastAttemptStatus           - 0x%x\n", CurrentImageInfo->LastAttemptStatus));\r
-        DEBUG((DEBUG_VERBOSE, "    HardwareInstance            - 0x%lx\n", CurrentImageInfo->HardwareInstance));\r
+        DEBUG ((DEBUG_VERBOSE, "    LastAttemptVersion          - 0x%x\n", CurrentImageInfo->LastAttemptVersion));\r
+        DEBUG ((DEBUG_VERBOSE, "    LastAttemptStatus           - 0x%x\n", CurrentImageInfo->LastAttemptStatus));\r
+        DEBUG ((DEBUG_VERBOSE, "    HardwareInstance            - 0x%lx\n", CurrentImageInfo->HardwareInstance));\r
       }\r
     }\r
+\r
     //\r
     // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
     //\r
@@ -714,7 +507,7 @@ DumpFmpImageInfo (
 **/\r
 VOID\r
 DumpFmpCapsule (\r
-  IN EFI_CAPSULE_HEADER                *CapsuleHeader\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
   )\r
 {\r
   EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER        *FmpCapsuleHeader;\r
@@ -724,27 +517,31 @@ DumpFmpCapsule (
 \r
   FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
 \r
-  DEBUG((DEBUG_VERBOSE, "FmpCapsule:\n"));\r
-  DEBUG((DEBUG_VERBOSE, "  Version                - 0x%x\n", FmpCapsuleHeader->Version));\r
-  DEBUG((DEBUG_VERBOSE, "  EmbeddedDriverCount    - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount));\r
-  DEBUG((DEBUG_VERBOSE, "  PayloadItemCount       - 0x%x\n", FmpCapsuleHeader->PayloadItemCount));\r
+  DEBUG ((DEBUG_VERBOSE, "FmpCapsule:\n"));\r
+  DEBUG ((DEBUG_VERBOSE, "  Version                - 0x%x\n", FmpCapsuleHeader->Version));\r
+  DEBUG ((DEBUG_VERBOSE, "  EmbeddedDriverCount    - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount));\r
+  DEBUG ((DEBUG_VERBOSE, "  PayloadItemCount       - 0x%x\n", FmpCapsuleHeader->PayloadItemCount));\r
 \r
   ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
   for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {\r
-    DEBUG((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));\r
+    DEBUG ((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));\r
   }\r
-  for (; Index < (UINTN)(FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount); Index++) {\r
-    DEBUG((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));\r
+\r
+  for ( ; Index < (UINT32)FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount; Index++) {\r
+    DEBUG ((DEBUG_VERBOSE, "  ItemOffsetList[%d]      - 0x%lx\n", Index, ItemOffsetList[Index]));\r
     ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
 \r
-    DEBUG((DEBUG_VERBOSE, "  ImageHeader:\n"));\r
-    DEBUG((DEBUG_VERBOSE, "    Version                - 0x%x\n", ImageHeader->Version));\r
-    DEBUG((DEBUG_VERBOSE, "    UpdateImageTypeId      - %g\n", &ImageHeader->UpdateImageTypeId));\r
-    DEBUG((DEBUG_VERBOSE, "    UpdateImageIndex       - 0x%x\n", ImageHeader->UpdateImageIndex));\r
-    DEBUG((DEBUG_VERBOSE, "    UpdateImageSize        - 0x%x\n", ImageHeader->UpdateImageSize));\r
-    DEBUG((DEBUG_VERBOSE, "    UpdateVendorCodeSize   - 0x%x\n", ImageHeader->UpdateVendorCodeSize));\r
-    if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
-      DEBUG((DEBUG_VERBOSE, "    UpdateHardwareInstance - 0x%lx\n", ImageHeader->UpdateHardwareInstance));\r
+    DEBUG ((DEBUG_VERBOSE, "  ImageHeader:\n"));\r
+    DEBUG ((DEBUG_VERBOSE, "    Version                - 0x%x\n", ImageHeader->Version));\r
+    DEBUG ((DEBUG_VERBOSE, "    UpdateImageTypeId      - %g\n", &ImageHeader->UpdateImageTypeId));\r
+    DEBUG ((DEBUG_VERBOSE, "    UpdateImageIndex       - 0x%x\n", ImageHeader->UpdateImageIndex));\r
+    DEBUG ((DEBUG_VERBOSE, "    UpdateImageSize        - 0x%x\n", ImageHeader->UpdateImageSize));\r
+    DEBUG ((DEBUG_VERBOSE, "    UpdateVendorCodeSize   - 0x%x\n", ImageHeader->UpdateVendorCodeSize));\r
+    if (ImageHeader->Version >= 2) {\r
+      DEBUG ((DEBUG_VERBOSE, "    UpdateHardwareInstance - 0x%lx\n", ImageHeader->UpdateHardwareInstance));\r
+      if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
+        DEBUG ((DEBUG_VERBOSE, "    ImageCapsuleSupport    - 0x%lx\n", ImageHeader->ImageCapsuleSupport));\r
+      }\r
     }\r
   }\r
 }\r
@@ -757,18 +554,18 @@ DumpAllFmpInfo (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                                    Status;\r
-  EFI_HANDLE                                    *HandleBuffer;\r
-  UINTN                                         NumberOfHandles;\r
-  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
-  UINTN                                         Index;\r
-  UINTN                                         ImageInfoSize;\r
-  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;\r
-  UINT32                                        FmpImageInfoDescriptorVer;\r
-  UINT8                                         FmpImageInfoCount;\r
-  UINTN                                         DescriptorSize;\r
-  UINT32                                        PackageVersion;\r
-  CHAR16                                        *PackageVersionName;\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        *HandleBuffer;\r
+  UINTN                             NumberOfHandles;\r
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;\r
+  UINTN                             Index;\r
+  UINTN                             ImageInfoSize;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;\r
+  UINT32                            FmpImageInfoDescriptorVer;\r
+  UINT8                             FmpImageInfoCount;\r
+  UINTN                             DescriptorSize;\r
+  UINT32                            PackageVersion;\r
+  CHAR16                            *PackageVersionName;\r
 \r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
@@ -777,31 +574,31 @@ DumpAllFmpInfo (
                   &NumberOfHandles,\r
                   &HandleBuffer\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
-    return ;\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
   }\r
 \r
   for (Index = 0; Index < NumberOfHandles; Index++) {\r
-    Status = gBS->HandleProtocol(\r
+    Status = gBS->HandleProtocol (\r
                     HandleBuffer[Index],\r
                     &gEfiFirmwareManagementProtocolGuid,\r
                     (VOID **)&Fmp\r
                     );\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
 \r
     ImageInfoSize = 0;\r
-    Status = Fmp->GetImageInfo (\r
-                    Fmp,\r
-                    &ImageInfoSize,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL\r
-                    );\r
+    Status        = Fmp->GetImageInfo (\r
+                           Fmp,\r
+                           &ImageInfoSize,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL\r
+                           );\r
     if (Status != EFI_BUFFER_TOO_SMALL) {\r
       continue;\r
     }\r
@@ -812,23 +609,23 @@ DumpAllFmpInfo (
     }\r
 \r
     PackageVersionName = NULL;\r
-    Status = Fmp->GetImageInfo (\r
-                    Fmp,\r
-                    &ImageInfoSize,               // ImageInfoSize\r
-                    FmpImageInfoBuf,              // ImageInfo\r
-                    &FmpImageInfoDescriptorVer,   // DescriptorVersion\r
-                    &FmpImageInfoCount,           // DescriptorCount\r
-                    &DescriptorSize,              // DescriptorSize\r
-                    &PackageVersion,              // PackageVersion\r
-                    &PackageVersionName           // PackageVersionName\r
-                    );\r
-    if (EFI_ERROR(Status)) {\r
-      FreePool(FmpImageInfoBuf);\r
+    Status             = Fmp->GetImageInfo (\r
+                                Fmp,\r
+                                &ImageInfoSize,             // ImageInfoSize\r
+                                FmpImageInfoBuf,            // ImageInfo\r
+                                &FmpImageInfoDescriptorVer, // DescriptorVersion\r
+                                &FmpImageInfoCount,         // DescriptorCount\r
+                                &DescriptorSize,            // DescriptorSize\r
+                                &PackageVersion,            // PackageVersion\r
+                                &PackageVersionName         // PackageVersionName\r
+                                );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (FmpImageInfoBuf);\r
       continue;\r
     }\r
 \r
-    DEBUG((DEBUG_INFO, "FMP (%d) ImageInfo:\n", Index));\r
-    DumpFmpImageInfo(\r
+    DEBUG ((DEBUG_INFO, "FMP (%d) ImageInfo:\n", Index));\r
+    DumpFmpImageInfo (\r
       ImageInfoSize,               // ImageInfoSize\r
       FmpImageInfoBuf,             // ImageInfo\r
       FmpImageInfoDescriptorVer,   // DescriptorVersion\r
@@ -839,13 +636,15 @@ DumpAllFmpInfo (
       );\r
 \r
     if (PackageVersionName != NULL) {\r
-      FreePool(PackageVersionName);\r
+      FreePool (PackageVersionName);\r
     }\r
 \r
-    FreePool(FmpImageInfoBuf);\r
+    FreePool (FmpImageInfoBuf);\r
   }\r
 \r
-  return ;\r
+  FreePool (HandleBuffer);\r
+\r
+  return;\r
 }\r
 \r
 /**\r
@@ -853,41 +652,55 @@ DumpAllFmpInfo (
 \r
   @param[in]     UpdateImageTypeId       Used to identify device firmware targeted by this update.\r
   @param[in]     UpdateHardwareInstance  The HardwareInstance to target with this update.\r
-  @param[in,out] NoHandles               The number of handles returned in Buffer.\r
-  @param[out]    Buffer[out]             A pointer to the buffer to return the requested array of handles.\r
-\r
-  @retval EFI_SUCCESS            The array of handles was returned in Buffer, and the number of\r
-                                 handles in Buffer was returned in NoHandles.\r
+  @param[out]    NoHandles               The number of handles returned in HandleBuf.\r
+  @param[out]    HandleBuf               A pointer to the buffer to return the requested array of handles.\r
+  @param[out]    ResetRequiredBuf        A pointer to the buffer to return reset required flag for\r
+                                         the requested array of handles.\r
+\r
+  @retval EFI_SUCCESS            The array of handles and their reset required flag were returned in\r
+                                 HandleBuf and ResetRequiredBuf, and the number of handles in HandleBuf\r
+                                 was returned in NoHandles.\r
   @retval EFI_NOT_FOUND          No handles match the search.\r
   @retval EFI_OUT_OF_RESOURCES   There is not enough pool memory to store the matching results.\r
 **/\r
 EFI_STATUS\r
 GetFmpHandleBufferByType (\r
-  IN     EFI_GUID                     *UpdateImageTypeId,\r
-  IN     UINT64                       UpdateHardwareInstance,\r
-  IN OUT UINTN                        *NoHandles,\r
-  OUT    EFI_HANDLE                   **Buffer\r
+  IN     EFI_GUID    *UpdateImageTypeId,\r
+  IN     UINT64      UpdateHardwareInstance,\r
+  OUT    UINTN       *NoHandles  OPTIONAL,\r
+  OUT    EFI_HANDLE  **HandleBuf  OPTIONAL,\r
+  OUT    BOOLEAN     **ResetRequiredBuf OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                                    Status;\r
-  EFI_HANDLE                                    *HandleBuffer;\r
-  UINTN                                         NumberOfHandles;\r
-  EFI_HANDLE                                    *MatchedHandleBuffer;\r
-  UINTN                                         MatchedNumberOfHandles;\r
-  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
-  UINTN                                         Index;\r
-  UINTN                                         ImageInfoSize;\r
-  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;\r
-  UINT32                                        FmpImageInfoDescriptorVer;\r
-  UINT8                                         FmpImageInfoCount;\r
-  UINTN                                         DescriptorSize;\r
-  UINT32                                        PackageVersion;\r
-  CHAR16                                        *PackageVersionName;\r
-  UINTN                                         Index2;\r
-  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *TempFmpImageInfo;\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        *HandleBuffer;\r
+  UINTN                             NumberOfHandles;\r
+  EFI_HANDLE                        *MatchedHandleBuffer;\r
+  BOOLEAN                           *MatchedResetRequiredBuffer;\r
+  UINTN                             MatchedNumberOfHandles;\r
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;\r
+  UINTN                             Index;\r
+  UINTN                             ImageInfoSize;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;\r
+  UINT32                            FmpImageInfoDescriptorVer;\r
+  UINT8                             FmpImageInfoCount;\r
+  UINTN                             DescriptorSize;\r
+  UINT32                            PackageVersion;\r
+  CHAR16                            *PackageVersionName;\r
+  UINTN                             Index2;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *TempFmpImageInfo;\r
+\r
+  if (NoHandles != NULL) {\r
+    *NoHandles = 0;\r
+  }\r
 \r
-  *NoHandles = 0;\r
-  *Buffer = NULL;\r
+  if (HandleBuf != NULL) {\r
+    *HandleBuf = NULL;\r
+  }\r
+\r
+  if (ResetRequiredBuf != NULL) {\r
+    *ResetRequiredBuf = NULL;\r
+  }\r
 \r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
@@ -896,38 +709,55 @@ GetFmpHandleBufferByType (
                   &NumberOfHandles,\r
                   &HandleBuffer\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   MatchedNumberOfHandles = 0;\r
-  MatchedHandleBuffer = AllocateZeroPool (sizeof(EFI_HANDLE) * NumberOfHandles);\r
-  if (MatchedHandleBuffer == NULL) {\r
-    FreePool (HandleBuffer);\r
-    return EFI_OUT_OF_RESOURCES;\r
+\r
+  MatchedHandleBuffer = NULL;\r
+  if (HandleBuf != NULL) {\r
+    MatchedHandleBuffer = AllocateZeroPool (sizeof (EFI_HANDLE) * NumberOfHandles);\r
+    if (MatchedHandleBuffer == NULL) {\r
+      FreePool (HandleBuffer);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
+  MatchedResetRequiredBuffer = NULL;\r
+  if (ResetRequiredBuf != NULL) {\r
+    MatchedResetRequiredBuffer = AllocateZeroPool (sizeof (BOOLEAN) * NumberOfHandles);\r
+    if (MatchedResetRequiredBuffer == NULL) {\r
+      if (MatchedHandleBuffer != NULL) {\r
+        FreePool (MatchedHandleBuffer);\r
+      }\r
+\r
+      FreePool (HandleBuffer);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
   }\r
 \r
   for (Index = 0; Index < NumberOfHandles; Index++) {\r
-    Status = gBS->HandleProtocol(\r
+    Status = gBS->HandleProtocol (\r
                     HandleBuffer[Index],\r
                     &gEfiFirmwareManagementProtocolGuid,\r
                     (VOID **)&Fmp\r
                     );\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
 \r
     ImageInfoSize = 0;\r
-    Status = Fmp->GetImageInfo (\r
-                    Fmp,\r
-                    &ImageInfoSize,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL\r
-                    );\r
+    Status        = Fmp->GetImageInfo (\r
+                           Fmp,\r
+                           &ImageInfoSize,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL,\r
+                           NULL\r
+                           );\r
     if (Status != EFI_BUFFER_TOO_SMALL) {\r
       continue;\r
     }\r
@@ -938,23 +768,23 @@ GetFmpHandleBufferByType (
     }\r
 \r
     PackageVersionName = NULL;\r
-    Status = Fmp->GetImageInfo (\r
-                    Fmp,\r
-                    &ImageInfoSize,               // ImageInfoSize\r
-                    FmpImageInfoBuf,              // ImageInfo\r
-                    &FmpImageInfoDescriptorVer,   // DescriptorVersion\r
-                    &FmpImageInfoCount,           // DescriptorCount\r
-                    &DescriptorSize,              // DescriptorSize\r
-                    &PackageVersion,              // PackageVersion\r
-                    &PackageVersionName           // PackageVersionName\r
-                    );\r
-    if (EFI_ERROR(Status)) {\r
-      FreePool(FmpImageInfoBuf);\r
+    Status             = Fmp->GetImageInfo (\r
+                                Fmp,\r
+                                &ImageInfoSize,             // ImageInfoSize\r
+                                FmpImageInfoBuf,            // ImageInfo\r
+                                &FmpImageInfoDescriptorVer, // DescriptorVersion\r
+                                &FmpImageInfoCount,         // DescriptorCount\r
+                                &DescriptorSize,            // DescriptorSize\r
+                                &PackageVersion,            // PackageVersion\r
+                                &PackageVersionName         // PackageVersionName\r
+                                );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (FmpImageInfoBuf);\r
       continue;\r
     }\r
 \r
     if (PackageVersionName != NULL) {\r
-      FreePool(PackageVersionName);\r
+      FreePool (PackageVersionName);\r
     }\r
 \r
     TempFmpImageInfo = FmpImageInfoBuf;\r
@@ -962,26 +792,50 @@ GetFmpHandleBufferByType (
       //\r
       // Check if this FMP instance matches\r
       //\r
-      if (CompareGuid(UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId)) {\r
+      if (CompareGuid (UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId)) {\r
         if ((UpdateHardwareInstance == 0) ||\r
             ((FmpImageInfoDescriptorVer >= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) &&\r
-             (UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance))) {\r
-          MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];\r
+             (UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance)))\r
+        {\r
+          if (MatchedHandleBuffer != NULL) {\r
+            MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];\r
+          }\r
+\r
+          if (MatchedResetRequiredBuffer != NULL) {\r
+            MatchedResetRequiredBuffer[MatchedNumberOfHandles] = (((TempFmpImageInfo->AttributesSupported &\r
+                                                                    IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) &&\r
+                                                                  ((TempFmpImageInfo->AttributesSetting &\r
+                                                                    IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0));\r
+          }\r
+\r
           MatchedNumberOfHandles++;\r
           break;\r
         }\r
       }\r
+\r
       TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);\r
     }\r
-    FreePool(FmpImageInfoBuf);\r
+\r
+    FreePool (FmpImageInfoBuf);\r
   }\r
 \r
+  FreePool (HandleBuffer);\r
+\r
   if (MatchedNumberOfHandles == 0) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  *NoHandles = MatchedNumberOfHandles;\r
-  *Buffer = MatchedHandleBuffer;\r
+  if (NoHandles != NULL) {\r
+    *NoHandles = MatchedNumberOfHandles;\r
+  }\r
+\r
+  if (HandleBuf != NULL) {\r
+    *HandleBuf = MatchedHandleBuffer;\r
+  }\r
+\r
+  if (ResetRequiredBuf != NULL) {\r
+    *ResetRequiredBuf = MatchedResetRequiredBuffer;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -995,39 +849,39 @@ GetFmpHandleBufferByType (
 **/\r
 UINT32\r
 GetFmpImageInfoDescriptorVer (\r
-  IN EFI_HANDLE                                   Handle\r
+  IN EFI_HANDLE  Handle\r
   )\r
 {\r
-  EFI_STATUS                                    Status;\r
-  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
-  UINTN                                         ImageInfoSize;\r
-  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;\r
-  UINT32                                        FmpImageInfoDescriptorVer;\r
-  UINT8                                         FmpImageInfoCount;\r
-  UINTN                                         DescriptorSize;\r
-  UINT32                                        PackageVersion;\r
-  CHAR16                                        *PackageVersionName;\r
-\r
-  Status = gBS->HandleProtocol(\r
+  EFI_STATUS                        Status;\r
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;\r
+  UINTN                             ImageInfoSize;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;\r
+  UINT32                            FmpImageInfoDescriptorVer;\r
+  UINT8                             FmpImageInfoCount;\r
+  UINTN                             DescriptorSize;\r
+  UINT32                            PackageVersion;\r
+  CHAR16                            *PackageVersionName;\r
+\r
+  Status = gBS->HandleProtocol (\r
                   Handle,\r
                   &gEfiFirmwareManagementProtocolGuid,\r
                   (VOID **)&Fmp\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return 0;\r
   }\r
 \r
   ImageInfoSize = 0;\r
-  Status = Fmp->GetImageInfo (\r
-                  Fmp,\r
-                  &ImageInfoSize,\r
-                  NULL,\r
-                  NULL,\r
-                  NULL,\r
-                  NULL,\r
-                  NULL,\r
-                  NULL\r
-                  );\r
+  Status        = Fmp->GetImageInfo (\r
+                         Fmp,\r
+                         &ImageInfoSize,\r
+                         NULL,\r
+                         NULL,\r
+                         NULL,\r
+                         NULL,\r
+                         NULL,\r
+                         NULL\r
+                         );\r
   if (Status != EFI_BUFFER_TOO_SMALL) {\r
     return 0;\r
   }\r
@@ -1038,20 +892,21 @@ GetFmpImageInfoDescriptorVer (
   }\r
 \r
   PackageVersionName = NULL;\r
-  Status = Fmp->GetImageInfo (\r
-                  Fmp,\r
-                  &ImageInfoSize,               // ImageInfoSize\r
-                  FmpImageInfoBuf,              // ImageInfo\r
-                  &FmpImageInfoDescriptorVer,   // DescriptorVersion\r
-                  &FmpImageInfoCount,           // DescriptorCount\r
-                  &DescriptorSize,              // DescriptorSize\r
-                  &PackageVersion,              // PackageVersion\r
-                  &PackageVersionName           // PackageVersionName\r
-                  );\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool(FmpImageInfoBuf);\r
+  Status             = Fmp->GetImageInfo (\r
+                              Fmp,\r
+                              &ImageInfoSize,             // ImageInfoSize\r
+                              FmpImageInfoBuf,            // ImageInfo\r
+                              &FmpImageInfoDescriptorVer, // DescriptorVersion\r
+                              &FmpImageInfoCount,         // DescriptorCount\r
+                              &DescriptorSize,            // DescriptorSize\r
+                              &PackageVersion,            // PackageVersion\r
+                              &PackageVersionName         // PackageVersionName\r
+                              );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (FmpImageInfoBuf);\r
     return 0;\r
   }\r
+\r
   return FmpImageInfoDescriptorVer;\r
 }\r
 \r
@@ -1066,34 +921,53 @@ GetFmpImageInfoDescriptorVer (
 **/\r
 EFI_STATUS\r
 SetFmpImageData (\r
-  IN EFI_HANDLE                                   Handle,\r
-  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader,\r
-  IN UINTN                                        PayloadIndex\r
+  IN EFI_HANDLE                                    Handle,\r
+  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,\r
+  IN UINTN                                         PayloadIndex\r
   )\r
 {\r
-  EFI_STATUS                                    Status;\r
-  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
-  UINT8                                         *Image;\r
-  VOID                                          *VendorCode;\r
-  CHAR16                                        *AbortReason;\r
-\r
-  Status = gBS->HandleProtocol(\r
+  EFI_STATUS                                     Status;\r
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL               *Fmp;\r
+  UINT8                                          *Image;\r
+  VOID                                           *VendorCode;\r
+  CHAR16                                         *AbortReason;\r
+  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  ProgressCallback;\r
+\r
+  Status = gBS->HandleProtocol (\r
                   Handle,\r
                   &gEfiFirmwareManagementProtocolGuid,\r
                   (VOID **)&Fmp\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
+  //\r
+  // Lookup Firmware Management Progress Protocol before SetImage() is called\r
+  // This is an optional protocol that may not be present on Handle.\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEdkiiFirmwareManagementProgressProtocolGuid,\r
+                  (VOID **)&mFmpProgress\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    mFmpProgress = NULL;\r
+  }\r
+\r
   if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
     Image = (UINT8 *)(ImageHeader + 1);\r
   } else {\r
     //\r
     // If the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER is version 1,\r
-    // Header should exclude UpdateHardwareInstance field\r
+    // Header should exclude UpdateHardwareInstance field, and\r
+    // ImageCapsuleSupport field if version is 2.\r
     //\r
-    Image = (UINT8 *)ImageHeader + OFFSET_OF(EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);\r
+    if (ImageHeader->Version == 1) {\r
+      Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);\r
+    } else {\r
+      Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);\r
+    }\r
   }\r
 \r
   if (ImageHeader->UpdateVendorCodeSize == 0) {\r
@@ -1101,30 +975,57 @@ SetFmpImageData (
   } else {\r
     VendorCode = Image + ImageHeader->UpdateImageSize;\r
   }\r
+\r
   AbortReason = NULL;\r
-  DEBUG((DEBUG_INFO, "Fmp->SetImage ...\n"));\r
-  DEBUG((DEBUG_INFO, "ImageTypeId - %g, ", &ImageHeader->UpdateImageTypeId));\r
-  DEBUG((DEBUG_INFO, "PayloadIndex - 0x%x, ", PayloadIndex));\r
-  DEBUG((DEBUG_INFO, "ImageIndex - 0x%x ", ImageHeader->UpdateImageIndex));\r
-  if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
-    DEBUG((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));\r
+  DEBUG ((DEBUG_INFO, "Fmp->SetImage ...\n"));\r
+  DEBUG ((DEBUG_INFO, "ImageTypeId - %g, ", &ImageHeader->UpdateImageTypeId));\r
+  DEBUG ((DEBUG_INFO, "PayloadIndex - 0x%x, ", PayloadIndex));\r
+  DEBUG ((DEBUG_INFO, "ImageIndex - 0x%x ", ImageHeader->UpdateImageIndex));\r
+  if (ImageHeader->Version >= 2) {\r
+    DEBUG ((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));\r
+    if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
+      DEBUG ((DEBUG_INFO, "(ImageCapsuleSupport - 0x%x)", ImageHeader->ImageCapsuleSupport));\r
+    }\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "\n"));\r
+\r
+  //\r
+  // Before calling SetImage(), reset the progress bar to 0%\r
+  //\r
+  ProgressCallback = UpdateImageProgress;\r
+  Status           = UpdateImageProgress (0);\r
+  if (EFI_ERROR (Status)) {\r
+    ProgressCallback = NULL;\r
   }\r
-  DEBUG((DEBUG_INFO, "\n"));\r
-  Status = Fmp->SetImage(\r
+\r
+  Status = Fmp->SetImage (\r
                   Fmp,\r
                   ImageHeader->UpdateImageIndex,          // ImageIndex\r
                   Image,                                  // Image\r
                   ImageHeader->UpdateImageSize,           // ImageSize\r
                   VendorCode,                             // VendorCode\r
-                  Update_Image_Progress,                  // Progress\r
+                  ProgressCallback,                       // Progress\r
                   &AbortReason                            // AbortReason\r
                   );\r
-  DEBUG((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));\r
+  //\r
+  // Set the progress bar to 100% after returning from SetImage()\r
+  //\r
+  if (ProgressCallback != NULL) {\r
+    UpdateImageProgress (100);\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));\r
   if (AbortReason != NULL) {\r
     DEBUG ((DEBUG_ERROR, "%s\n", AbortReason));\r
-    FreePool(AbortReason);\r
+    FreePool (AbortReason);\r
   }\r
 \r
+  //\r
+  // Clear mFmpProgress after SetImage() returns\r
+  //\r
+  mFmpProgress = NULL;\r
+\r
   return Status;\r
 }\r
 \r
@@ -1142,11 +1043,11 @@ StartFmpImage (
   IN UINTN  ImageSize\r
   )\r
 {\r
-  MEMMAP_DEVICE_PATH                            MemMapNode;\r
-  EFI_STATUS                                    Status;\r
-  EFI_HANDLE                                    ImageHandle;\r
-  EFI_DEVICE_PATH_PROTOCOL                      *DriverDevicePath;\r
-  UINTN                                         ExitDataSize;\r
+  MEMMAP_DEVICE_PATH        MemMapNode;\r
+  EFI_STATUS                Status;\r
+  EFI_HANDLE                ImageHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DriverDevicePath;\r
+  UINTN                     ExitDataSize;\r
 \r
   SetDevicePathNodeLength (&MemMapNode.Header, sizeof (MemMapNode));\r
   MemMapNode.Header.Type     = HARDWARE_DEVICE_PATH;\r
@@ -1160,8 +1061,8 @@ StartFmpImage (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  DEBUG((DEBUG_INFO, "FmpCapsule: LoadImage ...\n"));\r
-  Status = gBS->LoadImage(\r
+  DEBUG ((DEBUG_INFO, "FmpCapsule: LoadImage ...\n"));\r
+  Status = gBS->LoadImage (\r
                   FALSE,\r
                   gImageHandle,\r
                   DriverDevicePath,\r
@@ -1169,55 +1070,67 @@ StartFmpImage (
                   ImageSize,\r
                   &ImageHandle\r
                   );\r
-  DEBUG((DEBUG_INFO, "FmpCapsule: LoadImage - %r\n", Status));\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool(DriverDevicePath);\r
+  DEBUG ((DEBUG_INFO, "FmpCapsule: LoadImage - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created\r
+    // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.\r
+    // If the caller doesn't have the option to defer the execution of an image, we should\r
+    // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.\r
+    //\r
+    if (Status == EFI_SECURITY_VIOLATION) {\r
+      gBS->UnloadImage (ImageHandle);\r
+    }\r
+\r
+    FreePool (DriverDevicePath);\r
     return Status;\r
   }\r
 \r
-  DEBUG((DEBUG_INFO, "FmpCapsule: StartImage ...\n"));\r
-  Status = gBS->StartImage(\r
+  DEBUG ((DEBUG_INFO, "FmpCapsule: StartImage ...\n"));\r
+  Status = gBS->StartImage (\r
                   ImageHandle,\r
                   &ExitDataSize,\r
                   NULL\r
                   );\r
-  DEBUG((DEBUG_INFO, "FmpCapsule: StartImage - %r\n", Status));\r
-  if (EFI_ERROR(Status)) {\r
+  DEBUG ((DEBUG_INFO, "FmpCapsule: StartImage - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
     DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));\r
   }\r
 \r
-  FreePool(DriverDevicePath);\r
+  FreePool (DriverDevicePath);\r
   return Status;\r
 }\r
 \r
 /**\r
   Record FMP capsule status.\r
 \r
-  @param[in]  Handle        A FMP handle.\r
+  @param[in] Handle         A FMP handle.\r
   @param[in] CapsuleHeader  The capsule image header\r
   @param[in] CapsuleStatus  The capsule process stauts\r
   @param[in] PayloadIndex   FMP payload index\r
   @param[in] ImageHeader    FMP image header\r
+  @param[in] CapFileName    Capsule file name\r
 **/\r
 VOID\r
 RecordFmpCapsuleStatus (\r
-  IN EFI_HANDLE                                    Handle,  OPTIONAL\r
+  IN EFI_HANDLE                                    Handle   OPTIONAL,\r
   IN EFI_CAPSULE_HEADER                            *CapsuleHeader,\r
   IN EFI_STATUS                                    CapsuleStatus,\r
   IN UINTN                                         PayloadIndex,\r
-  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader\r
+  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,\r
+  IN CHAR16                                        *CapFileName   OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                                    Status;\r
-  EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath;\r
-  UINT32                                        FmpImageInfoDescriptorVer;\r
-  EFI_STATUS                                    StatusEsrt;\r
-  ESRT_MANAGEMENT_PROTOCOL                      *EsrtProtocol;\r
-  EFI_SYSTEM_RESOURCE_ENTRY                     EsrtEntry;\r
+  EFI_STATUS                 Status;\r
+  EFI_DEVICE_PATH_PROTOCOL   *FmpDevicePath;\r
+  UINT32                     FmpImageInfoDescriptorVer;\r
+  EFI_STATUS                 StatusEsrt;\r
+  ESRT_MANAGEMENT_PROTOCOL   *EsrtProtocol;\r
+  EFI_SYSTEM_RESOURCE_ENTRY  EsrtEntry;\r
 \r
   FmpDevicePath = NULL;\r
   if (Handle != NULL) {\r
-    gBS->HandleProtocol(\r
+    gBS->HandleProtocol (\r
            Handle,\r
            &gEfiDevicePathProtocolGuid,\r
            (VOID **)&FmpDevicePath\r
@@ -1229,36 +1142,38 @@ RecordFmpCapsuleStatus (
     CapsuleStatus,\r
     PayloadIndex,\r
     ImageHeader,\r
-    FmpDevicePath\r
+    FmpDevicePath,\r
+    CapFileName\r
     );\r
 \r
   //\r
   // Update corresponding ESRT entry LastAttemp Status\r
   //\r
-  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);\r
+  Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);\r
   if (EFI_ERROR (Status)) {\r
-    return ;\r
+    return;\r
   }\r
 \r
   if (Handle == NULL) {\r
-    return ;\r
+    return;\r
   }\r
 \r
   //\r
   // Update EsrtEntry For V1, V2 FMP instance.\r
-  // V3 FMP ESRT cache will be synced up through EsrtSyncFmp interface\r
+  // V3 FMP ESRT cache will be synced up through SyncEsrtFmp interface\r
   //\r
   FmpImageInfoDescriptorVer = GetFmpImageInfoDescriptorVer (Handle);\r
   if (FmpImageInfoDescriptorVer < EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) {\r
-    StatusEsrt = EsrtProtocol->GetEsrtEntry(&ImageHeader->UpdateImageTypeId, &EsrtEntry);\r
-    if (!EFI_ERROR(StatusEsrt)){\r
-      if (!EFI_ERROR(CapsuleStatus)) {\r
+    StatusEsrt = EsrtProtocol->GetEsrtEntry (&ImageHeader->UpdateImageTypeId, &EsrtEntry);\r
+    if (!EFI_ERROR (StatusEsrt)) {\r
+      if (!EFI_ERROR (CapsuleStatus)) {\r
         EsrtEntry.LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
       } else {\r
         EsrtEntry.LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;\r
       }\r
+\r
       EsrtEntry.LastAttemptVersion = 0;\r
-      EsrtProtocol->UpdateEsrtEntry(&EsrtEntry);\r
+      EsrtProtocol->UpdateEsrtEntry (&EsrtEntry);\r
     }\r
   }\r
 }\r
@@ -1273,7 +1188,9 @@ RecordFmpCapsuleStatus (
 \r
   This function need support nested FMP capsule.\r
 \r
-  @param[in]   CapsuleHeader         Points to a capsule header.\r
+  @param[in]  CapsuleHeader         Points to a capsule header.\r
+  @param[in]  CapFileName           Capsule file name.\r
+  @param[out] ResetRequired         Indicates whether reset is required or not.\r
 \r
   @retval EFI_SUCESS            Process Capsule Image successfully.\r
   @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.\r
@@ -1283,7 +1200,9 @@ RecordFmpCapsuleStatus (
 **/\r
 EFI_STATUS\r
 ProcessFmpCapsuleImage (\r
-  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader,\r
+  IN CHAR16              *CapFileName   OPTIONAL,\r
+  OUT BOOLEAN            *ResetRequired OPTIONAL\r
   )\r
 {\r
   EFI_STATUS                                    Status;\r
@@ -1293,6 +1212,7 @@ ProcessFmpCapsuleImage (
   UINT32                                        ItemNum;\r
   UINTN                                         Index;\r
   EFI_HANDLE                                    *HandleBuffer;\r
+  BOOLEAN                                       *ResetRequiredBuffer;\r
   UINTN                                         NumberOfHandles;\r
   UINTN                                         DriverLen;\r
   UINT64                                        UpdateHardwareInstance;\r
@@ -1300,20 +1220,21 @@ ProcessFmpCapsuleImage (
   BOOLEAN                                       NotReady;\r
   BOOLEAN                                       Abort;\r
 \r
-  if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {\r
-    return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
+  if (!IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {\r
+    return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), CapFileName, ResetRequired);\r
   }\r
 \r
   NotReady = FALSE;\r
-  Abort = FALSE;\r
+  Abort    = FALSE;\r
 \r
-  DumpFmpCapsule(CapsuleHeader);\r
+  DumpFmpCapsule (CapsuleHeader);\r
 \r
-  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
 \r
   if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
 \r
   ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
@@ -1330,7 +1251,8 @@ ProcessFmpCapsuleImage (
   //\r
   for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {\r
     if ((FmpCapsuleHeader->PayloadItemCount == 0) &&\r
-        (Index == (UINTN)FmpCapsuleHeader->EmbeddedDriverCount - 1)) {\r
+        (Index == (UINTN)FmpCapsuleHeader->EmbeddedDriverCount - 1))\r
+    {\r
       //\r
       // When driver is last element in the ItemOffsetList array, the driver size is calculated by reference CapsuleImageSize in EFI_CAPSULE_HEADER\r
       //\r
@@ -1343,7 +1265,7 @@ ProcessFmpCapsuleImage (
                (UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index],\r
                DriverLen\r
                );\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
       DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));\r
       return Status;\r
     }\r
@@ -1352,7 +1274,7 @@ ProcessFmpCapsuleImage (
   //\r
   // 2. Route payload to right FMP instance\r
   //\r
-  DEBUG((DEBUG_INFO, "FmpCapsule: route payload to right FMP instance ...\n"));\r
+  DEBUG ((DEBUG_INFO, "FmpCapsule: route payload to right FMP instance ...\n"));\r
 \r
   DumpAllFmpInfo ();\r
 \r
@@ -1360,10 +1282,13 @@ ProcessFmpCapsuleImage (
   // Check all the payload entry in capsule payload list\r
   //\r
   for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {\r
-    ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
+    ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
 \r
     UpdateHardwareInstance = 0;\r
-    if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
+    ///\r
+    /// UpdateHardwareInstance field was added in Version 2\r
+    ///\r
+    if (ImageHeader->Version >= 2) {\r
       UpdateHardwareInstance = ImageHeader->UpdateHardwareInstance;\r
     }\r
 \r
@@ -1371,16 +1296,21 @@ ProcessFmpCapsuleImage (
                &ImageHeader->UpdateImageTypeId,\r
                UpdateHardwareInstance,\r
                &NumberOfHandles,\r
-               &HandleBuffer\r
+               &HandleBuffer,\r
+               &ResetRequiredBuffer\r
                );\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status) ||\r
+        (HandleBuffer == NULL) ||\r
+        (ResetRequiredBuffer == NULL))\r
+    {\r
       NotReady = TRUE;\r
       RecordFmpCapsuleStatus (\r
         NULL,\r
         CapsuleHeader,\r
         EFI_NOT_READY,\r
         Index - FmpCapsuleHeader->EmbeddedDriverCount,\r
-        ImageHeader\r
+        ImageHeader,\r
+        CapFileName\r
         );\r
       continue;\r
     }\r
@@ -1392,7 +1322,8 @@ ProcessFmpCapsuleImage (
           CapsuleHeader,\r
           EFI_ABORTED,\r
           Index - FmpCapsuleHeader->EmbeddedDriverCount,\r
-          ImageHeader\r
+          ImageHeader,\r
+          CapFileName\r
           );\r
         continue;\r
       }\r
@@ -1404,6 +1335,10 @@ ProcessFmpCapsuleImage (
                  );\r
       if (Status != EFI_SUCCESS) {\r
         Abort = TRUE;\r
+      } else {\r
+        if (ResetRequired != NULL) {\r
+          *ResetRequired |= ResetRequiredBuffer[Index2];\r
+        }\r
       }\r
 \r
       RecordFmpCapsuleStatus (\r
@@ -1411,11 +1346,17 @@ ProcessFmpCapsuleImage (
         CapsuleHeader,\r
         Status,\r
         Index - FmpCapsuleHeader->EmbeddedDriverCount,\r
-        ImageHeader\r
+        ImageHeader,\r
+        CapFileName\r
         );\r
     }\r
+\r
     if (HandleBuffer != NULL) {\r
-      FreePool(HandleBuffer);\r
+      FreePool (HandleBuffer);\r
+    }\r
+\r
+    if (ResetRequiredBuffer != NULL) {\r
+      FreePool (ResetRequiredBuffer);\r
     }\r
   }\r
 \r
@@ -1440,11 +1381,10 @@ ProcessFmpCapsuleImage (
 **/\r
 BOOLEAN\r
 IsNestedFmpCapsule (\r
-  IN EFI_CAPSULE_HEADER         *CapsuleHeader\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
   )\r
 {\r
   EFI_STATUS                 Status;\r
-  EFI_SYSTEM_RESOURCE_TABLE  *Esrt;\r
   EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;\r
   UINTN                      Index;\r
   BOOLEAN                    EsrtGuidFound;\r
@@ -1454,34 +1394,45 @@ IsNestedFmpCapsule (
   EFI_SYSTEM_RESOURCE_ENTRY  Entry;\r
 \r
   EsrtGuidFound = FALSE;\r
-\r
-  //\r
-  // Check ESRT protocol\r
-  //\r
-  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);\r
-  if (!EFI_ERROR(Status)) {\r
-    Status = EsrtProtocol->GetEsrtEntry(&CapsuleHeader->CapsuleGuid, &Entry);\r
-    if (!EFI_ERROR(Status)) {\r
-      EsrtGuidFound = TRUE;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Check ESRT configuration table\r
-  //\r
-  if (!EsrtGuidFound) {\r
-    Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
-    if (!EFI_ERROR(Status)) {\r
-      ASSERT (Esrt != NULL);\r
-      EsrtEntry = (VOID *)(Esrt + 1);\r
-      for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {\r
-        if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
+  if (mIsVirtualAddrConverted) {\r
+    if (mEsrtTable != NULL) {\r
+      EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);\r
+      for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {\r
+        if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
           EsrtGuidFound = TRUE;\r
           break;\r
         }\r
       }\r
     }\r
+  } else {\r
+    //\r
+    // Check ESRT protocol\r
+    //\r
+    Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = EsrtProtocol->GetEsrtEntry (&CapsuleHeader->CapsuleGuid, &Entry);\r
+      if (!EFI_ERROR (Status)) {\r
+        EsrtGuidFound = TRUE;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Check Firmware Management Protocols\r
+    //\r
+    if (!EsrtGuidFound) {\r
+      Status = GetFmpHandleBufferByType (\r
+                 &CapsuleHeader->CapsuleGuid,\r
+                 0,\r
+                 NULL,\r
+                 NULL,\r
+                 NULL\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        EsrtGuidFound = TRUE;\r
+      }\r
+    }\r
   }\r
+\r
   if (!EsrtGuidFound) {\r
     return FALSE;\r
   }\r
@@ -1491,16 +1442,19 @@ IsNestedFmpCapsule (
   // FMP GUID after ESRT one\r
   //\r
   NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
-  NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize - (UINTN)NestedCapsuleHeader;\r
-  if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {\r
+  NestedCapsuleSize   = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize - (UINTN)NestedCapsuleHeader;\r
+  if (NestedCapsuleSize < sizeof (EFI_CAPSULE_HEADER)) {\r
     return FALSE;\r
   }\r
-  if (!IsValidCapsuleHeader(NestedCapsuleHeader, NestedCapsuleSize)) {\r
+\r
+  if (!IsValidCapsuleHeader (NestedCapsuleHeader, NestedCapsuleSize)) {\r
     return FALSE;\r
   }\r
-  if (!IsFmpCapsuleGuid(&NestedCapsuleHeader->CapsuleGuid)) {\r
+\r
+  if (!IsFmpCapsuleGuid (&NestedCapsuleHeader->CapsuleGuid)) {\r
     return FALSE;\r
   }\r
+\r
   DEBUG ((DEBUG_INFO, "IsNestedFmpCapsule\n"));\r
   return TRUE;\r
 }\r
@@ -1515,15 +1469,17 @@ IsNestedFmpCapsule (
 **/\r
 BOOLEAN\r
 IsFmpCapsule (\r
-  IN EFI_CAPSULE_HEADER         *CapsuleHeader\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
   )\r
 {\r
-  if (IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {\r
+  if (IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {\r
     return TRUE;\r
   }\r
-  if (IsNestedFmpCapsule(CapsuleHeader)) {\r
+\r
+  if (IsNestedFmpCapsule (CapsuleHeader)) {\r
     return TRUE;\r
   }\r
+\r
   return FALSE;\r
 }\r
 \r
@@ -1551,13 +1507,28 @@ SupportCapsuleImage (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (IsFmpCapsule(CapsuleHeader)) {\r
+  //\r
+  // Check capsule file name capsule\r
+  //\r
+  if (IsCapsuleNameCapsule (CapsuleHeader)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (IsFmpCapsule (CapsuleHeader)) {\r
+    //\r
+    // Fake capsule header is valid case in QueryCapsuleCpapbilities().\r
+    //\r
+    if (CapsuleHeader->HeaderSize == CapsuleHeader->CapsuleImageSize) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
     //\r
     // Check layout of FMP capsule\r
     //\r
-    return ValidateFmpCapsule(CapsuleHeader, NULL);\r
+    return ValidateFmpCapsule (CapsuleHeader, NULL);\r
   }\r
-  DEBUG((DEBUG_ERROR, "Unknown Capsule Guid - %g\n", &CapsuleHeader->CapsuleGuid));\r
+\r
+  DEBUG ((DEBUG_ERROR, "Unknown Capsule Guid - %g\n", &CapsuleHeader->CapsuleGuid));\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
@@ -1567,6 +1538,8 @@ SupportCapsuleImage (
   Caution: This function may receive untrusted input.\r
 \r
   @param[in]  CapsuleHeader         Points to a capsule header.\r
+  @param[in]  CapFileName           Capsule file name.\r
+  @param[out] ResetRequired         Indicates whether reset is required or not.\r
 \r
   @retval EFI_SUCESS            Process Capsule Image successfully.\r
   @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.\r
@@ -1575,14 +1548,16 @@ SupportCapsuleImage (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ProcessCapsuleImage (\r
-  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
+ProcessThisCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader,\r
+  IN CHAR16              *CapFileName   OPTIONAL,\r
+  OUT BOOLEAN            *ResetRequired OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
+  EFI_STATUS  Status;\r
 \r
   if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) {\r
-    RecordCapsuleStatusVariable(CapsuleHeader, EFI_UNSUPPORTED);\r
+    RecordCapsuleStatusVariable (CapsuleHeader, EFI_UNSUPPORTED);\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1590,9 +1565,9 @@ ProcessCapsuleImage (
   // Display image in firmware update display capsule\r
   //\r
   if (CompareGuid (&gWindowsUxCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {\r
-    DEBUG((DEBUG_INFO, "ProcessCapsuleImage for WindowsUxCapsule ...\n"));\r
-    Status = DisplayCapsuleImage(CapsuleHeader);\r
-    RecordCapsuleStatusVariable(CapsuleHeader, Status);\r
+    DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for WindowsUxCapsule ...\n"));\r
+    Status = DisplayCapsuleImage (CapsuleHeader);\r
+    RecordCapsuleStatusVariable (CapsuleHeader, Status);\r
     return Status;\r
   }\r
 \r
@@ -1600,21 +1575,21 @@ ProcessCapsuleImage (
   // Check FMP capsule layout\r
   //\r
   if (IsFmpCapsule (CapsuleHeader)) {\r
-    DEBUG((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));\r
-    DEBUG((DEBUG_INFO, "ValidateFmpCapsule ...\n"));\r
-    Status = ValidateFmpCapsule(CapsuleHeader, NULL);\r
-    DEBUG((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));\r
-    if (EFI_ERROR(Status)) {\r
-      RecordCapsuleStatusVariable(CapsuleHeader, Status);\r
+    DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));\r
+    DEBUG ((DEBUG_INFO, "ValidateFmpCapsule ...\n"));\r
+    Status = ValidateFmpCapsule (CapsuleHeader, NULL);\r
+    DEBUG ((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));\r
+    if (EFI_ERROR (Status)) {\r
+      RecordCapsuleStatusVariable (CapsuleHeader, Status);\r
       return Status;\r
     }\r
 \r
     //\r
-    // Press EFI FMP Capsule\r
+    // Process EFI FMP Capsule\r
     //\r
-    DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));\r
-    Status = ProcessFmpCapsuleImage(CapsuleHeader);\r
-    DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));\r
+    DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));\r
+    Status = ProcessFmpCapsuleImage (CapsuleHeader, CapFileName, ResetRequired);\r
+    DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));\r
 \r
     return Status;\r
   }\r
@@ -1622,6 +1597,27 @@ ProcessCapsuleImage (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+/**\r
+  The firmware implements to process the capsule image.\r
+\r
+  Caution: This function may receive untrusted input.\r
+\r
+  @param[in]  CapsuleHeader         Points to a capsule header.\r
+\r
+  @retval EFI_SUCESS            Process Capsule Image successfully.\r
+  @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.\r
+  @retval EFI_VOLUME_CORRUPTED  FV volume in the capsule is corrupted.\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ProcessCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER  *CapsuleHeader\r
+  )\r
+{\r
+  return ProcessThisCapsuleImage (CapsuleHeader, NULL, NULL);\r
+}\r
+\r
 /**\r
   Callback function executed when the EndOfDxe event group is signaled.\r
 \r
@@ -1650,12 +1646,11 @@ DxeCapsuleLibEndOfDxe (
 EFI_STATUS\r
 EFIAPI\r
 DxeCapsuleLibConstructor (\r
-  IN EFI_HANDLE         ImageHandle,\r
-  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_EVENT     EndOfDxeEvent;\r
-  EFI_STATUS    Status;\r
+  EFI_STATUS  Status;\r
 \r
   Status = gBS->CreateEventEx (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -1663,11 +1658,37 @@ DxeCapsuleLibConstructor (
                   DxeCapsuleLibEndOfDxe,\r
                   NULL,\r
                   &gEfiEndOfDxeEventGroupGuid,\r
-                  &EndOfDxeEvent\r
+                  &mDxeCapsuleLibEndOfDxeEvent\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  InitCapsuleVariable();\r
+  InitCapsuleVariable ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The destructor function closes the End of DXE event.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   The destructor completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeCapsuleLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Close the End of DXE event.\r
+  //\r
+  Status = gBS->CloseEvent (mDxeCapsuleLibEndOfDxeEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   return EFI_SUCCESS;\r
 }\r