]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
MdeModulePkg/DxeCapsuleLibFmp: Use new Variable Lock interface
[mirror_edk2.git] / MdeModulePkg / Library / DxeCapsuleLibFmp / DxeCapsuleLib.c
index 3c283e251331bb6109a8d776383af0c02e5f6621..90942135d70074ea91381dac1f97e4ada1d83b41 100644 (file)
   ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and\r
   performs basic validation.\r
 \r
-  Copyright (c) 2016 - 2018, 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
@@ -39,7 +33,6 @@
 #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
@@ -87,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
@@ -97,7 +91,8 @@ 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
@@ -116,6 +111,22 @@ UpdateImageProgress (
   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 CompareGuid (&CapsuleHeader->CapsuleGuid, &gEdkiiCapsuleOnDiskNameGuid);\r
+}\r
+\r
 /**\r
   Return if this CapsuleGuid is a FMP capsule GUID or not.\r
 \r
@@ -274,8 +285,10 @@ ValidateFmpCapsule (
       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
+    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
     if (FmpImageSize < FmpImageHeaderSize) {\r
       DEBUG((DEBUG_ERROR, "FmpImageSize(0x%lx) < FmpImageHeaderSize(0x%x)\n", FmpImageSize, FmpImageHeaderSize));\r
@@ -508,8 +521,11 @@ DumpFmpCapsule (
     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
+    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
@@ -610,6 +626,8 @@ DumpAllFmpInfo (
     FreePool(FmpImageInfoBuf);\r
   }\r
 \r
+  FreePool (HandleBuffer);\r
+\r
   return ;\r
 }\r
 \r
@@ -618,11 +636,14 @@ 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
@@ -630,14 +651,16 @@ EFI_STATUS
 GetFmpHandleBufferByType (\r
   IN     EFI_GUID                     *UpdateImageTypeId,\r
   IN     UINT64                       UpdateHardwareInstance,\r
-  IN OUT UINTN                        *NoHandles,\r
-  OUT    EFI_HANDLE                   **Buffer\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
+  BOOLEAN                                       *MatchedResetRequiredBuffer;\r
   UINTN                                         MatchedNumberOfHandles;\r
   EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
   UINTN                                         Index;\r
@@ -651,8 +674,15 @@ GetFmpHandleBufferByType (
   UINTN                                         Index2;\r
   EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *TempFmpImageInfo;\r
 \r
-  *NoHandles = 0;\r
-  *Buffer = NULL;\r
+  if (NoHandles != NULL) {\r
+    *NoHandles = 0;\r
+  }\r
+  if (HandleBuf != NULL) {\r
+    *HandleBuf = NULL;\r
+  }\r
+  if (ResetRequiredBuf != NULL) {\r
+    *ResetRequiredBuf = NULL;\r
+  }\r
 \r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
@@ -666,10 +696,26 @@ GetFmpHandleBufferByType (
   }\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
+      FreePool (HandleBuffer);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
   }\r
 \r
   for (Index = 0; Index < NumberOfHandles; Index++) {\r
@@ -731,7 +777,15 @@ GetFmpHandleBufferByType (
         if ((UpdateHardwareInstance == 0) ||\r
             ((FmpImageInfoDescriptorVer >= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) &&\r
              (UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance))) {\r
-          MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];\r
+          if (MatchedHandleBuffer != NULL) {\r
+            MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];\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
           MatchedNumberOfHandles++;\r
           break;\r
         }\r
@@ -741,12 +795,21 @@ GetFmpHandleBufferByType (
     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
+  if (HandleBuf != NULL) {\r
+    *HandleBuf = MatchedHandleBuffer;\r
+  }\r
+  if (ResetRequiredBuf != NULL) {\r
+    *ResetRequiredBuf = MatchedResetRequiredBuffer;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -870,9 +933,14 @@ SetFmpImageData (
   } 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
@@ -885,8 +953,11 @@ SetFmpImageData (
   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
+  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
   DEBUG((DEBUG_INFO, "\n"));\r
 \r
@@ -972,6 +1043,15 @@ StartFmpImage (
                   );\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
     FreePool(DriverDevicePath);\r
     return Status;\r
   }\r
@@ -994,11 +1074,12 @@ StartFmpImage (
 /**\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
@@ -1006,7 +1087,8 @@ RecordFmpCapsuleStatus (
   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
@@ -1030,7 +1112,8 @@ RecordFmpCapsuleStatus (
     CapsuleStatus,\r
     PayloadIndex,\r
     ImageHeader,\r
-    FmpDevicePath\r
+    FmpDevicePath,\r
+    CapFileName\r
     );\r
 \r
   //\r
@@ -1074,7 +1157,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
@@ -1084,7 +1169,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
@@ -1094,6 +1181,7 @@ ProcessFmpCapsuleImage (
   UINT32                                        ItemNum;\r
   UINTN                                         Index;\r
   EFI_HANDLE                                    *HandleBuffer;\r
+  BOOLEAN                                       *ResetRequiredBuffer;\r
   UINTN                                         NumberOfHandles;\r
   UINTN                                         DriverLen;\r
   UINT64                                        UpdateHardwareInstance;\r
@@ -1102,7 +1190,7 @@ ProcessFmpCapsuleImage (
   BOOLEAN                                       Abort;\r
 \r
   if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {\r
-    return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
+    return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), CapFileName, ResetRequired);\r
   }\r
 \r
   NotReady = FALSE;\r
@@ -1164,7 +1252,10 @@ ProcessFmpCapsuleImage (
     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
@@ -1172,16 +1263,20 @@ 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
       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
@@ -1193,7 +1288,8 @@ ProcessFmpCapsuleImage (
           CapsuleHeader,\r
           EFI_ABORTED,\r
           Index - FmpCapsuleHeader->EmbeddedDriverCount,\r
-          ImageHeader\r
+          ImageHeader,\r
+          CapFileName\r
           );\r
         continue;\r
       }\r
@@ -1205,6 +1301,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
@@ -1212,12 +1312,16 @@ ProcessFmpCapsuleImage (
         CapsuleHeader,\r
         Status,\r
         Index - FmpCapsuleHeader->EmbeddedDriverCount,\r
-        ImageHeader\r
+        ImageHeader,\r
+        CapFileName\r
         );\r
     }\r
     if (HandleBuffer != NULL) {\r
       FreePool(HandleBuffer);\r
     }\r
+    if (ResetRequiredBuffer != NULL) {\r
+      FreePool(ResetRequiredBuffer);\r
+    }\r
   }\r
 \r
   if (NotReady) {\r
@@ -1252,8 +1356,6 @@ IsNestedFmpCapsule (
   UINTN                      NestedCapsuleSize;\r
   ESRT_MANAGEMENT_PROTOCOL   *EsrtProtocol;\r
   EFI_SYSTEM_RESOURCE_ENTRY  Entry;\r
-  EFI_HANDLE                 *HandleBuffer;\r
-  UINTN                      NumberOfHandles;\r
 \r
   EsrtGuidFound = FALSE;\r
   if (mIsVirtualAddrConverted) {\r
@@ -1282,19 +1384,16 @@ IsNestedFmpCapsule (
     // Check Firmware Management Protocols\r
     //\r
     if (!EsrtGuidFound) {\r
-      HandleBuffer = NULL;\r
       Status = GetFmpHandleBufferByType (\r
                  &CapsuleHeader->CapsuleGuid,\r
                  0,\r
-                 &NumberOfHandles,\r
-                 &HandleBuffer\r
+                 NULL,\r
+                 NULL,\r
+                 NULL\r
                  );\r
       if (!EFI_ERROR(Status)) {\r
         EsrtGuidFound = TRUE;\r
       }\r
-      if (HandleBuffer != NULL) {\r
-        FreePool (HandleBuffer);\r
-      }\r
     }\r
   }\r
   if (!EsrtGuidFound) {\r
@@ -1366,7 +1465,20 @@ SupportCapsuleImage (
     return EFI_SUCCESS;\r
   }\r
 \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
     // Check layout of FMP capsule\r
     //\r
@@ -1382,6 +1494,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
@@ -1390,8 +1504,10 @@ 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
@@ -1428,7 +1544,7 @@ ProcessCapsuleImage (
     // Process EFI FMP Capsule\r
     //\r
     DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));\r
-    Status = ProcessFmpCapsuleImage(CapsuleHeader);\r
+    Status = ProcessFmpCapsuleImage(CapsuleHeader, CapFileName, ResetRequired);\r
     DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));\r
 \r
     return Status;\r
@@ -1437,6 +1553,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