mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-24 06:04:52 +02:00
FmpDevicePkg: Add Last Attempt Status support to dependency libs
The FMP dependency libraries are leveraged during firmware update to check for dependencies required to update the image. This change adds granular Last Attempt Status code support to these services so failures can be more easily observed during the firmware update process via Last Attempt Status codes. Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Guomin Jiang <guomin.jiang@intel.com> Cc: Wei6 Xu <wei6.xu@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Acked-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Wei6 Xu <wei6.xu@intel.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
004ce0ab04
commit
207414cba4
@ -730,6 +730,15 @@ GetAllHeaderSize (
|
|||||||
LAST_ATTEMPT_STATUS_DRIVER_MIN_ERROR_CODE_VALUE
|
LAST_ATTEMPT_STATUS_DRIVER_MIN_ERROR_CODE_VALUE
|
||||||
to LAST_ATTEMPT_STATUS_DRIVER_MAX_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_SUCCESS The image was successfully checked.
|
||||||
@retval EFI_ABORTED The operation is aborted.
|
@retval EFI_ABORTED The operation is aborted.
|
||||||
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
||||||
@ -925,7 +934,16 @@ CheckTheImageInternal (
|
|||||||
//
|
//
|
||||||
// Get the dependency from Image.
|
// Get the dependency from Image.
|
||||||
//
|
//
|
||||||
Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);
|
Dependencies = GetImageDependency (
|
||||||
|
(EFI_FIRMWARE_IMAGE_AUTHENTICATION *) Image,
|
||||||
|
ImageSize,
|
||||||
|
&DependenciesSize,
|
||||||
|
LastAttemptStatus
|
||||||
|
);
|
||||||
|
if (*LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {
|
||||||
|
Status = EFI_ABORTED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check the FmpPayloadHeader
|
// Check the FmpPayloadHeader
|
||||||
@ -964,11 +982,18 @@ CheckTheImageInternal (
|
|||||||
//
|
//
|
||||||
// Evaluate dependency expression
|
// Evaluate dependency expression
|
||||||
//
|
//
|
||||||
Private->DependenciesSatisfied = CheckFmpDependency (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize);
|
Private->DependenciesSatisfied = CheckFmpDependency (
|
||||||
|
Private->Descriptor.ImageTypeId,
|
||||||
|
Version,
|
||||||
|
Dependencies,
|
||||||
|
DependenciesSize,
|
||||||
|
&LocalLastAttemptStatus
|
||||||
|
);
|
||||||
if (!Private->DependenciesSatisfied) {
|
if (!Private->DependenciesSatisfied) {
|
||||||
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName));
|
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName));
|
||||||
*ImageUpdatable = IMAGE_UPDATABLE_INVALID;
|
*ImageUpdatable = IMAGE_UPDATABLE_INVALID;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
*LastAttemptStatus = LocalLastAttemptStatus;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,7 +1206,7 @@ SetTheImage (
|
|||||||
//
|
//
|
||||||
// Get the dependency from Image.
|
// Get the dependency from Image.
|
||||||
//
|
//
|
||||||
Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);
|
Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize, &LastAttemptStatus);
|
||||||
|
|
||||||
//
|
//
|
||||||
// No functional error in CheckTheImage. Attempt to get the Version to
|
// No functional error in CheckTheImage. Attempt to get the Version to
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Fmp Capsule Dependency check functions for Firmware Management Protocol based
|
Fmp Capsule Dependency check functions for Firmware Management Protocol based
|
||||||
firmware updates.
|
firmware updates.
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
@ -21,6 +22,10 @@
|
|||||||
@param[in] Version New version.
|
@param[in] Version New version.
|
||||||
@param[in] Dependencies Fmp dependency.
|
@param[in] Dependencies Fmp dependency.
|
||||||
@param[in] DependenciesSize Size, in bytes, of the 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 TRUE Dependencies are satisfied.
|
||||||
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
||||||
@ -32,7 +37,8 @@ CheckFmpDependency (
|
|||||||
IN EFI_GUID ImageTypeId,
|
IN EFI_GUID ImageTypeId,
|
||||||
IN UINT32 Version,
|
IN UINT32 Version,
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
||||||
IN UINT32 DependenciesSize
|
IN UINT32 DependenciesSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,9 +26,13 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
Validate the dependency expression and output its size.
|
Validate the dependency expression and output its size.
|
||||||
|
|
||||||
@param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
|
@param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
|
||||||
@param[in] MaxDepexSize Max size of the dependency.
|
@param[in] MaxDepexSize Max size of the dependency.
|
||||||
@param[out] DepexSize Size of dependency.
|
@param[out] DepexSize Size of dependency.
|
||||||
|
@param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
|
||||||
|
last attempt status to report back to the caller.
|
||||||
|
If a last attempt status error code is not returned,
|
||||||
|
this function will not modify the LastAttemptStatus value.
|
||||||
|
|
||||||
@retval TRUE The dependency expression is valid.
|
@retval TRUE The dependency expression is valid.
|
||||||
@retval FALSE The dependency expression is invalid.
|
@retval FALSE The dependency expression is invalid.
|
||||||
@ -39,16 +43,20 @@ EFIAPI
|
|||||||
ValidateDependency (
|
ValidateDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
||||||
IN UINTN MaxDepexSize,
|
IN UINTN MaxDepexSize,
|
||||||
OUT UINT32 *DepexSize
|
OUT UINT32 *DepexSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get dependency from firmware image.
|
Get dependency from firmware image.
|
||||||
|
|
||||||
@param[in] Image Points to the firmware image.
|
@param[in] Image Points to the firmware image.
|
||||||
@param[in] ImageSize Size, in bytes, of the firmware image.
|
@param[in] ImageSize Size, in bytes, of the firmware image.
|
||||||
@param[out] DepexSize Size, in bytes, of the dependency.
|
@param[out] DepexSize Size, in bytes, of the dependency.
|
||||||
|
@param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
|
||||||
|
last attempt status to report back to the caller.
|
||||||
|
If a last attempt status error code is not returned,
|
||||||
|
this function will not modify the LastAttemptStatus value.
|
||||||
@retval The pointer to dependency.
|
@retval The pointer to dependency.
|
||||||
@retval Null
|
@retval Null
|
||||||
|
|
||||||
@ -56,9 +64,10 @@ ValidateDependency (
|
|||||||
EFI_FIRMWARE_IMAGE_DEP*
|
EFI_FIRMWARE_IMAGE_DEP*
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GetImageDependency (
|
GetImageDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
|
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
|
||||||
IN UINTN ImageSize,
|
IN UINTN ImageSize,
|
||||||
OUT UINT32 *DepexSize
|
OUT UINT32 *DepexSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,6 +82,10 @@ GetImageDependency (
|
|||||||
parameter is optional and can be set to NULL.
|
parameter is optional and can be set to NULL.
|
||||||
@param[in] FmpVersionsCount Element count of the array. When FmpVersions
|
@param[in] FmpVersionsCount Element count of the array. When FmpVersions
|
||||||
is NULL, FmpVersionsCount must be 0.
|
is NULL, FmpVersionsCount must be 0.
|
||||||
|
@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 Dependency expressions evaluate to TRUE.
|
@retval TRUE Dependency expressions evaluate to TRUE.
|
||||||
@retval FALSE Dependency expressions evaluate to FALSE.
|
@retval FALSE Dependency expressions evaluate to FALSE.
|
||||||
@ -81,10 +94,11 @@ GetImageDependency (
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EvaluateDependency (
|
EvaluateDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
||||||
IN UINTN DependenciesSize,
|
IN UINTN DependenciesSize,
|
||||||
IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,
|
IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions, OPTIONAL
|
||||||
IN UINTN FmpVersionsCount
|
IN UINTN FmpVersionsCount,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Guid/SystemResourceTable.h>
|
||||||
|
#include <LastAttemptStatus.h>
|
||||||
|
#include <FmpLastAttemptStatus.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check dependency for firmware update.
|
Check dependency for firmware update.
|
||||||
@ -25,6 +28,10 @@
|
|||||||
@param[in] Version New version.
|
@param[in] Version New version.
|
||||||
@param[in] Dependencies Fmp dependency.
|
@param[in] Dependencies Fmp dependency.
|
||||||
@param[in] DependenciesSize Size, in bytes, of the 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 TRUE Dependencies are satisfied.
|
||||||
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
||||||
@ -36,7 +43,8 @@ CheckFmpDependency (
|
|||||||
IN EFI_GUID ImageTypeId,
|
IN EFI_GUID ImageTypeId,
|
||||||
IN UINT32 Version,
|
IN UINT32 Version,
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
||||||
IN UINT32 DependenciesSize
|
IN UINT32 DependenciesSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -44,6 +52,7 @@ CheckFmpDependency (
|
|||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
||||||
UINTN ImageInfoSize;
|
UINTN ImageInfoSize;
|
||||||
|
UINT32 LocalLastAttemptStatus;
|
||||||
UINT32 *DescriptorVer;
|
UINT32 *DescriptorVer;
|
||||||
UINT8 FmpImageInfoCount;
|
UINT8 FmpImageInfoCount;
|
||||||
UINTN *DescriptorSize;
|
UINTN *DescriptorSize;
|
||||||
@ -55,14 +64,15 @@ CheckFmpDependency (
|
|||||||
UINTN FmpVersionsCount;
|
UINTN FmpVersionsCount;
|
||||||
BOOLEAN IsSatisfied;
|
BOOLEAN IsSatisfied;
|
||||||
|
|
||||||
FmpImageInfoBuf = NULL;
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
|
||||||
DescriptorVer = NULL;
|
FmpImageInfoBuf = NULL;
|
||||||
DescriptorSize = NULL;
|
DescriptorVer = NULL;
|
||||||
NumberOfFmpInstance = 0;
|
DescriptorSize = NULL;
|
||||||
FmpVersions = NULL;
|
NumberOfFmpInstance = 0;
|
||||||
FmpVersionsCount = 0;
|
FmpVersions = NULL;
|
||||||
IsSatisfied = TRUE;
|
FmpVersionsCount = 0;
|
||||||
PackageVersionName = NULL;
|
IsSatisfied = TRUE;
|
||||||
|
PackageVersionName = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
|
// Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
|
||||||
@ -77,30 +87,35 @@ CheckFmpDependency (
|
|||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
|
DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
|
||||||
IsSatisfied = FALSE;
|
IsSatisfied = FALSE;
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
|
FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
|
||||||
if (FmpImageInfoBuf == NULL) {
|
if (FmpImageInfoBuf == NULL) {
|
||||||
IsSatisfied = FALSE;
|
IsSatisfied = FALSE;
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance);
|
DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance);
|
||||||
if (DescriptorVer == NULL ) {
|
if (DescriptorVer == NULL ) {
|
||||||
IsSatisfied = FALSE;
|
IsSatisfied = FALSE;
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance);
|
DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance);
|
||||||
if (DescriptorSize == NULL ) {
|
if (DescriptorSize == NULL ) {
|
||||||
IsSatisfied = FALSE;
|
IsSatisfied = FALSE;
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
|
FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
|
||||||
if (FmpVersions == NULL) {
|
if (FmpVersions == NULL) {
|
||||||
IsSatisfied = FALSE;
|
IsSatisfied = FALSE;
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +179,7 @@ CheckFmpDependency (
|
|||||||
// Evaluate firmware image's depex, against the version of other Fmp instances.
|
// Evaluate firmware image's depex, against the version of other Fmp instances.
|
||||||
//
|
//
|
||||||
if (Dependencies != NULL) {
|
if (Dependencies != NULL) {
|
||||||
IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount);
|
IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount, &LocalLastAttemptStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsSatisfied) {
|
if (!IsSatisfied) {
|
||||||
@ -194,5 +209,9 @@ cleanup:
|
|||||||
FreePool (FmpVersions);
|
FreePool (FmpVersions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LastAttemptStatus != NULL) {
|
||||||
|
*LastAttemptStatus = LocalLastAttemptStatus;
|
||||||
|
}
|
||||||
|
|
||||||
return IsSatisfied;
|
return IsSatisfied;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
Null instance of FmpDependencyCheckLib.
|
Null instance of FmpDependencyCheckLib.
|
||||||
|
|
||||||
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||||
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
#include <Guid/SystemResourceTable.h>
|
||||||
#include <Library/FmpDependencyCheckLib.h>
|
#include <Library/FmpDependencyCheckLib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,7 +18,10 @@
|
|||||||
@param[in] Version New version.
|
@param[in] Version New version.
|
||||||
@param[in] Dependencies Fmp dependency.
|
@param[in] Dependencies Fmp dependency.
|
||||||
@param[in] DependenciesSize Size, in bytes, of the 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 TRUE Dependencies are satisfied.
|
||||||
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
@retval FALSE Dependencies are unsatisfied or dependency check fails.
|
||||||
|
|
||||||
@ -27,8 +32,13 @@ CheckFmpDependency (
|
|||||||
IN EFI_GUID ImageTypeId,
|
IN EFI_GUID ImageTypeId,
|
||||||
IN UINT32 Version,
|
IN UINT32 Version,
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
|
||||||
IN UINT32 DependenciesSize
|
IN UINT32 DependenciesSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (LastAttemptStatus != NULL) {
|
||||||
|
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/FmpDependencyLib.h>
|
#include <Library/FmpDependencyLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Guid/SystemResourceTable.h>
|
||||||
|
#include <LastAttemptStatus.h>
|
||||||
|
#include <FmpLastAttemptStatus.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define the initial size of the dependency expression evaluation stack
|
// Define the initial size of the dependency expression evaluation stack
|
||||||
@ -203,6 +206,10 @@ Pop (
|
|||||||
parameter is optional and can be set to NULL.
|
parameter is optional and can be set to NULL.
|
||||||
@param[in] FmpVersionsCount Element count of the array. When FmpVersions
|
@param[in] FmpVersionsCount Element count of the array. When FmpVersions
|
||||||
is NULL, FmpVersionsCount must be 0.
|
is NULL, FmpVersionsCount must be 0.
|
||||||
|
@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 Dependency expressions evaluate to TRUE.
|
@retval TRUE Dependency expressions evaluate to TRUE.
|
||||||
@retval FALSE Dependency expressions evaluate to FALSE.
|
@retval FALSE Dependency expressions evaluate to FALSE.
|
||||||
@ -211,10 +218,11 @@ Pop (
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EvaluateDependency (
|
EvaluateDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
||||||
IN UINTN DependenciesSize,
|
IN UINTN DependenciesSize,
|
||||||
IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,
|
IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions, OPTIONAL
|
||||||
IN UINTN FmpVersionsCount
|
IN UINTN FmpVersionsCount,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -224,6 +232,9 @@ EvaluateDependency (
|
|||||||
DEPEX_ELEMENT Element2;
|
DEPEX_ELEMENT Element2;
|
||||||
GUID ImageTypeId;
|
GUID ImageTypeId;
|
||||||
UINT32 Version;
|
UINT32 Version;
|
||||||
|
UINT32 LocalLastAttemptStatus;
|
||||||
|
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if parameter is valid.
|
// Check if parameter is valid.
|
||||||
@ -249,6 +260,7 @@ EvaluateDependency (
|
|||||||
case EFI_FMP_DEP_PUSH_GUID:
|
case EFI_FMP_DEP_PUSH_GUID:
|
||||||
if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
|
if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end of dependency expression!\n"));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end of dependency expression!\n"));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GUID_BEYOND_DEPEX;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +271,7 @@ EvaluateDependency (
|
|||||||
if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){
|
if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){
|
||||||
Status = Push (FmpVersions[Index].Version, VersionType);
|
Status = Push (FmpVersions[Index].Version, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -266,18 +279,21 @@ EvaluateDependency (
|
|||||||
}
|
}
|
||||||
if (Index == FmpVersionsCount) {
|
if (Index == FmpVersionsCount) {
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &ImageTypeId));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &ImageTypeId));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_FMP_NOT_FOUND;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_PUSH_VERSION:
|
case EFI_FMP_DEP_PUSH_VERSION:
|
||||||
if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {
|
if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond end of dependency expression!\n"));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond end of dependency expression!\n"));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_BEYOND_DEPEX;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version = *(UINT32 *) (Iterator + 1);
|
Version = *(UINT32 *) (Iterator + 1);
|
||||||
Status = Push (Version, VersionType);
|
Status = Push (Version, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Iterator = Iterator + sizeof (UINT32);
|
Iterator = Iterator + sizeof (UINT32);
|
||||||
@ -286,154 +302,191 @@ EvaluateDependency (
|
|||||||
Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies));
|
Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies));
|
||||||
if (Iterator == (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
|
if (Iterator == (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond end of dependency expression!\n"));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond end of dependency expression!\n"));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_STR_BEYOND_DEPEX;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_AND:
|
case EFI_FMP_DEP_AND:
|
||||||
Status = Pop (&Element1, BooleanType);
|
Status = Pop (&Element1, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, BooleanType);
|
Status = Pop (&Element2, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType);
|
Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_OR:
|
case EFI_FMP_DEP_OR:
|
||||||
Status = Pop (&Element1, BooleanType);
|
Status = Pop (&Element1, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop(&Element2, BooleanType);
|
Status = Pop(&Element2, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType);
|
Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_NOT:
|
case EFI_FMP_DEP_NOT:
|
||||||
Status = Pop (&Element1, BooleanType);
|
Status = Pop (&Element1, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Push (!(Element1.Value.Boolean), BooleanType);
|
Status = Push (!(Element1.Value.Boolean), BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_TRUE:
|
case EFI_FMP_DEP_TRUE:
|
||||||
Status = Push (TRUE, BooleanType);
|
Status = Push (TRUE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_FALSE:
|
case EFI_FMP_DEP_FALSE:
|
||||||
Status = Push (FALSE, BooleanType);
|
Status = Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_EQ:
|
case EFI_FMP_DEP_EQ:
|
||||||
Status = Pop (&Element1, VersionType);
|
Status = Pop (&Element1, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, VersionType);
|
Status = Pop (&Element2, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_GT:
|
case EFI_FMP_DEP_GT:
|
||||||
Status = Pop (&Element1, VersionType);
|
Status = Pop (&Element1, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, VersionType);
|
Status = Pop (&Element2, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_GTE:
|
case EFI_FMP_DEP_GTE:
|
||||||
Status = Pop (&Element1, VersionType);
|
Status = Pop (&Element1, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, VersionType);
|
Status = Pop (&Element2, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_LT:
|
case EFI_FMP_DEP_LT:
|
||||||
Status = Pop (&Element1, VersionType);
|
Status = Pop (&Element1, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, VersionType);
|
Status = Pop (&Element2, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus= LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_LTE:
|
case EFI_FMP_DEP_LTE:
|
||||||
Status = Pop (&Element1, VersionType);
|
Status = Pop (&Element1, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = Pop (&Element2, VersionType);
|
Status = Pop (&Element2, VersionType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_FMP_DEP_END:
|
case EFI_FMP_DEP_END:
|
||||||
Status = Pop (&Element1, BooleanType);
|
Status = Pop (&Element1, BooleanType);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
return Element1.Value.Boolean;
|
return Element1.Value.Boolean;
|
||||||
default:
|
default:
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n", *Iterator));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n", *Iterator));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_UNKNOWN_OPCODE;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
Iterator++;
|
Iterator++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in expression!\n"));
|
DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in expression!\n"));
|
||||||
|
LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
|
if (LastAttemptStatus != NULL) {
|
||||||
|
*LastAttemptStatus = LocalLastAttemptStatus;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Validate the dependency expression and output its size.
|
Validate the dependency expression and output its size.
|
||||||
|
|
||||||
@param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
|
@param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
|
||||||
@param[in] MaxDepexSize Max size of the dependency.
|
@param[in] MaxDepexSize Max size of the dependency.
|
||||||
@param[out] DepexSize Size of dependency.
|
@param[out] DepexSize Size of dependency.
|
||||||
|
@param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
|
||||||
|
last attempt status to report back to the caller.
|
||||||
|
If a last attempt status error code is not returned,
|
||||||
|
this function will not modify the LastAttemptStatus value.
|
||||||
|
|
||||||
@retval TRUE The dependency expression is valid.
|
@retval TRUE The dependency expression is valid.
|
||||||
@retval FALSE The dependency expression is invalid.
|
@retval FALSE The dependency expression is invalid.
|
||||||
@ -444,7 +497,8 @@ EFIAPI
|
|||||||
ValidateDependency (
|
ValidateDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
|
||||||
IN UINTN MaxDepexSize,
|
IN UINTN MaxDepexSize,
|
||||||
OUT UINT32 *DepexSize
|
OUT UINT32 *DepexSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT8 *Depex;
|
UINT8 *Depex;
|
||||||
@ -493,16 +547,23 @@ ValidateDependency (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LastAttemptStatus != NULL) {
|
||||||
|
*LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get dependency from firmware image.
|
Get dependency from firmware image.
|
||||||
|
|
||||||
@param[in] Image Points to the firmware image.
|
@param[in] Image Points to the firmware image.
|
||||||
@param[in] ImageSize Size, in bytes, of the firmware image.
|
@param[in] ImageSize Size, in bytes, of the firmware image.
|
||||||
@param[out] DepexSize Size, in bytes, of the dependency.
|
@param[out] DepexSize Size, in bytes, of the dependency.
|
||||||
|
@param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
|
||||||
|
last attempt status to report back to the caller.
|
||||||
|
If a last attempt status error code is not returned,
|
||||||
|
this function will not modify the LastAttemptStatus value.
|
||||||
@retval The pointer to dependency.
|
@retval The pointer to dependency.
|
||||||
@retval Null
|
@retval Null
|
||||||
|
|
||||||
@ -512,7 +573,8 @@ EFIAPI
|
|||||||
GetImageDependency (
|
GetImageDependency (
|
||||||
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
|
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
|
||||||
IN UINTN ImageSize,
|
IN UINTN ImageSize,
|
||||||
OUT UINT32 *DepexSize
|
OUT UINT32 *DepexSize,
|
||||||
|
OUT UINT32 *LastAttemptStatus OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_FIRMWARE_IMAGE_DEP *Depex;
|
EFI_FIRMWARE_IMAGE_DEP *Depex;
|
||||||
@ -530,6 +592,9 @@ GetImageDependency (
|
|||||||
//
|
//
|
||||||
// Pointer overflow. Invalid image.
|
// Pointer overflow. Invalid image.
|
||||||
//
|
//
|
||||||
|
if (LastAttemptStatus != NULL) {
|
||||||
|
*LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GET_DEPEX_FAILURE;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +604,7 @@ GetImageDependency (
|
|||||||
//
|
//
|
||||||
// Validate the dependency and get the size of dependency
|
// Validate the dependency and get the size of dependency
|
||||||
//
|
//
|
||||||
if (ValidateDependency (Depex, MaxDepexSize, DepexSize)) {
|
if (ValidateDependency (Depex, MaxDepexSize, DepexSize, LastAttemptStatus)) {
|
||||||
return Depex;
|
return Depex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Unit tests of EvaluateDependency API in FmpDependencyLib.
|
Unit tests of EvaluateDependency API in FmpDependencyLib.
|
||||||
|
|
||||||
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||||
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@ -162,6 +163,7 @@ EvaluateDependencyTest (
|
|||||||
{
|
{
|
||||||
BASIC_TEST_CONTEXT *TestContext;
|
BASIC_TEST_CONTEXT *TestContext;
|
||||||
BOOLEAN EvaluationResult;
|
BOOLEAN EvaluationResult;
|
||||||
|
UINT32 LastAttemptStatus;
|
||||||
|
|
||||||
TestContext = (BASIC_TEST_CONTEXT *)Context;
|
TestContext = (BASIC_TEST_CONTEXT *)Context;
|
||||||
|
|
||||||
@ -169,8 +171,9 @@ EvaluateDependencyTest (
|
|||||||
(EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,
|
(EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,
|
||||||
TestContext->DependenciesSize,
|
TestContext->DependenciesSize,
|
||||||
mFmpVersions,
|
mFmpVersions,
|
||||||
sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA)
|
sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA),
|
||||||
);
|
&LastAttemptStatus
|
||||||
|
);
|
||||||
|
|
||||||
UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);
|
UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user