REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the FmpDevicePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			219 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Provides FMP capsule dependency check services when updating the firmware
 | 
						|
  image of a FMP device.
 | 
						|
 | 
						|
  Copyright (c) Microsoft Corporation.<BR>
 | 
						|
  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
#include <PiDxe.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/FmpDependencyLib.h>
 | 
						|
#include <Library/FmpDependencyCheckLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Guid/SystemResourceTable.h>
 | 
						|
#include <LastAttemptStatus.h>
 | 
						|
#include <FmpLastAttemptStatus.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Check dependency for firmware update.
 | 
						|
 | 
						|
  @param[in]  ImageTypeId        Image Type Id.
 | 
						|
  @param[in]  Version            New version.
 | 
						|
  @param[in]  Dependencies       Fmp dependency.
 | 
						|
  @param[in]  DependenciesSize   Size, in bytes, of the Fmp dependency.
 | 
						|
  @param[out] LastAttemptStatus  An optional pointer to a UINT32 that holds the
 | 
						|
                                 last attempt status to report back to the caller.
 | 
						|
                                 This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS
 | 
						|
                                 if an error code is not set.
 | 
						|
 | 
						|
  @retval  TRUE    Dependencies are satisfied.
 | 
						|
  @retval  FALSE   Dependencies are unsatisfied or dependency check fails.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
