/** @file
  Produces a Firmware Management Protocol that supports updates to a firmware
  image stored in a firmware device with platform and firmware device specific
  information provided through PCDs and libraries.

  Copyright (c) Microsoft Corporation.<BR>
  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FmpDxe.h"
#include "VariableSupport.h"

///
/// FILE_GUID from FmpDxe.inf.  When FmpDxe.inf is used in a platform, the
/// FILE_GUID must always be overridden in the <Defines> section to provide
/// the ESRT GUID value associated with the updatable firmware image.  A
/// check is made in this module's driver entry point to verify that a
/// new FILE_GUID value has been defined.
///
const EFI_GUID  mDefaultModuleFileGuid = {
  0x78ef0a56, 0x1cf0, 0x4535, { 0xb5, 0xda, 0xf6, 0xfd, 0x2f, 0x40, 0x5a, 0x11 }
};

///
/// TRUE if FmpDeviceLib manages a single firmware storage device.
///
BOOLEAN  mFmpSingleInstance = FALSE;

///
/// Firmware Management Protocol instance that is initialized in the entry
/// point from PCD settings.
///
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  mFmpProgress;

//
// Template of the private context structure for the Firmware Management
// Protocol instance
//
const FIRMWARE_MANAGEMENT_PRIVATE_DATA  mFirmwareManagementPrivateDataTemplate = {
  FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE, // Signature
  NULL,                                       // Handle
  {                                            // Fmp
    GetTheImageInfo,
    GetTheImage,
    SetTheImage,
    CheckTheImage,
    GetPackageInfo,
    SetPackageInfo
  },
  FALSE,            // DescriptorPopulated
  {                 // Desc
    1,              // ImageIndex
    //
    // ImageTypeId
    //
    { 0x00000000,   0x0000,0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
    },
    1,     // ImageId
    NULL,  // ImageIdName
    0,     // Version
    NULL,  // VersionName
    0,     // Size
    0,     // AttributesSupported
    0,     // AttributesSetting
    0,     // Compatibilities
    0,     // LowestSupportedImageVersion
    0,     // LastAttemptVersion
    0,     // LastAttemptStatus
    0      // HardwareInstance
  },
  NULL,             // ImageIdName
  NULL,             // VersionName
  TRUE,             // RuntimeVersionSupported
  NULL,             // FmpDeviceLockEvent
  FALSE,            // FmpDeviceLocked
  NULL,             // FmpDeviceContext
  NULL,             // VersionVariableName
  NULL,             // LsvVariableName
  NULL,             // LastAttemptStatusVariableName
  NULL,             // LastAttemptVersionVariableName
  NULL,             // FmpStateVariableName
  TRUE              // DependenciesSatisfied
};

///
/// GUID that is used to create event used to lock the firmware storage device.
///
EFI_GUID  *mLockGuid = NULL;

///
/// Progress() function pointer passed into SetTheImage()
///
EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  mProgressFunc = NULL;

///
/// Null-terminated Unicode string retrieved from PcdFmpDeviceImageIdName.
///
CHAR16  *mImageIdName = NULL;

/**
  Callback function to report the process of the firmware updating.

  Wrap the caller's version in this so that progress from the device lib is
  within the expected range.  Convert device lib 0% - 100% to 6% - 98%.

  FmpDxe        1% -   5%  for validation
  FmpDeviceLib  6% -  98%  for flashing/update
  FmpDxe       99% - 100%  finish

  @param[in] Completion  A value between 1 and 100 indicating the current
                         completion progress of the firmware update. Completion
                         progress is reported as from 1 to 100 percent. A value
                         of 0 is used by the driver to indicate that progress
                         reporting is not supported.

  @retval  EFI_SUCCESS      The progress was updated.
  @retval  EFI_UNSUPPORTED  Updating progress is not supported.

**/
EFI_STATUS
EFIAPI
FmpDxeProgress (
  IN UINTN  Completion
  )
{
  EFI_STATUS  Status;

  Status = EFI_UNSUPPORTED;

  if (mProgressFunc == NULL) {
    return Status;
  }

  //
  // Reserve 6% - 98% for the FmpDeviceLib.  Call the real progress function.
  //
  Status = mProgressFunc (((Completion * 92) / 100) + 6);

  if (Status == EFI_UNSUPPORTED) {
    mProgressFunc = NULL;
  }

  return Status;
}

/**
  Returns a pointer to the ImageTypeId GUID value.  An attempt is made to get
  the GUID value from the FmpDeviceLib. If the FmpDeviceLib does not provide
  a GUID value, then PcdFmpDeviceImageTypeIdGuid is used.  If the size of
  PcdFmpDeviceImageTypeIdGuid is not the size of EFI_GUID, then gEfiCallerIdGuid
  is returned.

  @retval  The ImageTypeId GUID

**/
EFI_GUID *
GetImageTypeIdGuid (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_GUID    *FmpDeviceLibGuid;
  UINTN       ImageTypeIdGuidSize;

  FmpDeviceLibGuid = NULL;
  Status           = FmpDeviceGetImageTypeIdGuidPtr (&FmpDeviceLibGuid);
  if (EFI_ERROR (Status)) {
    if (Status != EFI_UNSUPPORTED) {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid error %r\n", mImageIdName, Status));
    }
  } else if (FmpDeviceLibGuid == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid GUID\n", mImageIdName));
    Status = EFI_NOT_FOUND;
  }

  if (EFI_ERROR (Status)) {
    ImageTypeIdGuidSize = PcdGetSize (PcdFmpDeviceImageTypeIdGuid);
    if (ImageTypeIdGuidSize == sizeof (EFI_GUID)) {
      FmpDeviceLibGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceImageTypeIdGuid);
    } else {
      DEBUG ((DEBUG_WARN, "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid\n", mImageIdName));
      FmpDeviceLibGuid = &gEfiCallerIdGuid;
    }
  }

  return FmpDeviceLibGuid;
}

/**
  Returns a pointer to the Null-terminated Unicode ImageIdName string.

  @retval  Null-terminated Unicode ImageIdName string.

**/
CHAR16 *
GetImageTypeNameString (
  VOID
  )
{
  return mImageIdName;
}

/**
  Lowest supported version is a combo of three parts.
  1. Check if the device lib has a lowest supported version
  2. Check if we have a variable for lowest supported version (this will be updated with each capsule applied)
  3. Check Fixed at build PCD

  @param[in] Private  Pointer to the private context structure for the
                      Firmware Management Protocol instance.

  @retval  The largest value

**/
UINT32
GetLowestSupportedVersion (
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS  Status;
  UINT32      DeviceLibLowestSupportedVersion;
  UINT32      VariableLowestSupportedVersion;
  UINT32      ReturnLsv;

  //
  // Get the LowestSupportedVersion.
  //

  if (!IsLowestSupportedVersionCheckRequired ()) {
    //
    // Any Version can pass the 0 LowestSupportedVersion check.
    //
    return 0;
  }

  ReturnLsv = PcdGet32 (PcdFmpDeviceBuildTimeLowestSupportedVersion);

  //
  // Check the FmpDeviceLib
  //
  DeviceLibLowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
  Status                          = FmpDeviceGetLowestSupportedVersion (&DeviceLibLowestSupportedVersion);
  if (EFI_ERROR (Status)) {
    DeviceLibLowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
  }

  if (DeviceLibLowestSupportedVersion > ReturnLsv) {
    ReturnLsv = DeviceLibLowestSupportedVersion;
  }

  //
  // Check the lowest supported version UEFI variable for this device
  //
  VariableLowestSupportedVersion = GetLowestSupportedVersionFromVariable (Private);
  if (VariableLowestSupportedVersion > ReturnLsv) {
    ReturnLsv = VariableLowestSupportedVersion;
  }

  //
  // Return the largest value
  //
  return ReturnLsv;
}

