LAST_ATTEMPT_STATUS_DRIVER_MIN_ERROR_CODE_VALUE\r
to LAST_ATTEMPT_STATUS_DRIVER_MAX_ERROR_CODE_VALUE.\r
\r
+ This function might also return error codes that occur within libraries\r
+ linked against this module that return last attempt error codes such as:\r
+\r
+ LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_LIB_MIN_ERROR_CODE_VALUE to\r
+ LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_LIB_MAX_ERROR_CODE_VALUE\r
+\r
+ LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_CHECK_LIB_MIN_ERROR_CODE_VALUE to\r
+ LAST_ATTEMPT_STATUS_FMP_DEPENDENCY_CHECK_LIB_MAX_ERROR_CODE_VALUE\r
+\r
@retval EFI_SUCCESS The image was successfully checked.\r
@retval EFI_ABORTED The operation is aborted.\r
@retval EFI_INVALID_PARAMETER The Image was NULL.\r
//\r
// Get the dependency from Image.\r
//\r
- Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);\r
+ Dependencies = GetImageDependency (\r
+ (EFI_FIRMWARE_IMAGE_AUTHENTICATION *) Image,\r
+ ImageSize,\r
+ &DependenciesSize,\r
+ LastAttemptStatus\r
+ );\r
+ if (*LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {\r
+ Status = EFI_ABORTED;\r
+ goto cleanup;\r
+ }\r
\r
//\r
// Check the FmpPayloadHeader\r
//\r
// Evaluate dependency expression\r
//\r
- Private->DependenciesSatisfied = CheckFmpDependency (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize);\r
+ Private->DependenciesSatisfied = CheckFmpDependency (\r
+ Private->Descriptor.ImageTypeId,\r
+ Version,\r
+ Dependencies,\r
+ DependenciesSize,\r
+ &LocalLastAttemptStatus\r
+ );\r
if (!Private->DependenciesSatisfied) {\r
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName));\r
*ImageUpdatable = IMAGE_UPDATABLE_INVALID;\r
Status = EFI_SUCCESS;\r
+ *LastAttemptStatus = LocalLastAttemptStatus;\r
goto cleanup;\r
}\r
\r
//\r
// Get the dependency from Image.\r
//\r
- Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);\r
+ Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize, &LastAttemptStatus);\r
\r
//\r
// No functional error in CheckTheImage. Attempt to get the Version to\r
Fmp Capsule Dependency check functions for Firmware Management Protocol based\r
firmware updates.\r
\r
+ Copyright (c) Microsoft Corporation.<BR>\r
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
@param[in] Version New version.\r
@param[in] Dependencies Fmp dependency.\r
@param[in] DependenciesSize Size, in bytes, of the Fmp dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r
+ if an error code is not set.\r
\r
@retval TRUE Dependencies are satisfied.\r
@retval FALSE Dependencies are unsatisfied or dependency check fails.\r
IN EFI_GUID ImageTypeId,\r
IN UINT32 Version,\r
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL\r
- IN UINT32 DependenciesSize\r
+ IN UINT32 DependenciesSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
);\r
\r
#endif\r
/**\r
Validate the dependency expression and output its size.\r
\r
- @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.\r
- @param[in] MaxDepexSize Max size of the dependency.\r
- @param[out] DepexSize Size of dependency.\r
+ @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.\r
+ @param[in] MaxDepexSize Max size of the dependency.\r
+ @param[out] DepexSize Size of dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ If a last attempt status error code is not returned,\r
+ this function will not modify the LastAttemptStatus value.\r
\r
@retval TRUE The dependency expression is valid.\r
@retval FALSE The dependency expression is invalid.\r
ValidateDependency (\r
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
IN UINTN MaxDepexSize,\r
- OUT UINT32 *DepexSize\r
+ OUT UINT32 *DepexSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
);\r
\r
/**\r
Get dependency from firmware image.\r
\r
- @param[in] Image Points to the firmware image.\r
- @param[in] ImageSize Size, in bytes, of the firmware image.\r
- @param[out] DepexSize Size, in bytes, of the dependency.\r
-\r
+ @param[in] Image Points to the firmware image.\r
+ @param[in] ImageSize Size, in bytes, of the firmware image.\r
+ @param[out] DepexSize Size, in bytes, of the dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ If a last attempt status error code is not returned,\r
+ this function will not modify the LastAttemptStatus value.\r
@retval The pointer to dependency.\r
@retval Null\r
\r
EFI_FIRMWARE_IMAGE_DEP*\r
EFIAPI\r
GetImageDependency (\r
- IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,\r
- IN UINTN ImageSize,\r
- OUT UINT32 *DepexSize\r
+ IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,\r
+ IN UINTN ImageSize,\r
+ OUT UINT32 *DepexSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
);\r
\r
/**\r
parameter is optional and can be set to NULL.\r
@param[in] FmpVersionsCount Element count of the array. When FmpVersions\r
is NULL, FmpVersionsCount must be 0.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r
+ if an error code is not set.\r
\r
@retval TRUE Dependency expressions evaluate to TRUE.\r
@retval FALSE Dependency expressions evaluate to FALSE.\r
BOOLEAN\r
EFIAPI\r
EvaluateDependency (\r
- IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
- IN UINTN DependenciesSize,\r
- IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,\r
- IN UINTN FmpVersionsCount\r
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
+ IN UINTN DependenciesSize,\r
+ IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions, OPTIONAL\r
+ IN UINTN FmpVersionsCount,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
);\r
\r
#endif\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
+#include <Guid/SystemResourceTable.h>\r
+#include <LastAttemptStatus.h>\r
+#include <FmpLastAttemptStatus.h>\r
\r
/**\r
Check dependency for firmware update.\r
@param[in] Version New version.\r
@param[in] Dependencies Fmp dependency.\r
@param[in] DependenciesSize Size, in bytes, of the Fmp dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r
+ if an error code is not set.\r
\r
@retval TRUE Dependencies are satisfied.\r
@retval FALSE Dependencies are unsatisfied or dependency check fails.\r
IN EFI_GUID ImageTypeId,\r
IN UINT32 Version,\r
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL\r
- IN UINT32 DependenciesSize\r
+ IN UINT32 DependenciesSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
UINTN Index;\r
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
UINTN ImageInfoSize;\r
+ UINT32 LocalLastAttemptStatus;\r
UINT32 *DescriptorVer;\r
UINT8 FmpImageInfoCount;\r
UINTN *DescriptorSize;\r
UINTN FmpVersionsCount;\r
BOOLEAN IsSatisfied;\r
\r
- FmpImageInfoBuf = NULL;\r
- DescriptorVer = NULL;\r
- DescriptorSize = NULL;\r
- NumberOfFmpInstance = 0;\r
- FmpVersions = NULL;\r
- FmpVersionsCount = 0;\r
- IsSatisfied = TRUE;\r
- PackageVersionName = NULL;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
+ FmpImageInfoBuf = NULL;\r
+ DescriptorVer = NULL;\r
+ DescriptorSize = NULL;\r
+ NumberOfFmpInstance = 0;\r
+ FmpVersions = NULL;\r
+ FmpVersionsCount = 0;\r
+ IsSatisfied = TRUE;\r
+ PackageVersionName = NULL;\r
\r
//\r
// Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.\r
if (EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));\r
IsSatisfied = FALSE;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND;\r
goto cleanup;\r
}\r
\r
FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);\r
if (FmpImageInfoBuf == NULL) {\r
IsSatisfied = FALSE;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED;\r
goto cleanup;\r
}\r
\r
DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance);\r
if (DescriptorVer == NULL ) {\r
IsSatisfied = FALSE;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED;\r
goto cleanup;\r
}\r
\r
DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance);\r
if (DescriptorSize == NULL ) {\r
IsSatisfied = FALSE;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED;\r
goto cleanup;\r
}\r
\r
FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);\r
if (FmpVersions == NULL) {\r
IsSatisfied = FALSE;\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED;\r
goto cleanup;\r
}\r
\r
// Evaluate firmware image's depex, against the version of other Fmp instances.\r
//\r
if (Dependencies != NULL) {\r
- IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount);\r
+ IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount, &LocalLastAttemptStatus);\r
}\r
\r
if (!IsSatisfied) {\r
FreePool (FmpVersions);\r
}\r
\r
+ if (LastAttemptStatus != NULL) {\r
+ *LastAttemptStatus = LocalLastAttemptStatus;\r
+ }\r
+\r
return IsSatisfied;\r
}\r
Null instance of FmpDependencyCheckLib.\r
\r
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) Microsoft Corporation.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#include <PiDxe.h>\r
+#include <Guid/SystemResourceTable.h>\r
#include <Library/FmpDependencyCheckLib.h>\r
\r
/**\r
@param[in] Version New version.\r
@param[in] Dependencies Fmp dependency.\r
@param[in] DependenciesSize Size, in bytes, of the Fmp dependency.\r
-\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r
+ if an error code is not set.\r
@retval TRUE Dependencies are satisfied.\r
@retval FALSE Dependencies are unsatisfied or dependency check fails.\r
\r
IN EFI_GUID ImageTypeId,\r
IN UINT32 Version,\r
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL\r
- IN UINT32 DependenciesSize\r
+ IN UINT32 DependenciesSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
)\r
{\r
+ if (LastAttemptStatus != NULL) {\r
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
+ }\r
+\r
return TRUE;\r
}\r
#include <Library/DebugLib.h>\r
#include <Library/FmpDependencyLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Guid/SystemResourceTable.h>\r
+#include <LastAttemptStatus.h>\r
+#include <FmpLastAttemptStatus.h>\r
\r
//\r
// Define the initial size of the dependency expression evaluation stack\r
parameter is optional and can be set to NULL.\r
@param[in] FmpVersionsCount Element count of the array. When FmpVersions\r
is NULL, FmpVersionsCount must be 0.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r
+ if an error code is not set.\r
\r
@retval TRUE Dependency expressions evaluate to TRUE.\r
@retval FALSE Dependency expressions evaluate to FALSE.\r
BOOLEAN\r
EFIAPI\r
EvaluateDependency (\r
- IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
- IN UINTN DependenciesSize,\r
- IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,\r
- IN UINTN FmpVersionsCount\r
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
+ IN UINTN DependenciesSize,\r
+ IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions, OPTIONAL\r
+ IN UINTN FmpVersionsCount,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
DEPEX_ELEMENT Element2;\r
GUID ImageTypeId;\r
UINT32 Version;\r
+ UINT32 LocalLastAttemptStatus;\r
+\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
\r
//\r
// Check if parameter is valid.\r
case EFI_FMP_DEP_PUSH_GUID:\r
if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) {\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end of dependency expression!\n"));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GUID_BEYOND_DEPEX;\r
goto Error;\r
}\r
\r
if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){\r
Status = Push (FmpVersions[Index].Version, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
}\r
if (Index == FmpVersionsCount) {\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &ImageTypeId));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_FMP_NOT_FOUND;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_PUSH_VERSION:\r
if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond end of dependency expression!\n"));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_BEYOND_DEPEX;\r
goto Error;\r
}\r
\r
Version = *(UINT32 *) (Iterator + 1);\r
Status = Push (Version, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
Iterator = Iterator + sizeof (UINT32);\r
Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies));\r
if (Iterator == (UINT8 *) Dependencies->Dependencies + DependenciesSize) {\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond end of dependency expression!\n"));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_STR_BEYOND_DEPEX;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_AND:\r
Status = Pop (&Element1, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_OR:\r
Status = Pop (&Element1, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop(&Element2, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_NOT:\r
Status = Pop (&Element1, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Push (!(Element1.Value.Boolean), BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_TRUE:\r
Status = Push (TRUE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_FALSE:\r
Status = Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_EQ:\r
Status = Pop (&Element1, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_GT:\r
Status = Pop (&Element1, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_GTE:\r
Status = Pop (&Element1, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_LT:\r
Status = Pop (&Element1, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus= LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_LTE:\r
Status = Pop (&Element1, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = Pop (&Element2, VersionType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;\r
goto Error;\r
}\r
break;\r
case EFI_FMP_DEP_END:\r
Status = Pop (&Element1, BooleanType);\r
if (EFI_ERROR (Status)) {\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;\r
goto Error;\r
}\r
return Element1.Value.Boolean;\r
default:\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n", *Iterator));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_UNKNOWN_OPCODE;\r
goto Error;\r
}\r
Iterator++;\r
}\r
\r
DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in expression!\n"));\r
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;\r
\r
Error:\r
+ if (LastAttemptStatus != NULL) {\r
+ *LastAttemptStatus = LocalLastAttemptStatus;\r
+ }\r
+\r
return FALSE;\r
}\r
\r
/**\r
Validate the dependency expression and output its size.\r
\r
- @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.\r
- @param[in] MaxDepexSize Max size of the dependency.\r
- @param[out] DepexSize Size of dependency.\r
+ @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.\r
+ @param[in] MaxDepexSize Max size of the dependency.\r
+ @param[out] DepexSize Size of dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ If a last attempt status error code is not returned,\r
+ this function will not modify the LastAttemptStatus value.\r
\r
@retval TRUE The dependency expression is valid.\r
@retval FALSE The dependency expression is invalid.\r
ValidateDependency (\r
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,\r
IN UINTN MaxDepexSize,\r
- OUT UINT32 *DepexSize\r
+ OUT UINT32 *DepexSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
)\r
{\r
UINT8 *Depex;\r
}\r
}\r
\r
+ if (LastAttemptStatus != NULL) {\r
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;\r
+ }\r
+\r
return FALSE;\r
}\r
\r
/**\r
Get dependency from firmware image.\r
\r
- @param[in] Image Points to the firmware image.\r
- @param[in] ImageSize Size, in bytes, of the firmware image.\r
- @param[out] DepexSize Size, in bytes, of the dependency.\r
-\r
+ @param[in] Image Points to the firmware image.\r
+ @param[in] ImageSize Size, in bytes, of the firmware image.\r
+ @param[out] DepexSize Size, in bytes, of the dependency.\r
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r
+ last attempt status to report back to the caller.\r
+ If a last attempt status error code is not returned,\r
+ this function will not modify the LastAttemptStatus value.\r
@retval The pointer to dependency.\r
@retval Null\r
\r
GetImageDependency (\r
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,\r
IN UINTN ImageSize,\r
- OUT UINT32 *DepexSize\r
+ OUT UINT32 *DepexSize,\r
+ OUT UINT32 *LastAttemptStatus OPTIONAL\r
)\r
{\r
EFI_FIRMWARE_IMAGE_DEP *Depex;\r
//\r
// Pointer overflow. Invalid image.\r
//\r
+ if (LastAttemptStatus != NULL) {\r
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GET_DEPEX_FAILURE;\r
+ }\r
return NULL;\r
}\r
\r
//\r
// Validate the dependency and get the size of dependency\r
//\r
- if (ValidateDependency (Depex, MaxDepexSize, DepexSize)) {\r
+ if (ValidateDependency (Depex, MaxDepexSize, DepexSize, LastAttemptStatus)) {\r
return Depex;\r
}\r
\r
Unit tests of EvaluateDependency API in FmpDependencyLib.\r
\r
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) Microsoft Corporation.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
{\r
BASIC_TEST_CONTEXT *TestContext;\r
BOOLEAN EvaluationResult;\r
+ UINT32 LastAttemptStatus;\r
\r
TestContext = (BASIC_TEST_CONTEXT *)Context;\r
\r
(EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,\r
TestContext->DependenciesSize,\r
mFmpVersions,\r
- sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA)\r
- );\r
+ sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA),\r
+ &LastAttemptStatus\r
+ );\r
\r
UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);\r
\r