__FUNCTION__ is a pre-standard extension that gcc and Visual C++ among others support, while __func__ was standardized in C99. Since it's more standard, replace __FUNCTION__ with __func__ throughout MdeModulePkg. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
		
			
				
	
	
		
			519 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			519 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   DXE capsule report related function.
 | |
| 
 | |
|   Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <PiDxe.h>
 | |
| #include <Protocol/FirmwareManagement.h>
 | |
| #include <Guid/CapsuleReport.h>
 | |
| #include <Guid/FmpCapsule.h>
 | |
| #include <Guid/CapsuleVendor.h>
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/UefiRuntimeServicesTableLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include <Library/PcdLib.h>
 | |
| #include <Library/HobLib.h>
 | |
| #include <Library/PrintLib.h>
 | |
| #include <Library/ReportStatusCodeLib.h>
 | |
| #include <Library/DevicePathLib.h>
 | |
| #include <Library/CapsuleLib.h>
 | |
| #include <Library/VariablePolicyHelperLib.h>
 | |
| 
 | |
| #include <IndustryStandard/WindowsUxCapsule.h>
 | |
| 
 | |
| /**
 | |
|   This routine is called to clear CapsuleOnDisk Relocation Info variable.
 | |
|   Total Capsule On Disk length is recorded in this variable
 | |
| 
 | |
|   @retval EFI_SUCCESS   Capsule On Disk flags are cleared
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| CoDClearCapsuleRelocationInfo (
 | |
|   VOID
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   Get current capsule last variable index.
 | |
| 
 | |
|   @return Current capsule last variable index.
 | |
|   @retval -1  No current capsule last variable.
 | |
| **/
 | |
| INTN
 | |