/**
  Populates the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure in the private
  context structure.

  @param[in] Private  Pointer to the private context structure for the
                      Firmware Management Protocol instance.

**/
VOID
PopulateDescriptor (
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS  Status;
  UINT32      DependenciesSize;

  if (Private == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): PopulateDescriptor() - Private is NULL.\n", mImageIdName));
    return;
  }

  if (Private->DescriptorPopulated) {
    return;
  }

  Private->Descriptor.ImageIndex = 1;
  CopyGuid (&Private->Descriptor.ImageTypeId, GetImageTypeIdGuid ());
  Private->Descriptor.ImageId     = Private->Descriptor.ImageIndex;
  Private->Descriptor.ImageIdName = GetImageTypeNameString ();

  //
  // Get the hardware instance from FmpDeviceLib
  //
  Status = FmpDeviceGetHardwareInstance (&Private->Descriptor.HardwareInstance);
  if (Status == EFI_UNSUPPORTED) {
    Private->Descriptor.HardwareInstance = 0;
  }

  //
  // Generate UEFI Variable names used to store status information for this
  // FMP instance.
  //
  GenerateFmpVariableNames (Private);

  //
  // Get the version.  Some devices don't support getting the firmware version
  // at runtime.  If FmpDeviceLib does not support returning a version, then
  // it is stored in a UEFI variable.
  //
  Status = FmpDeviceGetVersion (&Private->Descriptor.Version);
  if (Status == EFI_UNSUPPORTED) {
    Private->RuntimeVersionSupported = FALSE;
    Private->Descriptor.Version      = GetVersionFromVariable (Private);
  } else if (EFI_ERROR (Status)) {
    //
    // Unexpected error.   Use default version.
    //
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetVersion() from FmpDeviceLib (%s) returned %r\n", mImageIdName, GetImageTypeNameString (), Status));
    Private->Descriptor.Version = DEFAULT_VERSION;
  }

  //
  // Free the current version name.  Shouldn't really happen but this populate
  // function could be called multiple times (to refresh).
  //
  if (Private->Descriptor.VersionName != NULL) {
    FreePool (Private->Descriptor.VersionName);
    Private->Descriptor.VersionName = NULL;
  }

  //
  // Attempt to get the version string from the FmpDeviceLib
  //
  Status = FmpDeviceGetVersionString (&Private->Descriptor.VersionName);
  if (Status == EFI_UNSUPPORTED) {
    DEBUG ((DEBUG_INFO, "FmpDxe(%s): GetVersionString() unsupported in FmpDeviceLib.\n", mImageIdName));
    Private->Descriptor.VersionName = AllocateCopyPool (
                                        sizeof (VERSION_STRING_NOT_SUPPORTED),
                                        VERSION_STRING_NOT_SUPPORTED
                                        );
  } else if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "FmpDxe(%s): GetVersionString() not available in FmpDeviceLib.\n", mImageIdName));
    Private->Descriptor.VersionName = AllocateCopyPool (
                                        sizeof (VERSION_STRING_NOT_AVAILABLE),
                                        VERSION_STRING_NOT_AVAILABLE
                                        );
  }

  Private->Descriptor.LowestSupportedImageVersion = GetLowestSupportedVersion (Private);

  //
  // Get attributes from the FmpDeviceLib
  //
  FmpDeviceGetAttributes (
    &Private->Descriptor.AttributesSupported,
    &Private->Descriptor.AttributesSetting
    );

  //
  // Force set the updatable bits in the attributes;
  //
  Private->Descriptor.AttributesSupported |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
  Private->Descriptor.AttributesSetting   |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;

  //
  // Force set the authentication bits in the attributes;
  //
  Private->Descriptor.AttributesSupported |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
  Private->Descriptor.AttributesSetting   |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);

  Private->Descriptor.Compatibilities = 0;

  //
  // Get the size of the firmware image from the FmpDeviceLib
  //
  Status = FmpDeviceGetSize (&Private->Descriptor.Size);
  if (EFI_ERROR (Status)) {
    Private->Descriptor.Size = 0;
  }

  Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private);
  Private->Descriptor.LastAttemptStatus  = GetLastAttemptStatusFromVariable (Private);

  //
  // Get the dependency from the FmpDependencyDeviceLib.
  //
  Private->Descriptor.Dependencies = NULL;

  //
  // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY
  //
  if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
    Private->Descriptor.Dependencies = GetFmpDependency (&DependenciesSize);
  }

  Private->DescriptorPopulated = TRUE;
}

/**
  Returns information about the current firmware image(s) of the device.

  This function allows a copy of the current firmware image to be created and saved.
  The saved copy could later been used, for example, in firmware image recovery or rollback.

  @param[in]      This               A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in, out] ImageInfoSize      A pointer to the size, in bytes, of the ImageInfo buffer.
                                     On input, this is the size of the buffer allocated by the caller.
                                     On output, it is the size of the buffer returned by the firmware
                                     if the buffer was large enough, or the size of the buffer needed
                                     to contain the image(s) information if the buffer was too small.
  @param[in, out] ImageInfo          A pointer to the buffer in which firmware places the current image(s)
                                     information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
  @param[out]     DescriptorVersion  A pointer to the location in which firmware returns the version number
                                     associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
  @param[out]     DescriptorCount    A pointer to the location in which firmware returns the number of
                                     descriptors or firmware images within this device.
  @param[out]     DescriptorSize     A pointer to the location in which firmware returns the size, in bytes,
                                     of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
  @param[out]     PackageVersion     A version number that represents all the firmware images in the device.
                                     The format is vendor specific and new version must have a greater value
                                     than the old version. If PackageVersion is not supported, the value is
                                     0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
                                     is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
                                     that package version update is in progress.
  @param[out]     PackageVersionName A pointer to a pointer to a null-terminated string representing the
                                     package version name. The buffer is allocated by this function with
                                     AllocatePool(), and it is the caller's responsibility to free it with a call
                                     to FreePool().

  @retval EFI_SUCCESS                The device was successfully updated with the new image.
  @retval EFI_BUFFER_TOO_SMALL       The ImageInfo buffer was too small. The current buffer size
                                     needed to hold the image(s) information is returned in ImageInfoSize.
  @retval EFI_INVALID_PARAMETER      ImageInfoSize is NULL.
  @retval EFI_DEVICE_ERROR           Valid information could not be returned. Possible corrupted image.

**/
EFI_STATUS
EFIAPI
GetTheImageInfo (
  IN     EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  IN OUT UINTN                             *ImageInfoSize,
  IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR     *ImageInfo,
  OUT    UINT32                            *DescriptorVersion,
  OUT    UINT8                             *DescriptorCount,
  OUT    UINTN                             *DescriptorSize,
  OUT    UINT32                            *PackageVersion,
  OUT    CHAR16                            **PackageVersionName
  )
{
  EFI_STATUS                        Status;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;

  Status = EFI_SUCCESS;

  if (This == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - This is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // Retrieve the private context structure
  //
  Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
  FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);

  //
  // Check for valid pointer
  //
  if (ImageInfoSize == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - ImageInfoSize is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // Check the buffer size
  // NOTE: Check this first so caller can get the necessary memory size it must allocate.
  //
  if (*ImageInfoSize < (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR))) {
    *ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
    DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImageInfo() - ImageInfoSize is to small.\n", mImageIdName));
    Status = EFI_BUFFER_TOO_SMALL;
    goto cleanup;
  }

  //
  // Confirm that buffer isn't null
  //
  if (  (ImageInfo == NULL) || (DescriptorVersion == NULL) || (DescriptorCount == NULL) || (DescriptorSize == NULL)
     || (PackageVersion == NULL))
  {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - Pointer Parameter is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // Set the size to whatever we need
  //
  *ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);

  //
  // Make sure the descriptor has already been loaded or refreshed
  //
  PopulateDescriptor (Private);

  //
  // Copy the image descriptor
  //
  CopyMem (ImageInfo, &Private->Descriptor, sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR));

  *DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
  *DescriptorCount   = 1;
  *DescriptorSize    = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
  //
  // means unsupported
  //
  *PackageVersion = 0xFFFFFFFF;

  //
  // Do not update PackageVersionName since it is not supported in this instance.
  //