CheckFmpDependency (
 | 
						|
  IN  EFI_GUID                ImageTypeId,
 | 
						|
  IN  UINT32                  Version,
 | 
						|
  IN  EFI_FIRMWARE_IMAGE_DEP  *Dependencies     OPTIONAL,
 | 
						|
  IN  UINT32                  DependenciesSize,
 | 
						|
  OUT UINT32                  *LastAttemptStatus OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  EFI_HANDLE                        *HandleBuffer;
 | 
						|
  UINTN                             Index;
 | 
						|
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
 | 
						|
  UINTN                             ImageInfoSize;
 | 
						|
  UINT32                            LocalLastAttemptStatus;
 | 
						|
  UINT32                            *DescriptorVer;
 | 
						|
  UINT8                             FmpImageInfoCount;
 | 
						|
  UINTN                             *DescriptorSize;
 | 
						|
  UINT32                            PackageVersion;
 | 
						|
  CHAR16                            *PackageVersionName;
 | 
						|
  UINTN                             NumberOfFmpInstance;
 | 
						|
  EFI_FIRMWARE_IMAGE_DESCRIPTOR     **FmpImageInfoBuf;
 | 
						|
  FMP_DEPEX_CHECK_VERSION_DATA      *FmpVersions;
 | 
						|
  UINTN                             FmpVersionsCount;
 | 
						|
  BOOLEAN                           IsSatisfied;
 | 
						|
 | 
						|
  LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
 | 
						|
  FmpImageInfoBuf        = NULL;
 | 
						|
  DescriptorVer          = NULL;
 | 
						|
  DescriptorSize         = NULL;
 | 
						|
  NumberOfFmpInstance    = 0;
 | 
						|
  FmpVersions            = NULL;
 | 
						|
  FmpVersionsCount       = 0;
 | 
						|
  IsSatisfied            = TRUE;
 | 
						|
  PackageVersionName     = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
 | 
						|
  //
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                  ByProtocol,
 | 
						|
                  &gEfiFirmwareManagementProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  &NumberOfFmpInstance,
 | 
						|
                  &HandleBuffer
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
 | 
						|
    IsSatisfied            = FALSE;
 | 
						|
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND;
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
  FmpImageInfoBuf = AllocateZeroPool (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
 | 
						|
  if (FmpImageInfoBuf == NULL) {
 | 
						|
    IsSatisfied            = FALSE;
 | 
						|
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED;
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
  DescriptorVer = AllocateZeroPool (sizeof (UINT32) * NumberOfFmpInstance);
 | 
						|
  if (DescriptorVer == NULL ) {
 | 
						|
    IsSatisfied            = FALSE;
 | 
						|
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED;
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
  DescriptorSize = AllocateZeroPool (sizeof (UINTN) * NumberOfFmpInstance);
 | 
						|
  if (DescriptorSize == NULL ) {
 | 
						|
    IsSatisfied            = FALSE;
 | 
						|
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED;
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
  FmpVersions = AllocateZeroPool (sizeof (FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
 | 
						|
  if (FmpVersions == NULL) {
 | 
						|
    IsSatisfied            = FALSE;
 | 
						|
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED;
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < NumberOfFmpInstance; Index++) {
 | 
						|
    Status = gBS->HandleProtocol (
 | 
						|
                    HandleBuffer[Index],
 | 
						|
                    &gEfiFirmwareManagementProtocolGuid,
 | 
						|
                    (VOID **)&Fmp
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    ImageInfoSize = 0;
 | 
						|
    Status        = Fmp->GetImageInfo (
 | 
						|
                           Fmp,
 | 
						|
                           &ImageInfoSize,
 | 
						|
                           NULL,
 | 
						|
                           NULL,
 | 
						|
                           NULL,
 | 
						|
                           NULL,
 | 
						|
                           NULL,
 | 
						|
                           NULL
 | 
						|
                           );
 | 
						|
    if (Status != EFI_BUFFER_TOO_SMALL) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);
 | 
						|
    if (FmpImageInfoBuf[Index] == NULL) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Fmp->GetImageInfo (
 | 
						|
                    Fmp,
 | 
						|
                    &ImageInfoSize,               // ImageInfoSize
 | 
						|
                    FmpImageInfoBuf[Index],       // ImageInfo
 | 
						|
                    &DescriptorVer[Index],        // DescriptorVersion
 | 
						|
                    &FmpImageInfoCount,           // DescriptorCount
 | 
						|
                    &DescriptorSize[Index],       // DescriptorSize
 | 
						|
                    &PackageVersion,              // PackageVersion
 | 
						|
                    &PackageVersionName           // PackageVersionName
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (FmpImageInfoBuf[Index]);
 | 
						|
      FmpImageInfoBuf[Index] = NULL;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (PackageVersionName != NULL) {
 | 
						|
      FreePool (PackageVersionName);
 | 
						|
      PackageVersionName = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId);
 | 
						|
    FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version;
 | 
						|
    FmpVersionsCount++;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Evaluate firmware image's depex, against the version of other Fmp instances.
 | 
						|
  //
 | 
						|
  if (Dependencies != NULL) {
 | 
						|
    IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount, &LocalLastAttemptStatus);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsSatisfied) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId));
 | 
						|
    goto cleanup;
 | 
						|
  }
 | 
						|
 | 
						|
cleanup:
 | 
						|
  if (FmpImageInfoBuf != NULL) {
 | 
						|
    for (Index = 0; Index < NumberOfFmpInstance; Index++) {
 | 
						|
      if (FmpImageInfoBuf[Index] != NULL) {
 | 
						|
        FreePool (FmpImageInfoBuf[Index]);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    FreePool (FmpImageInfoBuf);
 | 
						|
  }
 | 
						|
 | 
						|
  if (DescriptorVer != NULL) {
 | 
						|
    FreePool (DescriptorVer);
 | 
						|
  }
 | 
						|
 | 
						|
  if (DescriptorSize != NULL) {
 | 
						|
    FreePool (DescriptorSize);
 | 
						|
  }
 | 
						|
 | 
						|
  if (FmpVersions != NULL) {
 | 
						|
    FreePool (FmpVersions);
 | 
						|
  }
 | 
						|
 | 
						|
  if (LastAttemptStatus != NULL) {
 | 
						|
    *LastAttemptStatus = LocalLastAttemptStatus;
 | 
						|
  }
 | 
						|
 | 
						|
  return IsSatisfied;
 | 
						|
}
 |