| GetCurrentCapsuleLastIndex (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   UINTN       Size;
 | |
|   CHAR16      CapsuleLastStr[sizeof ("Capsule####")];
 | |
|   EFI_STATUS  Status;
 | |
|   UINT16      CurrentIndex;
 | |
| 
 | |
|   Size   = sizeof (L"Capsule####") - sizeof (CHAR16); // no zero terminator
 | |
|   Status = gRT->GetVariable (
 | |
|                   L"CapsuleLast",
 | |
|                   &gEfiCapsuleReportGuid,
 | |
|                   NULL,
 | |
|                   &Size,
 | |
|                   CapsuleLastStr
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   CurrentIndex = (UINT16)StrHexToUintn (&CapsuleLastStr[sizeof ("Capsule") - 1]);
 | |
|   return CurrentIndex;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get a new capsule status variable index.
 | |
| 
 | |
|   @return A new capsule status variable index.
 | |
|   @retval 0  No new capsule status variable index. Rolling over.
 | |
| **/
 | |
| INTN
 | |
| GetNewCapsuleResultIndex (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   INTN  CurrentIndex;
 | |
| 
 | |
|   CurrentIndex = GetCurrentCapsuleLastIndex ();
 | |
|   if (CurrentIndex >= PcdGet16 (PcdCapsuleMax)) {
 | |
|     DEBUG ((DEBUG_INFO, "  CapsuleResult variable Rolling Over!\n"));
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return CurrentIndex + 1;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Lock Variable by variable policy.
 | |
| 
 | |
|   @param[in] VariableGuid         The Guid of the variable to be locked
 | |
|   @param[in] VariableName         The name of the variable to be locked
 | |
|   @param[in] VariablePolicy       The pointer of variable lock policy
 | |
| **/
 | |
| VOID
 | |
| LockVariable (
 | |
|   IN CONST  EFI_GUID                 VariableGuid,
 | |
|   IN CHAR16                          *VariableName,
 | |
|   IN EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   // Set the policies to protect the target variables
 | |
|   Status = RegisterBasicVariablePolicy (
 | |
|              VariablePolicy,
 | |
|              &VariableGuid,
 | |
|              VariableName,
 | |
|              VARIABLE_POLICY_NO_MIN_SIZE,
 | |
|              VARIABLE_POLICY_NO_MAX_SIZE,
 | |
|              VARIABLE_POLICY_NO_MUST_ATTR,
 | |
|              VARIABLE_POLICY_NO_CANT_ATTR,
 | |
|              VARIABLE_POLICY_TYPE_LOCK_NOW
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((
 | |
|       DEBUG_ERROR,
 | |
|       "DxeCapsuleLibFmp: Failed to lock variable %g %s.  Status = %r\n",
 | |
|       &VariableGuid,
 | |
|       VariableName,
 | |
|       Status
 | |
|       ));
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Write a new capsule status variable.
 | |
| 
 | |
|   @param[in] CapsuleResult      The capsule status variable
 | |
|   @param[in] CapsuleResultSize  The size of the capsule stauts variable in bytes
 | |
| 
 | |
|   @retval EFI_SUCCESS          The capsule status variable is recorded.
 | |
|   @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.
 | |
| **/
 | |
| EFI_STATUS
 | |
| WriteNewCapsuleResultVariable (
 | |
|   IN VOID   *CapsuleResult,
 | |
|   IN UINTN  CapsuleResultSize
 | |
|   )
 | |
| {
 | |
|   INTN        CapsuleResultIndex;
 | |
|   CHAR16      CapsuleResultStr[sizeof ("Capsule####")];
 | |
|   UINTN       Size;
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   CapsuleResultIndex = GetNewCapsuleResultIndex ();
 | |
|   DEBUG ((DEBUG_INFO, "New CapsuleResultIndex - 0x%x\n", CapsuleResultIndex));
 | |
| 
 | |
|   UnicodeSPrint (
 | |
|     CapsuleResultStr,
 | |
|     sizeof (CapsuleResultStr),
 | |
|     L"Capsule%04x",
 | |
|     CapsuleResultIndex
 | |
|     );
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   CapsuleResultStr,
 | |
|                   &gEfiCapsuleReportGuid,
 | |
|                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                   CapsuleResultSize,
 | |
|                   CapsuleResult
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Size = sizeof (L"Capsule####") - sizeof (CHAR16); // no zero terminator
 | |
|     DEBUG ((DEBUG_INFO, "Set CapsuleLast - %s\n", CapsuleResultStr));
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"CapsuleLast",
 | |
|                     &gEfiCapsuleReportGuid,
 | |
|                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                     Size,
 | |
|                     CapsuleResultStr
 | |
|                     );
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Record capsule status variable and to local cache.
 | |
| 
 | |
|   @param[in] CapsuleHeader  The capsule image header
 | |
|   @param[in] CapsuleStatus  The capsule process stauts
 | |
| 
 | |
|   @retval EFI_SUCCESS          The capsule status variable is recorded.
 | |
|   @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.
 | |
| **/
 | |
| EFI_STATUS
 | |
| RecordCapsuleStatusVariable (
 | |
|   IN EFI_CAPSULE_HEADER  *CapsuleHeader,
 | |
|   IN EFI_STATUS          CapsuleStatus
 | |
|   )
 | |
| {
 | |
|   EFI_CAPSULE_RESULT_VARIABLE_HEADER  CapsuleResultVariable;
 | |
|   EFI_STATUS                          Status;
 | |
| 
 | |
|   CapsuleResultVariable.VariableTotalSize = sizeof (CapsuleResultVariable);
 | |
|   CapsuleResultVariable.Reserved          = 0;
 | |
|   CopyGuid (&CapsuleResultVariable.CapsuleGuid, &CapsuleHeader->CapsuleGuid);
 | |
|   ZeroMem (&CapsuleResultVariable.CapsuleProcessed, sizeof (CapsuleResultVariable.CapsuleProcessed));
 | |
|   gRT->GetTime (&CapsuleResultVariable.CapsuleProcessed, NULL);
 | |
|   CapsuleResultVariable.CapsuleStatus = CapsuleStatus;
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
|   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
 | |
|     Status = WriteNewCapsuleResultVariable (&CapsuleResultVariable, sizeof (CapsuleResultVariable));
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Record FMP capsule status variable and to local cache.
 | |
| 
 | |
|   @param[in] CapsuleHeader  The capsule image header
 | |
|   @param[in] CapsuleStatus  The capsule process stauts
 | |
|   @param[in] PayloadIndex   FMP payload index
 | |
|   @param[in] ImageHeader    FMP image header
 | |
|   @param[in] FmpDevicePath  DevicePath associated with the FMP producer
 | |
|   @param[in] CapFileName    Capsule file name
 | |
| 
 | |
|   @retval EFI_SUCCESS          The capsule status variable is recorded.
 | |
|   @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.
 | |
| **/
 | |
| EFI_STATUS
 | |
| RecordFmpCapsuleStatusVariable (
 | |
|   IN EFI_CAPSULE_HEADER                            *CapsuleHeader,
 | |
|   IN EFI_STATUS                                    CapsuleStatus,
 | |
|   IN UINTN                                         PayloadIndex,
 | |
|   IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath  OPTIONAL,
 | |
|   IN CHAR16                                        *CapFileName    OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_CAPSULE_RESULT_VARIABLE_HEADER  *CapsuleResultVariableHeader;
 | |
|   EFI_CAPSULE_RESULT_VARIABLE_FMP     *CapsuleResultVariableFmp;
 | |
|   EFI_STATUS                          Status;
 | |
|   UINT8                               *CapsuleResultVariable;
 | |
|   UINTN                               CapsuleResultVariableSize;
 | |
|   CHAR16                              *DevicePathStr;
 | |
|   UINTN                               DevicePathStrSize;
 | |
|   UINTN                               CapFileNameSize;
 | |
| 
 | |
|   DevicePathStr   = NULL;
 | |
|   CapFileNameSize = sizeof (CHAR16);
 | |
| 
 | |
|   if (FmpDevicePath != NULL) {
 | |
|     DevicePathStr = ConvertDevicePathToText (FmpDevicePath, FALSE, FALSE);
 | |
|   }
 | |
| 
 | |
|   if (DevicePathStr != NULL) {
 | |
|     DevicePathStrSize = StrSize (DevicePathStr);
 | |
|   } else {
 | |
|     DevicePathStrSize = sizeof (CHAR16);
 | |
|   }
 | |
| 
 | |
|   if (CapFileName != NULL) {
 | |
|     CapFileNameSize = StrSize (CapFileName);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Allocate room for CapsuleFileName.
 | |
|   //
 | |
|   CapsuleResultVariableSize = sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof (EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapFileNameSize + DevicePathStrSize;
 | |
| 
 | |
|   CapsuleResultVariable = AllocateZeroPool (CapsuleResultVariableSize);
 | |
|   if (CapsuleResultVariable == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   CapsuleResultVariableHeader                    = (VOID *)CapsuleResultVariable;
 | |
|   CapsuleResultVariableHeader->VariableTotalSize = (UINT32)CapsuleResultVariableSize;
 | |
|   CapsuleResultVariableHeader->Reserved          = 0;
 | |
|   CopyGuid (&CapsuleResultVariableHeader->CapsuleGuid, &CapsuleHeader->CapsuleGuid);
 | |
|   ZeroMem (&CapsuleResultVariableHeader->CapsuleProcessed, sizeof (CapsuleResultVariableHeader->CapsuleProcessed));
 | |
|   gRT->GetTime (&CapsuleResultVariableHeader->CapsuleProcessed, NULL);
 | |
|   CapsuleResultVariableHeader->CapsuleStatus = CapsuleStatus;
 | |
| 
 | |
|   CapsuleResultVariableFmp                   = (VOID *)(CapsuleResultVariable + sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER));
 | |
|   CapsuleResultVariableFmp->Version          = 0x1;
 | |
|   CapsuleResultVariableFmp->PayloadIndex     = (UINT8)PayloadIndex;
 | |
|   CapsuleResultVariableFmp->UpdateImageIndex = ImageHeader->UpdateImageIndex;
 | |
|   CopyGuid (&CapsuleResultVariableFmp->UpdateImageTypeId, &ImageHeader->UpdateImageTypeId);
 | |
| 
 | |
|   if (CapFileName != NULL) {
 | |
|     CopyMem ((UINT8 *)CapsuleResultVariableFmp + sizeof (EFI_CAPSULE_RESULT_VARIABLE_FMP), CapFileName, CapFileNameSize);
 | |
|   }
 | |
| 
 | |
|   if (DevicePathStr != NULL) {
 | |
|     CopyMem ((UINT8 *)CapsuleResultVariableFmp + sizeof (EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapFileNameSize, DevicePathStr, DevicePathStrSize);
 | |
|     FreePool (DevicePathStr);
 | |
|     DevicePathStr = NULL;
 | |
|   }
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
|   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
 | |
|     Status = WriteNewCapsuleResultVariable (CapsuleResultVariable, CapsuleResultVariableSize);
 | |
|   }
 | |
| 
 | |
|   FreePool (CapsuleResultVariable);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Initialize CapsuleMax variables.
 | |
| 
 | |
|   @param[in] VariablePolicy       The pointer of variable lock policy
 | |
| **/
 | |
| VOID
 | |
| InitCapsuleMaxVariable (
 | |
|   EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINTN       Size;
 | |
|   CHAR16      CapsuleMaxStr[sizeof ("Capsule####")];
 | |
| 
 | |
|   UnicodeSPrint (
 | |
|     CapsuleMaxStr,
 | |
|     sizeof (CapsuleMaxStr),
 | |
|     L"Capsule%04x",
 | |
|     PcdGet16 (PcdCapsuleMax)
 | |
|     );
 | |
| 
 | |
|   Size   = sizeof (L"Capsule####") - sizeof (CHAR16); // no zero terminator
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"CapsuleMax",
 | |
|                   &gEfiCapsuleReportGuid,
 | |
|                   EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                   Size,
 | |
|                   CapsuleMaxStr
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     // Lock it per UEFI spec.
 | |
|     LockVariable (gEfiCapsuleReportGuid, L"CapsuleMax", VariablePolicy);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Initialize CapsuleLast variables.
 | |
| 
 | |
|   @param[in] VariablePolicy       The pointer of variable lock policy
 | |
| **/
 | |
| VOID
 | |
| InitCapsuleLastVariable (
 | |
|   EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS     Status;
 | |
|   EFI_BOOT_MODE  BootMode;
 | |
|   VOID           *CapsuleResult;
 | |
|   UINTN          Size;
 | |
|   CHAR16         CapsuleLastStr[sizeof ("Capsule####")];
 | |
| 
 | |
|   BootMode = GetBootModeHob ();
 | |
|   if (BootMode == BOOT_ON_FLASH_UPDATE) {
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"CapsuleLast",
 | |
|                     &gEfiCapsuleReportGuid,
 | |
|                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                     0,
 | |
|                     NULL
 | |
|                     );
 | |
|     // Do not lock it because it will be updated later.
 | |
|   } else {
 | |
|     //
 | |
|     // Check if OS/APP cleared L"Capsule####"
 | |
|     //
 | |
|     ZeroMem (CapsuleLastStr, sizeof (CapsuleLastStr));
 | |
|     Size   = sizeof (L"Capsule####") - sizeof (CHAR16); // no zero terminator
 | |
|     Status = gRT->GetVariable (
 | |
|                     L"CapsuleLast",
 | |
|                     &gEfiCapsuleReportGuid,
 | |
|                     NULL,
 | |
|                     &Size,
 | |
|                     CapsuleLastStr
 | |
|                     );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       //
 | |
|       // L"CapsuleLast" is got, check if data is there.
 | |
|       //
 | |
|       Status = GetVariable2 (
 | |
|                  CapsuleLastStr,
 | |
|                  &gEfiCapsuleReportGuid,
 | |
|                  (VOID **)&CapsuleResult,
 | |
|                  NULL
 | |
|                  );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         //
 | |
|         // If no data, delete L"CapsuleLast"
 | |
|         //
 | |
|         Status = gRT->SetVariable (
 | |
|                         L"CapsuleLast",
 | |
|                         &gEfiCapsuleReportGuid,
 | |
|                         EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                         0,
 | |
|                         NULL
 | |
|                         );
 | |
|       } else {
 | |
|         if (CapsuleResult != NULL) {
 | |
|           FreePool (CapsuleResult);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // Lock it in normal boot path per UEFI spec.
 | |
|     LockVariable (gEfiCapsuleReportGuid, L"CapsuleLast", VariablePolicy);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Initialize capsule update variables.
 | |
| **/
 | |
| VOID
 | |
| InitCapsuleUpdateVariable (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINTN       Index;
 | |
|   CHAR16      CapsuleVarName[30];
 | |
|   CHAR16      *TempVarName;
 | |
| 
 | |
|   //
 | |
|   // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
 | |
|   // as early as possible which will avoid the next time boot after the capsule update
 | |
|   // will still into the capsule loop
 | |
|   //
 | |
|   StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CapsuleVarName[0]), EFI_CAPSULE_VARIABLE_NAME);
 | |
|   TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
 | |
|   Index       = 0;
 | |
|   while (TRUE) {
 | |
|     if (Index > 0) {
 | |
|       UnicodeValueToStringS (
 | |
|         TempVarName,
 | |
|         sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
 | |
|         0,
 | |
|         Index,
 | |
|         0
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     Status = gRT->SetVariable (
 | |
|                     CapsuleVarName,
 | |
|                     &gEfiCapsuleVendorGuid,
 | |
|                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
 | |
|                     0,
 | |
|                     (VOID *)NULL
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       //
 | |
|       // There is no capsule variables, quit
 | |
|       //
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     Index++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Initialize capsule relocation info variable.
 | |
| 
 | |
|   @param[in] VariablePolicy       The pointer of variable lock policy
 | |
| **/
 | |
| VOID
 | |
| InitCapsuleRelocationInfo (
 | |
|   EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy
 | |
|   )
 | |
| {
 | |
|   CoDClearCapsuleRelocationInfo ();
 | |
| 
 | |
|   //
 | |
|   // Unlock Capsule On Disk relocation Info variable only when Capsule On Disk flag is enabled
 | |
|   //
 | |
|   if (!CoDCheckCapsuleOnDiskFlag ()) {
 | |
|     LockVariable (gEfiCapsuleVendorGuid, COD_RELOCATION_INFO_VAR_NAME, VariablePolicy);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Initialize capsule related variables.
 | |
| **/
 | |
| VOID
 | |
| InitCapsuleVariable (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy;
 | |
| 
 | |
|   // Locate the VariablePolicy protocol
 | |
|   Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "DxeCapsuleReportLib %a - Could not locate VariablePolicy protocol! %r\n", __func__, Status));
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
|   }
 | |
| 
 | |
|   InitCapsuleUpdateVariable ();
 | |
|   InitCapsuleMaxVariable (VariablePolicy);
 | |
|   InitCapsuleLastVariable (VariablePolicy);
 | |
|   InitCapsuleRelocationInfo (VariablePolicy);
 | |
| 
 | |
|   //
 | |
|   // No need to clear L"Capsule####", because OS/APP should refer L"CapsuleLast"
 | |
|   // to check status and delete them.
 | |
|   //
 | |
| }
 |