cleanup:

  return Status;
}

/**
  Retrieves a copy of the current firmware image of the device.

  This function allows a copy of the current firmware image to be created and saved.
  The saved copy could later been used, for example, in firmware image recovery or rollback.

  @param[in]      This           A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in]      ImageIndex     A unique number identifying the firmware image(s) within the device.
                                 The number is between 1 and DescriptorCount.
  @param[in, out] Image          Points to the buffer where the current image is copied to.
  @param[in, out] ImageSize      On entry, points to the size of the buffer pointed to by Image, in bytes.
                                 On return, points to the length of the image, in bytes.

  @retval EFI_SUCCESS            The device was successfully updated with the new image.
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to hold the
                                 image. The current buffer size needed to hold the image is returned
                                 in ImageSize.
  @retval EFI_INVALID_PARAMETER  The Image was NULL.
  @retval EFI_NOT_FOUND          The current image is not copied to the buffer.
  @retval EFI_UNSUPPORTED        The operation is not supported.
  @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.

**/
EFI_STATUS
EFIAPI
GetTheImage (
  IN     EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  IN     UINT8                             ImageIndex,
  IN OUT VOID                              *Image,
  IN OUT UINTN                             *ImageSize
  )
{
  EFI_STATUS                        Status;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;
  UINTN                             Size;

  if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
    return EFI_UNSUPPORTED;
  }

  Status = EFI_SUCCESS;

  if (This == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - This is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // Retrieve the private context structure
  //
  Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
  FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);

  //
  // Check to make sure index is 1 (only 1 image for this device)
  //
  if (ImageIndex != 1) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Index Invalid.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  if (ImageSize == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - ImageSize Pointer Parameter is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // Check the buffer size
  //
  Status = FmpDeviceGetSize (&Size);
  if (EFI_ERROR (Status)) {
    Size = 0;
  }

  if (*ImageSize < Size) {
    *ImageSize = Size;
    DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small.\n", mImageIdName));
    Status = EFI_BUFFER_TOO_SMALL;
    goto cleanup;
  }

  if (Image == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  Status = FmpDeviceGetImage (Image, ImageSize);
cleanup:

  return Status;
}

/**
  Helper function to safely retrieve the FMP header from
  within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.

  @param[in]   Image                 Pointer to the image.
  @param[in]   ImageSize             Size of the image.
  @param[in]   AdditionalHeaderSize  Size of any headers that cannot be calculated by this function.
  @param[out]  PayloadSize           An optional pointer to a UINTN that holds the size of the payload
                                     (image size minus headers)

  @retval  !NULL  Valid pointer to the header.
  @retval  NULL   Structure is bad and pointer cannot be found.

**/
VOID *
GetFmpHeader (
  IN  CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION  *Image,
  IN  CONST UINTN                              ImageSize,
  IN  CONST UINTN                              AdditionalHeaderSize,
  OUT UINTN                                    *PayloadSize OPTIONAL
  )
{
  //
  // Check to make sure that operation can be safely performed.
  //
  if ((((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize < (UINTN)Image) || \
      (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize >= (UINTN)Image + ImageSize))
  {
    //
    // Pointer overflow. Invalid image.
    //
    return NULL;
  }

  if (PayloadSize != NULL) {
    *PayloadSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength + AdditionalHeaderSize);
  }

  return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength  + AdditionalHeaderSize);
}

/**
  Helper function to safely calculate the size of all headers
  within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.

  @param[in]  Image                 Pointer to the image.
  @param[in]  AdditionalHeaderSize  Size of any headers that cannot be calculated by this function.

  @retval  UINT32>0  Valid size of all the headers.
  @retval  0         Structure is bad and size cannot be found.

**/
UINT32
GetAllHeaderSize (
  IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION  *Image,
  IN UINT32                                   AdditionalHeaderSize
  )
{
  UINT32  CalculatedSize;

  if (Image == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetAllHeaderSize() - Image is NULL.\n", mImageIdName));
    return 0;
  }

  CalculatedSize = sizeof (Image->MonotonicCount) +
                   AdditionalHeaderSize +
                   Image->AuthInfo.Hdr.dwLength;

  //
  // Check to make sure that operation can be safely performed.
  //
  if ((CalculatedSize < sizeof (Image->MonotonicCount)) ||
      (CalculatedSize < AdditionalHeaderSize) ||
      (CalculatedSize < Image->AuthInfo.Hdr.dwLength))
  {
    //
    // Integer overflow. Invalid image.
    //
    return 0;
  }

  return CalculatedSize;
}

/**
  Checks if the firmware image is valid for the device.

  This function allows firmware update application to validate the firmware image without
  invoking the SetImage() first.

  @param[in]  This               A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in]  ImageIndex         A unique number identifying the firmware image(s) within the device.
                                 The number is between 1 and DescriptorCount.
  @param[in]  Image              Points to the new image.
  @param[in]  ImageSize          Size of the new image in bytes.
  @param[out] ImageUpdatable     Indicates if the new image is valid for update. It also provides,
                                 if available, additional information if the image is invalid.
  @param[out] LastAttemptStatus  A pointer to a UINT32 that holds the last attempt status to report
                                 back to the ESRT table in case of error.  If an error does not occur,
                                 this function will set the value to LAST_ATTEMPT_STATUS_SUCCESS.

                                 This function will return error codes that occur within this function
                                 implementation within a driver range of last attempt error codes from
                                 LAST_ATTEMPT_STATUS_DRIVER_MIN_ERROR_CODE_VALUE
                                 to LAST_ATTEMPT_STATUS_DRIVER_MAX_ERROR_CODE_VALUE.

                                 This function might also return error codes that occur within libraries
                                 linked against this module that return last attempt error codes such as:

                                 LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_LIB_MIN_ERROR_CODE_VALUE to
                                 LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_LIB_MAX_ERROR_CODE_VALUE

                                 LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_CHECK_LIB_MIN_ERROR_CODE_VALUE to
                                 LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_CHECK_LIB_MAX_ERROR_CODE_VALUE

  @retval EFI_SUCCESS            The image was successfully checked.
  @retval EFI_ABORTED            The operation is aborted.
  @retval EFI_INVALID_PARAMETER  The Image was NULL.
  @retval EFI_UNSUPPORTED        The operation is not supported.
  @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.

**/
EFI_STATUS
EFIAPI
CheckTheImageInternal (
  IN  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  IN  UINT8                             ImageIndex,
  IN  CONST VOID                        *Image,
  IN  UINTN                             ImageSize,
  OUT UINT32                            *ImageUpdatable,
  OUT UINT32                            *LastAttemptStatus
  )
{
  EFI_STATUS                        Status;
  UINT32                            LocalLastAttemptStatus;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;
  UINTN                             RawSize;
  VOID                              *FmpPayloadHeader;
  UINTN                             FmpPayloadSize;
  UINT32                            Version;
  UINT32                            FmpHeaderSize;
  UINTN                             AllHeaderSize;
  UINT32                            Index;
  VOID                              *PublicKeyData;
  UINTN                             PublicKeyDataLength;
  UINT8                             *PublicKeyDataXdr;
  UINT8                             *PublicKeyDataXdrEnd;
  EFI_FIRMWARE_IMAGE_DEP            *Dependencies;
  UINT32                            DependenciesSize;

  Status                 = EFI_SUCCESS;
  LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
  RawSize                = 0;
  FmpPayloadHeader       = NULL;
  FmpPayloadSize         = 0;
  Version                = 0;
  FmpHeaderSize          = 0;
  AllHeaderSize          = 0;
  Dependencies           = NULL;
  DependenciesSize       = 0;

  if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
    return EFI_UNSUPPORTED;
  }

  if (LastAttemptStatus == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImageInternal() - LastAttemptStatus is NULL.\n", mImageIdName));
    Status = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  //
  // A last attempt status error code will always override the success
  // value before returning from the function
  //
  *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;

  if (This == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - This is NULL.\n", mImageIdName));
    Status             = EFI_INVALID_PARAMETER;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_PROTOCOL_ARG_MISSING;
    goto cleanup;
  }

  //
  // Retrieve the private context structure
  //
  Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
  FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);

  //
  // Make sure the descriptor has already been loaded or refreshed
  //
  PopulateDescriptor (Private);

  if (ImageUpdatable == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - ImageUpdatable Pointer Parameter is NULL.\n", mImageIdName));
    Status             = EFI_INVALID_PARAMETER;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_NOT_UPDATABLE;
    goto cleanup;
  }

  //
  // Set to valid and then if any tests fail it will update this flag.
  //
  *ImageUpdatable = IMAGE_UPDATABLE_VALID;

  //
  // Set to satisfied and then if dependency evaluates to false it will update this flag.
  //
  Private->DependenciesSatisfied = TRUE;

  if (Image == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
    //
    // not sure if this is needed
    //
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_NOT_PROVIDED;
    return EFI_INVALID_PARAMETER;
  }

  PublicKeyDataXdr    = PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr);
  PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize (PcdFmpDevicePkcs7CertBufferXdr);

  if ((PublicKeyDataXdr == NULL) || (PublicKeyDataXdr == PublicKeyDataXdrEnd)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n", mImageIdName));
    Status                 = EFI_ABORTED;
    LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_CERTIFICATE;
  } else {
    //
    // Try each key from PcdFmpDevicePkcs7CertBufferXdr
    //
    for (Index = 1; PublicKeyDataXdr < PublicKeyDataXdrEnd; Index++) {
      Index++;
      DEBUG (
        (DEBUG_INFO,
         "FmpDxe(%s): Certificate #%d [%p..%p].\n",
         mImageIdName,
         Index,
         PublicKeyDataXdr,
         PublicKeyDataXdrEnd
        )
        );

      if ((PublicKeyDataXdr + sizeof (UINT32)) > PublicKeyDataXdrEnd) {
        //
        // Key data extends beyond end of PCD
        //
        DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate size extends beyond end of PCD, skipping it.\n", mImageIdName));
        Status                 = EFI_ABORTED;
        LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_KEY_LENGTH_VALUE;
        break;
      }

      //
      // Read key length stored in big-endian format
      //
      PublicKeyDataLength = SwapBytes32 (*(UINT32 *)(PublicKeyDataXdr));
      //
      // Point to the start of the key data
      //
      PublicKeyDataXdr += sizeof (UINT32);
      if (PublicKeyDataXdr + PublicKeyDataLength > PublicKeyDataXdrEnd) {
        //
        // Key data extends beyond end of PCD
        //
        DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate extends beyond end of PCD, skipping it.\n", mImageIdName));
        Status                 = EFI_ABORTED;
        LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_KEY_LENGTH;
        break;
      }

      PublicKeyData = PublicKeyDataXdr;
      Status        = AuthenticateFmpImage (
                        (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,
                        ImageSize,
                        PublicKeyData,
                        PublicKeyDataLength
                        );
      if (!EFI_ERROR (Status)) {
        break;
      }

      PublicKeyDataXdr += PublicKeyDataLength;
      PublicKeyDataXdr  = (UINT8 *)ALIGN_POINTER (PublicKeyDataXdr, sizeof (UINT32));
    }
  }

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Authentication Failed %r.\n", mImageIdName, Status));
    if (LocalLastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {
      *LastAttemptStatus = LocalLastAttemptStatus;
    } else {
      *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_AUTH_FAILURE;
    }

    goto cleanup;
  }

  //
  // Check to make sure index is 1
  //
  if (ImageIndex != 1) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Index Invalid.\n", mImageIdName));
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID_TYPE;
    Status             = EFI_INVALID_PARAMETER;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_IMAGE_INDEX;
    goto cleanup;
  }

  //
  // Get the dependency from Image.
  //
  Dependencies =  GetImageDependency (
                    (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,
                    ImageSize,
                    &DependenciesSize,
                    LastAttemptStatus
                    );
  if (*LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {
    Status = EFI_ABORTED;
    goto cleanup;
  }

  //
  // Check the FmpPayloadHeader
  //
  FmpPayloadHeader = GetFmpHeader ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize);
  if (FmpPayloadHeader == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpHeader failed.\n", mImageIdName));
    Status             = EFI_ABORTED;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER;
    goto cleanup;
  }

  Status = GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize, &Version);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", mImageIdName, Status));
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID;
    Status             = EFI_SUCCESS;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER_VERSION;
    goto cleanup;
  }

  //
  // Check the lowest supported version
  //
  if (Version < Private->Descriptor.LowestSupportedImageVersion) {
    DEBUG (
      (DEBUG_ERROR,
       "FmpDxe(%s): CheckTheImage() - Version Lower than lowest supported version. 0x%08X < 0x%08X\n",
       mImageIdName, Version, Private->Descriptor.LowestSupportedImageVersion)
      );
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID_OLD;
    Status             = EFI_SUCCESS;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_VERSION_TOO_LOW;
    goto cleanup;
  }

  //
  // Evaluate dependency expression
  //
  Private->DependenciesSatisfied =  CheckFmpDependency (
                                      Private->Descriptor.ImageTypeId,
                                      Version,
                                      Dependencies,
                                      DependenciesSize,
                                      &LocalLastAttemptStatus
                                      );
  if (!Private->DependenciesSatisfied) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName));
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID;
    Status             = EFI_SUCCESS;
    *LastAttemptStatus = LocalLastAttemptStatus;
    goto cleanup;
  }

  //
  // Get the FmpHeaderSize so we can determine the real payload size
  //
  Status = GetFmpPayloadHeaderSize (FmpPayloadHeader, FmpPayloadSize, &FmpHeaderSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe: CheckTheImage() - GetFmpPayloadHeaderSize failed %r.\n", Status));
    *ImageUpdatable    = IMAGE_UPDATABLE_INVALID;
    Status             = EFI_SUCCESS;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER_SIZE;
    goto cleanup;
  }

  //
  // Call FmpDevice Lib Check Image on the
  // Raw payload.  So all headers need stripped off
  //
  AllHeaderSize = GetAllHeaderSize ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
  if (AllHeaderSize == 0) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
    Status             = EFI_ABORTED;
    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_ALL_HEADER_SIZE;
    goto cleanup;
  }

  RawSize = ImageSize - AllHeaderSize;

  //
  // FmpDeviceLib CheckImage function to do any specific checks
  //
  Status = FmpDeviceCheckImageWithStatus ((((UINT8 *)Image) + AllHeaderSize), RawSize, ImageUpdatable, LastAttemptStatus);
  if (EFI_ERROR (Status)) {
    // The image cannot be valid if an error occurred checking the image
    if (*ImageUpdatable == IMAGE_UPDATABLE_VALID) {
      *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
    }

    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - FmpDeviceLib CheckImage failed. Status = %r\n", mImageIdName, Status));
  }

  //
  // Only validate the library last attempt status code if the image is not updatable.
  // This specifically avoids converting LAST_ATTEMPT_STATUS_SUCCESS if it set for an updatable image.
  //
  if (*ImageUpdatable != IMAGE_UPDATABLE_VALID) {
    //
    // LastAttemptStatus returned from the device library should fall within the designated error range
    // [LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE, LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE]
    //
    if ((*LastAttemptStatus < LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE) ||
        (*LastAttemptStatus > LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE))
    {
      DEBUG ((
        DEBUG_ERROR,
        "FmpDxe(%s): CheckTheImage() - LastAttemptStatus %d from FmpDeviceCheckImageWithStatus() is invalid.\n",
        mImageIdName,
        *LastAttemptStatus
        ));
      *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
    }
  }

cleanup:
  return Status;
}

/**
  Checks if the firmware image is valid for the device.

  This function allows firmware update application to validate the firmware image without
  invoking the SetImage() first.

  @param[in]  This               A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in]  ImageIndex         A unique number identifying the firmware image(s) within the device.
                                 The number is between 1 and DescriptorCount.
  @param[in]  Image              Points to the new image.
  @param[in]  ImageSize          Size of the new image in bytes.
  @param[out] ImageUpdatable     Indicates if the new image is valid for update. It also provides,
                                 if available, additional information if the image is invalid.

  @retval EFI_SUCCESS            The image was successfully checked.
  @retval EFI_ABORTED            The operation is aborted.
  @retval EFI_INVALID_PARAMETER  The Image was NULL.
  @retval EFI_UNSUPPORTED        The operation is not supported.
  @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.

**/
EFI_STATUS
EFIAPI
CheckTheImage (
  IN  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  IN  UINT8                             ImageIndex,
  IN  CONST VOID                        *Image,
  IN  UINTN                             ImageSize,
  OUT UINT32                            *ImageUpdatable
  )
{
  UINT32  LastAttemptStatus;

  return CheckTheImageInternal (This, ImageIndex, Image, ImageSize, ImageUpdatable, &LastAttemptStatus);
}

/**
  Updates the firmware image of the device.

  This function updates the hardware with the new firmware image.
  This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
  If the firmware image is updatable, the function should perform the following minimal validations
  before proceeding to do the firmware image update.
  - Validate the image authentication if image has attribute
    IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
    EFI_SECURITY_VIOLATION if the validation fails.
  - Validate the image is a supported image for this device. The function returns EFI_ABORTED if
    the image is unsupported. The function can optionally provide more detailed information on
    why the image is not a supported image.
  - Validate the data from VendorCode if not null. Image validation must be performed before
    VendorCode data validation. VendorCode data is ignored or considered invalid if image
    validation failed. The function returns EFI_ABORTED if the data is invalid.

  VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
  the caller did not specify the policy or use the default policy. As an example, vendor can implement
  a policy to allow an option to force a firmware image update when the abort reason is due to the new
  firmware image version is older than the current firmware image version or bad image checksum.
  Sensitive operations such as those wiping the entire firmware image and render the device to be
  non-functional should be encoded in the image itself rather than passed with the VendorCode.
  AbortReason enables vendor to have the option to provide a more detailed description of the abort
  reason to the caller.

  @param[in]  This               A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in]  ImageIndex         A unique number identifying the firmware image(s) within the device.
                                 The number is between 1 and DescriptorCount.
  @param[in]  Image              Points to the new image.
  @param[in]  ImageSize          Size of the new image in bytes.
  @param[in]  VendorCode         This enables vendor to implement vendor-specific firmware image update policy.
                                 Null indicates the caller did not specify the policy or use the default policy.
  @param[in]  Progress           A function used by the driver to report the progress of the firmware update.
  @param[out] AbortReason        A pointer to a pointer to a null-terminated string providing more
                                 details for the aborted operation. The buffer is allocated by this function
                                 with AllocatePool(), and it is the caller's responsibility to free it with a
                                 call to FreePool().

  @retval EFI_SUCCESS            The device was successfully updated with the new image.
  @retval EFI_ABORTED            The operation is aborted.
  @retval EFI_INVALID_PARAMETER  The Image was NULL.
  @retval EFI_UNSUPPORTED        The operation is not supported.
  @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.

**/
EFI_STATUS
EFIAPI
SetTheImage (
  IN  EFI_FIRMWARE_MANAGEMENT_PROTOCOL               *This,
  IN  UINT8                                          ImageIndex,
  IN  CONST VOID                                     *Image,
  IN  UINTN                                          ImageSize,
  IN  CONST VOID                                     *VendorCode,
  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,
  OUT CHAR16                                         **AbortReason
  )
{
  EFI_STATUS                        Status;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;
  UINT32                            Updateable;
  BOOLEAN                           BooleanValue;
  UINT32                            FmpHeaderSize;
  VOID                              *FmpHeader;
  UINTN                             FmpPayloadSize;
  UINT32                            AllHeaderSize;
  UINT32                            IncomingFwVersion;
  UINT32                            LastAttemptStatus;
  UINT32                            Version;
  UINT32                            LowestSupportedVersion;
  EFI_FIRMWARE_IMAGE_DEP            *Dependencies;
  UINT32                            DependenciesSize;

  Status            = EFI_SUCCESS;
  Private           = NULL;
  Updateable        = 0;
  BooleanValue      = FALSE;
  FmpHeaderSize     = 0;
  FmpHeader         = NULL;
  FmpPayloadSize    = 0;
  AllHeaderSize     = 0;
  IncomingFwVersion = 0;
  LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
  Dependencies      = NULL;
  DependenciesSize  = 0;

  if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
    return EFI_UNSUPPORTED;
  }

  if (This == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - This is NULL.\n", mImageIdName));
    Status            = EFI_INVALID_PARAMETER;
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_PROTOCOL_ARG_MISSING;
    goto cleanup;
  }

  //
  // Retrieve the private context structure
  //
  Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
  FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);

  //
  // Make sure the descriptor has already been loaded or refreshed
  //
  PopulateDescriptor (Private);

  //
  // Set to 0 to clear any previous results.
  //
  SetLastAttemptVersionInVariable (Private, IncomingFwVersion);

  //
  // if we have locked the device, then skip the set operation.
  // it should be blocked by hardware too but we can catch here even faster
  //
  if (Private->FmpDeviceLocked) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already locked.  Can't update.\n", mImageIdName));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_DEVICE_LOCKED;
    Status            = EFI_UNSUPPORTED;
    goto cleanup;
  }

  //
  // Call check image to verify the image
  //
  Status = CheckTheImageInternal (This, ImageIndex, Image, ImageSize, &Updateable, &LastAttemptStatus);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Check The Image failed with %r.\n", mImageIdName, Status));
    goto cleanup;
  }

  //
  // Get the dependency from Image.
  //
  Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize, &LastAttemptStatus);

  //
  // No functional error in CheckTheImage.  Attempt to get the Version to
  // support better error reporting.
  //
  FmpHeader = GetFmpHeader ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize);
  if (FmpHeader == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpHeader failed.\n", mImageIdName));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER;
    Status            = EFI_ABORTED;
    goto cleanup;
  }

  Status = GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &IncomingFwVersion);
  if (!EFI_ERROR (Status)) {
    //
    // Set to actual value
    //
    SetLastAttemptVersionInVariable (Private, IncomingFwVersion);
  }

  if (Updateable != IMAGE_UPDATABLE_VALID) {
    DEBUG (
      (DEBUG_ERROR,
       "FmpDxe(%s): SetTheImage() - Check The Image returned that the Image was not valid for update.  Updatable value = 0x%X.\n",
       mImageIdName, Updateable)
      );
    if (Private->DependenciesSatisfied == FALSE) {
      LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES;
    }

    Status = EFI_ABORTED;
    goto cleanup;
  }

  if (Progress == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Invalid progress callback\n", mImageIdName));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_PROGRESS_CALLBACK_ERROR;
    Status            = EFI_INVALID_PARAMETER;
    goto cleanup;
  }

  mProgressFunc = Progress;

  //
  // Checking the image is at least 1%
  //
  Status = Progress (1);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Progress Callback failed with Status %r.\n", mImageIdName, Status));
  }

  //
  // Check System Power
  //
  Status = CheckSystemPower (&BooleanValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemPower - API call failed %r.\n", mImageIdName, Status));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_CHECK_POWER_API;
    goto cleanup;
  }

  if (!BooleanValue) {
    Status = EFI_ABORTED;
    DEBUG (
      (DEBUG_ERROR,
       "FmpDxe(%s): SetTheImage() - CheckSystemPower - returned False.  Update not allowed due to System Power.\n", mImageIdName)
      );
    LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT;
    goto cleanup;
  }

  Progress (2);

  //
  // Check System Thermal
  //
  Status = CheckSystemThermal (&BooleanValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemThermal - API call failed %r.\n", mImageIdName, Status));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_CHECK_SYS_THERMAL_API;
    goto cleanup;
  }

  if (!BooleanValue) {
    Status            = EFI_ABORTED;
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_THERMAL;
    DEBUG (
      (DEBUG_ERROR,
       "FmpDxe(%s): SetTheImage() - CheckSystemThermal - returned False.  Update not allowed due to System Thermal.\n", mImageIdName)
      );
    goto cleanup;
  }

  Progress (3);

  //
  // Check System Environment
  //
  Status = CheckSystemEnvironment (&BooleanValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemEnvironment - API call failed %r.\n", mImageIdName, Status));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_CHECK_SYS_ENV_API;
    goto cleanup;
  }

  if (!BooleanValue) {
    Status            = EFI_ABORTED;
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_SYSTEM_ENV;
    DEBUG (
      (DEBUG_ERROR,
       "FmpDxe(%s): SetTheImage() - CheckSystemEnvironment - returned False.  Update not allowed due to System Environment.\n", mImageIdName)
      );
    goto cleanup;
  }

  Progress (4);

  //
  // Save LastAttemptStatus as error so that if SetImage never returns the error
  // state is recorded.
  //
  SetLastAttemptStatusInVariable (Private, LastAttemptStatus);

  //
  // Strip off all the headers so the device can process its firmware
  //
  Status = GetFmpPayloadHeaderSize (FmpHeader, FmpPayloadSize, &FmpHeaderSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpPayloadHeaderSize failed %r.\n", mImageIdName, Status));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER_SIZE;
    goto cleanup;
  }

  AllHeaderSize = GetAllHeaderSize ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
  if (AllHeaderSize == 0) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
    LastAttemptStatus = LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_ALL_HEADER_SIZE;
    Status            = EFI_ABORTED;
    goto cleanup;
  }

  //
  // Indicate that control is handed off to FmpDeviceLib
  //
  Progress (5);

  //
  // Copy the requested image to the firmware using the FmpDeviceLib
  //
  Status = FmpDeviceSetImageWithStatus (
             (((UINT8 *)Image) + AllHeaderSize),
             ImageSize - AllHeaderSize,
             VendorCode,
             FmpDxeProgress,
             IncomingFwVersion,
             AbortReason,
             &LastAttemptStatus
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SetImage from FmpDeviceLib failed. Status =  %r.\n", mImageIdName, Status));

    //
    // LastAttemptStatus returned from the device library should fall within the designated error range
    // [LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE, LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE]
    //
    if ((LastAttemptStatus < LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE) ||
        (LastAttemptStatus > LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE))
    {
      DEBUG (
        (DEBUG_ERROR,
         "FmpDxe(%s): SetTheImage() - LastAttemptStatus %d from FmpDeviceSetImageWithStatus() is invalid.\n",
         mImageIdName,
         LastAttemptStatus)
        );
      LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
    }

    goto cleanup;
  }

  //
  // Store the dependency
  //
  if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
    Status = SaveFmpDependency (Dependencies, DependenciesSize);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SaveFmpDependency from FmpDependencyCheckLib failed. (%r)\n", mImageIdName, Status));
    }

    Status = EFI_SUCCESS;
  }

  //
  // Finished the update without error
  // Indicate that control has been returned from FmpDeviceLib
  //
  Progress (99);

  //
  // Update the version stored in variable
  //
  if (!Private->RuntimeVersionSupported) {
    Version = DEFAULT_VERSION;
    GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Version);
    SetVersionInVariable (Private, Version);
  }

  //
  // Update lowest supported variable
  //
  LowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
  GetFmpPayloadHeaderLowestSupportedVersion (FmpHeader, FmpPayloadSize, &LowestSupportedVersion);
  SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion);

  LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;

cleanup:
  mProgressFunc = NULL;

  if (Private != NULL) {
    DEBUG ((DEBUG_INFO, "FmpDxe(%s): SetTheImage() LastAttemptStatus: %u.\n", mImageIdName, LastAttemptStatus));
    SetLastAttemptStatusInVariable (Private, LastAttemptStatus);
  }

  if (Progress != NULL) {
    //
    // Set progress to 100 after everything is done including recording Status.
    //
    Progress (100);
  }

  //
  // Need repopulate after SetImage is called to
  // update LastAttemptVersion and LastAttemptStatus.
  //
  if (Private != NULL) {
    Private->DescriptorPopulated = FALSE;
  }

  return Status;
}

/**
  Returns information about the firmware package.

  This function returns package information.

  @param[in]  This                     A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[out] PackageVersion           A version number that represents all the firmware images in the device.
                                       The format is vendor specific and new version must have a greater value
                                       than the old version. If PackageVersion is not supported, the value is
                                       0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
                                       comparison is to be performed using PackageVersionName. A value of
                                       0xFFFFFFFD indicates that package version update is in progress.
  @param[out] PackageVersionName       A pointer to a pointer to a null-terminated string representing
                                       the package version name. The buffer is allocated by this function with
                                       AllocatePool(), and it is the caller's responsibility to free it with a
                                       call to FreePool().
  @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
                                       package version name. A value of 0 indicates the device does not support
                                       update of package version name. Length is the number of Unicode characters,
                                       including the terminating null character.
  @param[out] AttributesSupported      Package attributes that are supported by this device. See 'Package Attribute
                                       Definitions' for possible returned values of this parameter. A value of 1
                                       indicates the attribute is supported and the current setting value is
                                       indicated in AttributesSetting. A value of 0 indicates the attribute is not
                                       supported and the current setting value in AttributesSetting is meaningless.
  @param[out] AttributesSetting        Package attributes. See 'Package Attribute Definitions' for possible returned
                                       values of this parameter

  @retval EFI_SUCCESS                  The package information was successfully returned.
  @retval EFI_UNSUPPORTED              The operation is not supported.

**/
EFI_STATUS
EFIAPI
GetPackageInfo (
  IN  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  OUT UINT32                            *PackageVersion,
  OUT CHAR16                            **PackageVersionName,
  OUT UINT32                            *PackageVersionNameMaxLen,
  OUT UINT64                            *AttributesSupported,
  OUT UINT64                            *AttributesSetting
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Updates information about the firmware package.

  This function updates package information.
  This function returns EFI_UNSUPPORTED if the package information is not updatable.
  VendorCode enables vendor to implement vendor-specific package information update policy.
  Null if the caller did not specify this policy or use the default policy.

  @param[in]  This               A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
  @param[in]  Image              Points to the authentication image.
                                 Null if authentication is not required.
  @param[in]  ImageSize          Size of the authentication image in bytes.
                                 0 if authentication is not required.
  @param[in]  VendorCode         This enables vendor to implement vendor-specific firmware
                                 image update policy.
                                 Null indicates the caller did not specify this policy or use
                                 the default policy.
  @param[in]  PackageVersion     The new package version.
  @param[in]  PackageVersionName A pointer to the new null-terminated Unicode string representing
                                 the package version name.
                                 The string length is equal to or less than the value returned in
                                 PackageVersionNameMaxLen.

  @retval EFI_SUCCESS            The device was successfully updated with the new package
                                 information.
  @retval EFI_INVALID_PARAMETER  The PackageVersionName length is longer than the value
                                 returned in PackageVersionNameMaxLen.
  @retval EFI_UNSUPPORTED        The operation is not supported.
  @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.

**/
EFI_STATUS
EFIAPI
SetPackageInfo (
  IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *This,
  IN CONST VOID                        *Image,
  IN UINTN                             ImageSize,
  IN CONST VOID                        *VendorCode,
  IN UINT32                            PackageVersion,
  IN CONST CHAR16                      *PackageVersionName
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Event notification function that is invoked when the event GUID specified by
  PcdFmpDeviceLockEventGuid is signaled.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  The pointer to the notification function's context,
                      which is implementation-dependent.
**/
VOID
EFIAPI
FmpDxeLockEventNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS                        Status;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;

  if (Context == NULL) {
    ASSERT (Context != NULL);
    return;
  }

  Private = (FIRMWARE_MANAGEMENT_PRIVATE_DATA *)Context;

  if (!Private->FmpDeviceLocked) {
    //
    // Lock the firmware device
    //
    FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
    Status = FmpDeviceLock ();
    if (EFI_ERROR (Status)) {
      if (Status != EFI_UNSUPPORTED) {
        DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLock() returned error.  Status = %r\n", mImageIdName, Status));
      } else {
        DEBUG ((DEBUG_WARN, "FmpDxe(%s): FmpDeviceLock() returned error.  Status = %r\n", mImageIdName, Status));
      }
    }

    Private->FmpDeviceLocked = TRUE;
  }
}

/**
  Function to install FMP instance.

  @param[in]  Handle  The device handle to install a FMP instance on.

  @retval  EFI_SUCCESS            FMP Installed
  @retval  EFI_INVALID_PARAMETER  Handle was invalid
  @retval  other                  Error installing FMP

**/
EFI_STATUS
EFIAPI
InstallFmpInstance (
  IN EFI_HANDLE  Handle
  )
{
  EFI_STATUS                        Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;

  //
  // Only allow a single FMP Protocol instance to be installed
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  (VOID **)&Fmp,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Allocate FMP Protocol instance
  //
  Private = AllocateCopyPool (
              sizeof (mFirmwareManagementPrivateDataTemplate),
              &mFirmwareManagementPrivateDataTemplate
              );
  if (Private == NULL) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to allocate memory for private structure.\n", mImageIdName));
    Status = EFI_OUT_OF_RESOURCES;
    goto cleanup;
  }

  //
  // Initialize private context data structure
  //
  Private->Handle           = Handle;
  Private->FmpDeviceContext = NULL;
  Status                    = FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
  if (Status == EFI_UNSUPPORTED) {
    Private->FmpDeviceContext = NULL;
  } else if (EFI_ERROR (Status)) {
    goto cleanup;
  }

  //
  // Make sure the descriptor has already been loaded or refreshed
  //
  PopulateDescriptor (Private);

  if (IsLockFmpDeviceAtLockEventGuidRequired ()) {
    //
    // Register all UEFI Variables used by this module to be locked.
    //
    Status = LockAllFmpVariables (Private);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to register variables to lock.  Status = %r.\n", mImageIdName, Status));
    } else {
      DEBUG ((DEBUG_INFO, "FmpDxe(%s): All variables registered to lock\n", mImageIdName));
    }

    //
    // Create and register notify function to lock the FMP device.
    //
    Status = gBS->CreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    FmpDxeLockEventNotify,
                    Private,
                    mLockGuid,
                    &Private->FmpDeviceLockEvent
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to register notification.  Status = %r\n", mImageIdName, Status));
    }

    ASSERT_EFI_ERROR (Status);
  } else {
    DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): Not registering notification to call FmpDeviceLock() because mfg mode\n", mImageIdName));
  }

  //
  // Install FMP Protocol and FMP Progress Protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  &Private->Fmp,
                  &gEdkiiFirmwareManagementProgressProtocolGuid,
                  &mFmpProgress,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol install error. Status = %r.\n", mImageIdName, Status));
    goto cleanup;
  }

cleanup:

  if (EFI_ERROR (Status)) {
    if (Private != NULL) {
      if (Private->FmpDeviceLockEvent != NULL) {
        gBS->CloseEvent (Private->FmpDeviceLockEvent);
      }

      if (Private->Descriptor.VersionName != NULL) {
        FreePool (Private->Descriptor.VersionName);
      }

      if (Private->FmpDeviceContext != NULL) {
        FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);
      }

      if (Private->VersionVariableName != NULL) {
        FreePool (Private->VersionVariableName);
      }

      if (Private->LsvVariableName != NULL) {
        FreePool (Private->LsvVariableName);
      }

      if (Private->LastAttemptStatusVariableName != NULL) {
        FreePool (Private->LastAttemptStatusVariableName);
      }

      if (Private->LastAttemptVersionVariableName != NULL) {
        FreePool (Private->LastAttemptVersionVariableName);
      }

      if (Private->FmpStateVariableName != NULL) {
        FreePool (Private->FmpStateVariableName);
      }

      FreePool (Private);
    }
  }

  return Status;
}

/**
  Function to uninstall FMP instance.

  @param[in]  Handle  The device handle to install a FMP instance on.

  @retval  EFI_SUCCESS            FMP Installed
  @retval  EFI_INVALID_PARAMETER  Handle was invalid
  @retval  other                  Error installing FMP

**/
EFI_STATUS
EFIAPI
UninstallFmpInstance (
  IN EFI_HANDLE  Handle
  )
{
  EFI_STATUS                        Status;
  EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;
  FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  (VOID **)&Fmp,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol open error. Status = %r.\n", mImageIdName, Status));
    return Status;
  }

  Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (Fmp);
  FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);

  if (Private->FmpDeviceLockEvent != NULL) {
    gBS->CloseEvent (Private->FmpDeviceLockEvent);
  }

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Private->Handle,
                  &gEfiFirmwareManagementProtocolGuid,
                  &Private->Fmp,
                  &gEdkiiFirmwareManagementProgressProtocolGuid,
                  &mFmpProgress,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol uninstall error. Status = %r.\n", mImageIdName, Status));
    return Status;
  }

  if (Private->Descriptor.VersionName != NULL) {
    FreePool (Private->Descriptor.VersionName);
  }

  if (Private->FmpDeviceContext != NULL) {
    FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);
  }

  if (Private->VersionVariableName != NULL) {
    FreePool (Private->VersionVariableName);
  }

  if (Private->LsvVariableName != NULL) {
    FreePool (Private->LsvVariableName);
  }

  if (Private->LastAttemptStatusVariableName != NULL) {
    FreePool (Private->LastAttemptStatusVariableName);
  }

  if (Private->LastAttemptVersionVariableName != NULL) {
    FreePool (Private->LastAttemptVersionVariableName);
  }

  if (Private->FmpStateVariableName != NULL) {
    FreePool (Private->FmpStateVariableName);
  }

  FreePool (Private);

  return EFI_SUCCESS;
}

/**
  Unloads the application and its installed protocol.

  @param ImageHandle       Handle that identifies the image to be unloaded.
  @param  SystemTable      The system table.

  @retval EFI_SUCCESS      The image has been unloaded.

**/
EFI_STATUS
EFIAPI
FmpDxeLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  if (mFmpSingleInstance) {
    return UninstallFmpInstance (ImageHandle);
  }

  return EFI_SUCCESS;
}

/**
  Main entry for this driver/library.

  @param[in] ImageHandle  Image handle this driver.
  @param[in] SystemTable  Pointer to SystemTable.

**/
EFI_STATUS
EFIAPI
FmpDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Verify that a new FILE_GUID value has been provided in the <Defines>
  // section of this module.  The FILE_GUID is the ESRT GUID that must be
  // unique for each updatable firmware image.
  //
  if (CompareGuid (&mDefaultModuleFileGuid, &gEfiCallerIdGuid)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe: Use of default FILE_GUID detected.  FILE_GUID must be set to a unique value.\n"));
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }

  //
  // Get the ImageIdName value for the EFI_FIRMWARE_IMAGE_DESCRIPTOR from a PCD.
  //
  mImageIdName = (CHAR16 *)PcdGetPtr (PcdFmpDeviceImageIdName);
  if ((PcdGetSize (PcdFmpDeviceImageIdName) <= 2) || (mImageIdName[0] == 0)) {
    //
    // PcdFmpDeviceImageIdName must be set to a non-empty Unicode string
    //
    DEBUG ((DEBUG_ERROR, "FmpDxe(%g): PcdFmpDeviceImageIdName is an empty string.\n", &gEfiCallerIdGuid));
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }

  //
  // Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key.
  //
  DetectTestKey ();

  //
  // Fill in FMP Progress Protocol fields for Version 1
  //
  mFmpProgress.Version                        = 1;
  mFmpProgress.ProgressBarForegroundColor.Raw = PcdGet32 (PcdFmpDeviceProgressColor);
  mFmpProgress.WatchdogSeconds                = PcdGet8 (PcdFmpDeviceProgressWatchdogTimeInSeconds);

  // The lock event GUID is retrieved from PcdFmpDeviceLockEventGuid.
  // If PcdFmpDeviceLockEventGuid is not the size of an EFI_GUID, then
  // gEfiEndOfDxeEventGroupGuid is used.
  //
  mLockGuid = &gEfiEndOfDxeEventGroupGuid;
  if (PcdGetSize (PcdFmpDeviceLockEventGuid) == sizeof (EFI_GUID)) {
    mLockGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceLockEventGuid);
  }

  DEBUG ((DEBUG_INFO, "FmpDxe(%s): Lock GUID: %g\n", mImageIdName, mLockGuid));

  //
  // Register with library the install function so if the library uses
  // UEFI driver model/driver binding protocol it can install FMP on its device handle
  // If library is simple lib that does not use driver binding then it should return
  // unsupported and this will install the FMP instance on the ImageHandle
  //
  Status = RegisterFmpInstaller (InstallFmpInstance);
  if (Status == EFI_UNSUPPORTED) {
    mFmpSingleInstance = TRUE;
    DEBUG ((DEBUG_INFO, "FmpDxe(%s): FmpDeviceLib registration returned EFI_UNSUPPORTED.  Installing single FMP instance.\n", mImageIdName));
    Status = RegisterFmpUninstaller (UninstallFmpInstance);
    if (Status == EFI_UNSUPPORTED) {
      Status = InstallFmpInstance (ImageHandle);
    } else {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n", mImageIdName));
      Status = EFI_UNSUPPORTED;
    }
  } else if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib registration returned %r.  No FMP installed.\n", mImageIdName, Status));
  } else {
    DEBUG ((
      DEBUG_INFO,
      "FmpDxe(%s): FmpDeviceLib registration returned EFI_SUCCESS.  Expect FMP to be installed during the BDS/Device connection phase.\n",
      mImageIdName
      ));
    Status = RegisterFmpUninstaller (UninstallFmpInstance);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n", mImageIdName));
    }
  }

  return Status;
}
