From 064daac0c69049993f7dbdaf9864a812a0205dfd Mon Sep 17 00:00:00 2001 From: Liming Gao Date: Wed, 10 Jul 2019 23:25:21 +0800 Subject: Revert "BaseTools/FCE: Add a tool FCE" This reverts commit 3c59d94637adbfdd497b5a2c16073c7dc62b669c. There are the concerns on code design and code quality, and request to rewrite FCE, BfmLib and FMMT for the review. Cc: Leif Lindholm Cc: Feng Bob C Signed-off-by: Liming Gao Reviewed-by: Feng Bob C --- BaseTools/BinWrappers/PosixLike/FCE | 29 - BaseTools/Source/C/FCE/BinaryCreate.c | 216 - BaseTools/Source/C/FCE/BinaryCreate.h | 157 - BaseTools/Source/C/FCE/BinaryParse.c | 1326 ----- BaseTools/Source/C/FCE/BinaryParse.h | 187 - BaseTools/Source/C/FCE/Common.c | 2183 -------- BaseTools/Source/C/FCE/Common.h | 999 ---- BaseTools/Source/C/FCE/Expression.c | 2367 --------- BaseTools/Source/C/FCE/Fce.c | 6449 ----------------------- BaseTools/Source/C/FCE/Fce.h | 447 -- BaseTools/Source/C/FCE/GNUmakefile | 55 - BaseTools/Source/C/FCE/IfrParse.c | 4836 ----------------- BaseTools/Source/C/FCE/IfrParse.h | 789 --- BaseTools/Source/C/FCE/Makefile | 19 - BaseTools/Source/C/FCE/MonotonicBasedVariable.c | 874 --- BaseTools/Source/C/FCE/MonotonicBasedVariable.h | 162 - BaseTools/Source/C/FCE/TimeBasedVariable.c | 878 --- BaseTools/Source/C/FCE/TimeBasedVariable.h | 166 - BaseTools/Source/C/FCE/Variable.c | 1091 ---- BaseTools/Source/C/FCE/Variable.h | 154 - BaseTools/Source/C/FCE/VariableCommon.h | 55 - BaseTools/Source/C/GNUmakefile | 3 +- BaseTools/Source/C/Makefile | 3 +- 23 files changed, 2 insertions(+), 23443 deletions(-) delete mode 100755 BaseTools/BinWrappers/PosixLike/FCE delete mode 100644 BaseTools/Source/C/FCE/BinaryCreate.c delete mode 100644 BaseTools/Source/C/FCE/BinaryCreate.h delete mode 100644 BaseTools/Source/C/FCE/BinaryParse.c delete mode 100644 BaseTools/Source/C/FCE/BinaryParse.h delete mode 100644 BaseTools/Source/C/FCE/Common.c delete mode 100644 BaseTools/Source/C/FCE/Common.h delete mode 100644 BaseTools/Source/C/FCE/Expression.c delete mode 100644 BaseTools/Source/C/FCE/Fce.c delete mode 100644 BaseTools/Source/C/FCE/Fce.h delete mode 100644 BaseTools/Source/C/FCE/GNUmakefile delete mode 100644 BaseTools/Source/C/FCE/IfrParse.c delete mode 100644 BaseTools/Source/C/FCE/IfrParse.h delete mode 100644 BaseTools/Source/C/FCE/Makefile delete mode 100644 BaseTools/Source/C/FCE/MonotonicBasedVariable.c delete mode 100644 BaseTools/Source/C/FCE/MonotonicBasedVariable.h delete mode 100644 BaseTools/Source/C/FCE/TimeBasedVariable.c delete mode 100644 BaseTools/Source/C/FCE/TimeBasedVariable.h delete mode 100644 BaseTools/Source/C/FCE/Variable.c delete mode 100644 BaseTools/Source/C/FCE/Variable.h delete mode 100644 BaseTools/Source/C/FCE/VariableCommon.h diff --git a/BaseTools/BinWrappers/PosixLike/FCE b/BaseTools/BinWrappers/PosixLike/FCE deleted file mode 100755 index a244ecc095..0000000000 --- a/BaseTools/BinWrappers/PosixLike/FCE +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here -dir=$(dirname "$full_cmd") -cmd=${full_cmd##*/} - -if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] -then - exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" -elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] -then - if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] - then - echo "BaseTools C Tool binary was not found ($cmd)" - echo "You may need to run:" - echo " make -C $EDK_TOOLS_PATH/Source/C" - else - exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" - fi -elif [ -e "$dir/../../Source/C/bin/$cmd" ] -then - exec "$dir/../../Source/C/bin/$cmd" "$@" -else - echo "Unable to find the real '$cmd' to run" - echo "This message was printed by" - echo " $0" - exit 127 -fi - diff --git a/BaseTools/Source/C/FCE/BinaryCreate.c b/BaseTools/Source/C/FCE/BinaryCreate.c deleted file mode 100644 index 2f36bc2ef3..0000000000 --- a/BaseTools/Source/C/FCE/BinaryCreate.c +++ /dev/null @@ -1,216 +0,0 @@ -/** @file - - The API to create the binary. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "BinaryCreate.h" -#ifndef __GNUC__ -#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > NUL" -#else -#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > /dev/null" -#endif - -// -// The guid is to for FFS of BFV. -// -EFI_GUID gEfiFfsBfvForMultiPlatformGuid = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID; -EFI_GUID gEfiFfsBfvForMultiPlatformGuid2 = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2; - -/** - Convert a GUID to a string. - - @param[in] Guid Pointer to GUID to print. - - @return The string after convert. -**/ -static -CHAR8 * -LibBfmGuidToStr ( - IN EFI_GUID *Guid -) -{ - CHAR8 * Buffer; - - Buffer = NULL; - - if (Guid == NULL) { - return NULL; - } - - Buffer = (CHAR8 *) malloc (36 + 1); - - if (Buffer == NULL) { - return NULL; - } - memset (Buffer, '\0', 36 + 1); - - sprintf ( - Buffer, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - Guid->Data1, - Guid->Data2, - Guid->Data3, - Guid->Data4[0], - Guid->Data4[1], - Guid->Data4[2], - Guid->Data4[3], - Guid->Data4[4], - Guid->Data4[5], - Guid->Data4[6], - Guid->Data4[7] - ); - - return Buffer; -} - -/** - Create the Ras section in FFS - - @param[in] InputFilePath .efi file, it's optional unless process PE/TE section. - @param[in] OutputFilePath .te or .pe file - - @retval EFI_SUCCESS - -**/ -EFI_STATUS -CreateRawSection ( - IN CHAR8* InputFilePath, - IN CHAR8* OutputFilePath - ) -{ - INT32 ReturnValue; - CHAR8* SystemCommand; - - SystemCommand = NULL; - SystemCommand = malloc ( - strlen (GENSEC_RAW) + - strlen ("EFI_SECTION_RAW") + - strlen (InputFilePath) + - strlen (OutputFilePath) + - 1 - ); - if (NULL == SystemCommand) { - return EFI_OUT_OF_RESOURCES; - } - sprintf ( - SystemCommand, - GENSEC_RAW, - "EFI_SECTION_RAW", - InputFilePath, - OutputFilePath - ); - ReturnValue = system (SystemCommand); - free(SystemCommand); - - if (ReturnValue != 0) { - printf ("Error. Call GenSec failed.\n"); - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - -/** - Create the Ras type of FFS - - @param[in] InputFilePath .efi file, it's optional unless process PE/TE section. - @param[in] OutputFilePath .te or .pe file - - @retval EFI_SUCCESS - -**/ -EFI_STATUS -CreateRawFfs ( - IN CHAR8** InputFilePaths, - IN CHAR8* OutputFilePath, - IN BOOLEAN SizeOptimized - ) -{ - INT32 ReturnValue; - CHAR8* SystemCommandFormatString; - CHAR8* SystemCommand; - CHAR8* GuidStr; - CHAR8* FilePathFormatStr; - CHAR8* FilePathStr; - UINT32 Index; - UINT32 StrLen; - UINT32 Size; - - SystemCommand = NULL; - GuidStr = NULL; - FilePathStr = NULL; - StrLen = 0; - - FilePathFormatStr = " -i \""; - - for (Index = 0; InputFilePaths[Index] != NULL; Index++) { - Size = strlen (FilePathFormatStr) + strlen (InputFilePaths[Index]) + 2; // 2 menas "" " - if (FilePathStr == NULL) { - FilePathStr = malloc (Size); - if (NULL == FilePathStr) { - return EFI_OUT_OF_RESOURCES; - } - } else { - FilePathStr = realloc (FilePathStr, StrLen + Size); - if (NULL == FilePathStr) { - return EFI_OUT_OF_RESOURCES; - } - } - memset (FilePathStr + StrLen, ' ', Size); - memcpy (FilePathStr + StrLen, FilePathFormatStr, strlen(FilePathFormatStr)); - memcpy(FilePathStr + StrLen + strlen(FilePathFormatStr), InputFilePaths[Index], strlen(InputFilePaths[Index])); - StrLen += Size; - *(FilePathStr + StrLen - 2) = '\"'; - } - if (FilePathStr == NULL) { - return EFI_ABORTED; - } - *(FilePathStr + StrLen - 1)= '\0'; - - - if (SizeOptimized) { - GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid2); - } else { - GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid); - } - if (NULL == GuidStr) { - free (FilePathStr); - return EFI_OUT_OF_RESOURCES; - } - SystemCommandFormatString = "GenFfs -t %s %s -g %s -o \"%s\""; - SystemCommand = malloc ( - strlen (SystemCommandFormatString) + - strlen ("EFI_FV_FILETYPE_FREEFORM") + - strlen (FilePathStr) + - strlen (GuidStr) + - strlen (OutputFilePath) + - 1 - ); - if (NULL == SystemCommand) { - free (GuidStr); - free (FilePathStr); - return EFI_OUT_OF_RESOURCES; - } - sprintf ( - SystemCommand, - "GenFfs -t %s %s -g %s -o \"%s\"", - "EFI_FV_FILETYPE_FREEFORM",// -t - FilePathStr, // -i - GuidStr, // -g - OutputFilePath // -o - ); - ReturnValue = system (SystemCommand); - free(SystemCommand); - free (FilePathStr); - free (GuidStr); - - if (ReturnValue != 0) { - printf ("Error. Call GenFfs failed.\n"); - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - diff --git a/BaseTools/Source/C/FCE/BinaryCreate.h b/BaseTools/Source/C/FCE/BinaryCreate.h deleted file mode 100644 index 0e2f22599e..0000000000 --- a/BaseTools/Source/C/FCE/BinaryCreate.h +++ /dev/null @@ -1,157 +0,0 @@ -/** @file - - The API to create the binary. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _BINARY_CREATE_H_ -#define _BINARY_CREATE_H_ 1 - -#include -#include "Compress.h" -#include "Decompress.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "FirmwareVolumeBufferLib.h" -#include "OsPath.h" -#include "ParseGuidedSectionTools.h" -#include "StringFuncs.h" -#include "ParseInf.h" -#include -#include -#include -#include -#include -#include -#include -#include - -//1AE42876-008F-4161-B2B7-1C0D15C5EF43 -#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID \ - { 0x1ae42876, 0x008f, 0x4161, { 0xb2, 0xb7, 0x1c, 0xd, 0x15, 0xc5, 0xef, 0x43 }} - -extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid; - -// {003E7B41-98A2-4BE2-B27A-6C30C7655225} -#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2 \ - { 0x3e7b41, 0x98a2, 0x4be2, { 0xb2, 0x7a, 0x6c, 0x30, 0xc7, 0x65, 0x52, 0x25 }} - -extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid2; - -typedef UINT64 SKU_ID; - -typedef struct { - UINT32 Offset:24; - UINT32 Value:8; -} PCD_DATA_DELTA; - -typedef struct { - SKU_ID SkuId; - UINT16 DefaultId; - UINT8 Reserved[6]; -} PCD_DEFAULT_INFO; - -typedef struct { - // - // Full size, it must be at 8 byte alignment. - // - UINT32 DataSize; - // - // HeaderSize includes HeaderSize fields and DefaultInfo arrays - // - UINT32 HeaderSize; - // - // DefaultInfo arrays those have the same default setting. - // - PCD_DEFAULT_INFO DefaultInfo[1]; - // - // Default data is stored as variable storage or the array of DATA_DELTA. - // -} PCD_DEFAULT_DATA; - -#define PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE SIGNATURE_32('N', 'S', 'D', 'B') - -typedef struct { - // - // PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE - // - UINT32 Signature; - // - // Length of the taken default buffer - // - UINT32 Length; - // - // Length of the total reserved buffer - // - UINT32 MaxLength; - // - // Reserved for 8 byte alignment - // - UINT32 Reserved; - // one or more PCD_DEFAULT_DATA -} PCD_NV_STORE_DEFAULT_BUFFER_HEADER; - -// -// NvStoreDefaultValueBuffer layout: -// +-------------------------------------+ -// | PCD_NV_STORE_DEFAULT_BUFFER_HEADER | -// +-------------------------------------+ -// | PCD_DEFAULT_DATA (DEFAULT, Standard)| -// +-------------------------------------+ -// | PCD_DATA_DELTA (DEFAULT, Standard)| -// +-------------------------------------+ -// | ...... | -// +-------------------------------------+ -// | PCD_DEFAULT_DATA (SKU A, Standard) | -// +-------------------------------------+ -// | PCD_DATA_DELTA (SKU A, Standard) | -// +-------------------------------------+ -// | ...... | -// +-------------------------------------+ -// - -#pragma pack(1) - -typedef struct { - UINT16 Offset; - UINT8 Value; -} DATA_DELTA; - -#pragma pack() - -/** - Create the Ras section in FFS - - @param[in] InputFilePath The input file path and name. - @param[in] OutputFilePath The output file path and name. - - @retval EFI_SUCCESS - -**/ -EFI_STATUS -CreateRawSection ( - IN CHAR8* InputFilePath, - IN CHAR8* OutputFilePath - ); - -/** - Create the Ras type of FFS - - @param[in] InputFilePath .efi file, it's optional unless process PE/TE section. - @param[in] OutputFilePath .te or .pe file - - @retval EFI_SUCCESS - -**/ -EFI_STATUS -CreateRawFfs ( - IN CHAR8** InputFilePaths, - IN CHAR8* OutputFilePath, - IN BOOLEAN SizeOptimized - ); - -#endif - diff --git a/BaseTools/Source/C/FCE/BinaryParse.c b/BaseTools/Source/C/FCE/BinaryParse.c deleted file mode 100644 index e9f8ee6826..0000000000 --- a/BaseTools/Source/C/FCE/BinaryParse.c +++ /dev/null @@ -1,1326 +0,0 @@ -/** @file - - The API to parse the binary. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GNUC__ -#include "windows.h" -#else -#include -#include -#include -#endif -#include "BinaryParse.h" -#include "BinaryCreate.h" -#include "VariableCommon.h" -#include "FirmwareVolumeBufferLib.h" - -extern G_EFI_FD_INFO gEfiFdInfo; -extern EFI_HANDLE mParsedGuidedSectionTools; -extern CHAR8 mInputFdName[MAX_FILENAME_LEN]; - -// -// The Guid to sign the position of Vfr and Uni array in FV -// -EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID; -EFI_GUID gUniStrArrayAttractGuid = EFI_UNI_STR_ATTRACT_GUID; -EFI_GUID gEfiSystemNvDataFvGuid = EFI_SYSTEM_NVDATA_FV_GUID; -EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; - -/** - Converts a three byte length value into a UINT32. - - @param ThreeByteLength Pointer to the first of the 3 byte length. - - @retval Length Size of the section - -**/ -static -UINT32 -Get3ByteLength ( - IN UINT8 *ThreeByteLength - ) -{ - UINT32 Length; - - Length = 0; - - if (ThreeByteLength == NULL) { - return 0; - } - - Length = *((UINT32 *) ThreeByteLength); - Length = Length & 0x00FFFFFF; - - return Length; -} - -/** - Generate the unique template filename. -**/ -CHAR8 * -GenTempFile ( - VOID - ) -{ - CHAR8 *TemString; - TemString = NULL; -#ifndef __GNUC__ - TemString = CloneString (tmpnam (NULL)); -#else - CHAR8 tmp[] = "/tmp/fileXXXXXX"; - UINTN Fdtmp; - Fdtmp = mkstemp(tmp); - TemString = CloneString(tmp); - close(Fdtmp); -#endif - return TemString; -} - -/** - Check whether exist the same Ifr FFS. If not existed, return TRUE. - - @param[in] FfsImage The pointer to the binary. - @param[in] FileSize The size of binary. - - @return The string after convert. -**/ -static -BOOLEAN -NotExistSameFfsIfr ( - IN VOID *FfsImage -) -{ - UINT32 Index; - - Index = 0; - - while (gEfiFdInfo.FfsArray[Index] != NULL) { - if (memcmp (gEfiFdInfo.FfsArray[Index], FfsImage, sizeof (EFI_GUID)) == 0) { - return FALSE; - } - Index++; - } - return TRUE; -} - -/** - This function returns the next larger size that meets the alignment - requirement specified. - - @param ActualSize The size. - @param Alignment The desired alignment. - - @retval The Occupied length - -**/ -static -UINT32 -GetOccupiedSize ( - IN UINT32 ActualSize, - IN UINT32 Alignment - ) -{ - UINT32 OccupiedSize; - - OccupiedSize = ActualSize; - while ((OccupiedSize & (Alignment - 1)) != 0) { - OccupiedSize++; - } - - return OccupiedSize; -} - - -/** - Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS. - - @param SectionBuffer The section base address - @param BufferLength The length of FFS. - @param EfiBufferHeader The structure dual pointer to the efi informations - - @retval EFI_SUCCESS The application exited normally. - @retval EFI_ABORTED An error occurred. - -**/ -EFI_STATUS -ParseSection ( - IN BOOLEAN IsFfsOrEfi, - IN OUT UINT8 *SectionBuffer, - IN UINT32 BufferLength, - IN OUT EFI_SECTION_STRUCT **EfiBufferHeader - ) -{ - UINT32 ParsedLength; - EFI_SECTION_TYPE Type; - UINT8 *Ptr; - UINT32 SectionLength; - UINT8 *CompressedBuffer; - UINT32 CompressedLength; - UINT8 *UncompressedBuffer; - UINT32 UncompressedLength; - UINT8 CompressionType; - DECOMPRESS_FUNCTION DecompressFunction; - GETINFO_FUNCTION GetInfoFunction; - UINT32 ScratchSize; - UINT8 *ScratchBuffer; - EFI_STATUS Status; - UINT32 DstSize; - CHAR8 *ExtractionTool; - CHAR8 *ToolInputFile; - CHAR8 *ToolOutputFile; - CHAR8 *SystemCommandFormatString; - CHAR8 *SystemCommand; - UINT8 *ToolOutputBuffer; - UINT32 ToolOutputLength; - BOOLEAN HasDepexSection; - - Ptr = NULL; - SectionLength = 0; - CompressedBuffer = NULL; - CompressedLength = 0; - UncompressedBuffer = NULL; - UncompressedLength = 0; - CompressionType = 0; - ScratchSize = 0; - ScratchBuffer = NULL; - Status = EFI_SUCCESS; - DstSize = 0; - ExtractionTool = NULL; - ToolInputFile = NULL; - ToolOutputFile = NULL; - SystemCommandFormatString = NULL; - SystemCommand = NULL; - - // - // Jump the FFS header - // - if (IsFfsOrEfi) { - SectionBuffer = SectionBuffer + sizeof (EFI_FFS_FILE_HEADER); - BufferLength = BufferLength - sizeof (EFI_FFS_FILE_HEADER); - } - ParsedLength = 0; - HasDepexSection = FALSE; - ExtractionTool = NULL; - ToolOutputLength = 0; - ToolOutputBuffer = NULL; - - (*EfiBufferHeader)->Length = BufferLength; - - while (ParsedLength < BufferLength) { - Ptr = SectionBuffer + ParsedLength; - - SectionLength = Get3ByteLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size); - Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type; - - // - // This is sort of an odd check, but is necessary because FFS files are - // padded to a QWORD boundary, meaning there is potentially a whole section - // header worth of 0xFF bytes. - // - if ((SectionLength == 0xffffff) && (Type == 0xff)) { - ParsedLength += 4; - continue; - } - - switch (Type) { - - case EFI_SECTION_PE32: - case EFI_SECTION_TE: - // - //Got the correct address - // - (*EfiBufferHeader)->BufferBase = (UINTN)(Ptr + sizeof (EFI_COMMON_SECTION_HEADER)); - return EFI_SUCCESS; - - case EFI_SECTION_RAW: - case EFI_SECTION_PIC: - break; - - case EFI_SECTION_USER_INTERFACE: - HasDepexSection = FALSE; - break; - - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: - case EFI_SECTION_COMPATIBILITY16: - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: - break; - - case EFI_SECTION_PEI_DEPEX: - case EFI_SECTION_DXE_DEPEX: - case EFI_SECTION_SMM_DEPEX: - HasDepexSection = TRUE; - break; - - case EFI_SECTION_VERSION: - break; - case EFI_SECTION_COMPRESSION: - UncompressedBuffer = NULL; - CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION); - UncompressedLength = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength; - CompressionType = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType; - - if (CompressionType == EFI_NOT_COMPRESSED) { - if (CompressedLength != UncompressedLength) { - Error ( - NULL, - 0, - 0, - "file is not compressed, but the compressed length does not match the uncompressed length", - NULL - ); - return EFI_ABORTED; - } - - UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); - } else if (CompressionType == EFI_STANDARD_COMPRESSION) { - GetInfoFunction = EfiGetInfo; - DecompressFunction = EfiDecompress; - CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION); - - Status = GetInfoFunction ( - CompressedBuffer, - CompressedLength, - &DstSize, - &ScratchSize - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "error getting compression info from compression section", NULL); - return EFI_ABORTED; - } - - if (DstSize != UncompressedLength) { - Error (NULL, 0, 0003, "compression error in the compression section", NULL); - return EFI_ABORTED; - } - - ScratchBuffer = malloc (ScratchSize); - if (ScratchBuffer == NULL) { - return EFI_ABORTED; - } - UncompressedBuffer = malloc (UncompressedLength); - if (UncompressedBuffer == NULL) { - free (ScratchBuffer); - return EFI_ABORTED; - } - memset (UncompressedBuffer, 0, UncompressedLength); - - Status = DecompressFunction ( - CompressedBuffer, - CompressedLength, - UncompressedBuffer, - UncompressedLength, - ScratchBuffer, - ScratchSize - ); - free (ScratchBuffer); - if (Status != EFI_SUCCESS) { - Error (NULL, 0, 0003, "decompress failed", NULL); - free (UncompressedBuffer); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType); - return EFI_ABORTED; - } - - Status = ParseSection (FALSE, UncompressedBuffer, UncompressedLength, EfiBufferHeader); - if (Status != EFI_SUCCESS) { - Error (NULL, 0, 0003, "failed to parse section", NULL); - free (UncompressedBuffer); - UncompressedBuffer = NULL; - } else { - return EFI_SUCCESS; - } - // - // Store the allocate memory address for UncompressedBuffer - // - if (UncompressedBuffer != NULL) { - (*EfiBufferHeader)->UncompressedBuffer[(*EfiBufferHeader)->UnCompressIndex] = (UINTN) UncompressedBuffer; - (*EfiBufferHeader)->UnCompressIndex = (*EfiBufferHeader)->UnCompressIndex + 1; - } - break; - - case EFI_SECTION_GUID_DEFINED: - // - // Decompress failed, and then check for CRC32 sections which we can handle internally if needed. - // Maybe this section is no-compressed. - // - if (!CompareGuid ( - &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid, - &gEfiCrc32GuidedSectionExtractionProtocolGuid - )) { - // - // CRC32 guided section - // - Status = ParseSection ( - FALSE, - SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, - BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, - EfiBufferHeader - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL); - return EFI_ABORTED; - } else { - return EFI_SUCCESS; - } - } else { - ExtractionTool = LookupGuidedSectionToolPath ( - mParsedGuidedSectionTools, - &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid - ); - - if (ExtractionTool != NULL) { - ToolInputFile = GenTempFile (); - ToolOutputFile = GenTempFile (); - // - // Construction 'system' command string - // - SystemCommandFormatString = "%s -d -o \"%s\" \"%s\""; - SystemCommand = malloc ( - strlen (SystemCommandFormatString) \ - + strlen (ExtractionTool) \ - + strlen (ToolInputFile) \ - + strlen (ToolOutputFile) \ - + 1 - ); - if (SystemCommand == NULL) { - free (ExtractionTool); - free (ToolInputFile); - free (ToolOutputFile); - return EFI_ABORTED; - } - sprintf ( - SystemCommand, - "%s -d -o \"%s\" \"%s\"", - ExtractionTool, - ToolOutputFile, - ToolInputFile - ); - free (ExtractionTool); - - Status = PutFileImage ( - ToolInputFile, - (CHAR8*) Ptr + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset, - SectionLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset - ); - - if (HasDepexSection) { - HasDepexSection = FALSE; - } - - system (SystemCommand); - remove (ToolInputFile); - free (ToolInputFile); - ToolInputFile = NULL; - free (SystemCommand); - SystemCommand = NULL; - - if (EFI_ERROR (Status)) { - Error ("FCE", 0, 0004, "unable to decoded GUIDED section", NULL); - free (ToolOutputFile); - return EFI_ABORTED; - } - - Status = GetFileImage ( - ToolOutputFile, - (CHAR8 **)&ToolOutputBuffer, - &ToolOutputLength - ); - remove (ToolOutputFile); - free (ToolOutputFile); - ToolOutputFile = NULL; - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } - Status = ParseSection ( - FALSE, - ToolOutputBuffer, - ToolOutputLength, - EfiBufferHeader - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); - return EFI_ABORTED; - } - } - break; - - default: - ; - } - ParsedLength += SectionLength; - // - // We make then next section begin on a 4-byte boundary - // - ParsedLength = GetOccupiedSize (ParsedLength, 4); - } - - return EFI_ABORTED; -} - -static -BOOLEAN -GetNextOffset ( - IN UINT8 *Data, - IN EFI_GUID *Guid, - IN UINTN Len, - IN OUT UINTN *Offset - ) -{ - UINTN NextOffset; - if (*Offset >= Len || Len - *Offset <= sizeof (EFI_GUID)) { - return FALSE; - } - - for (NextOffset = *Offset; NextOffset < Len - sizeof (EFI_GUID); NextOffset++) { - if (CompareGuid(Guid, (EFI_GUID*)(Data + NextOffset)) == 0) { - *Offset = NextOffset + sizeof(EFI_GUID); - return TRUE; - } - } - return FALSE; -} - -/** - Get the address by Guid. - - Parse the FFS image, and find the GUID address.There may be some Guids matching the - searched Guid. - - @param Fv the Pointer to the image. - @param Guid The Guid need to find. - @param Offset The dual Pointer to the offset. - @param NumOfMatchGuid The number of matching Guid offset. - - @retval EFI_SUCCESS The Search was complete successfully - @return EFI_ABORTED An error occurred -**/ -EFI_STATUS -GetAddressByGuid ( - IN VOID *Fv, - IN EFI_GUID *Guid, - IN UINTN Len, - OUT UINTN **Offset, - OUT UINT8 *NumOfMatchGuid - ) -{ - VOID *LocalFv; - UINT8 Flag; - - EFI_RAW_SECTION* Section; - UINT8 *RawData; - VOID* SectionStart; - UINTN NextOffset; - UINTN Key; - UINTN TotalSectionsSize; - UINTN SecLen; - UINTN SecHdr; - EFI_STATUS Status; - - if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) || Len == 0 ){ - return EFI_ABORTED; - } - - LocalFv = Fv; - Flag = 0; - Section = NULL; - Key = 0; - - if (NumOfMatchGuid != NULL) { - *NumOfMatchGuid = 0; - } - - SectionStart = (VOID*)((UINTN)LocalFv + FvBufGetFfsHeaderSize(LocalFv)); - TotalSectionsSize = Len - FvBufGetFfsHeaderSize(LocalFv); - while (TRUE) { - Status = FvBufFindNextSection ( - SectionStart, - TotalSectionsSize, - &Key, - (VOID **)&Section - ); - if (Section == NULL || EFI_ERROR (Status)) { - break; - } - - if (EFI_SECTION_RAW == Section->Type) { - if ((*(UINT32 *)Section->Size & 0xffffff) == 0xffffff) { - SecLen = ((EFI_RAW_SECTION2 *)Section)->ExtendedSize; - SecHdr = sizeof(EFI_RAW_SECTION2); - } else { - SecLen = *(UINT32 *)Section->Size & 0xffffff; - SecHdr = sizeof(EFI_RAW_SECTION); - } - if (SecLen <= SecHdr || SecLen - SecHdr < sizeof(EFI_GUID)) { - continue; - } - RawData = (UINT8 *)Section + SecHdr; - NextOffset = 0; - while (GetNextOffset(RawData, Guid, SecLen - SecHdr, &NextOffset)) { - Flag = 1; - if ((NumOfMatchGuid != NULL) && (Offset != NULL)) { - if (*NumOfMatchGuid == 0) { - *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM); - if (*Offset == NULL) { - return EFI_ABORTED; - } - memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM); - } - *(*Offset + *NumOfMatchGuid) = NextOffset + (RawData - (UINT8 *)Fv); - (*NumOfMatchGuid)++; - } else { - return EFI_SUCCESS; - } - } - } - } - - if( Flag == 0 ) { - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - -/** - Search the VfrBin Base address. - - According the known GUID gVfrArrayAttractGuid to get the base address from FFS. - - @param Fv the Pointer to the FFS - @param EfiAddr the Pointer to the EFI in FFS - @param Length the length of Fv - @param Offset the Pointer to the Addr (Offset) - @param NumOfMachingOffset the number of Addr (Offset) - - @retval EFI_SUCCESS Get the address successfully. -**/ -EFI_STATUS -SearchVfrBinInFFS ( - IN VOID *Fv, - IN VOID *EfiAddr, - IN UINTN Length, - OUT UINTN **Offset, - OUT UINT8 *NumOfMachingOffset - ) -{ - UINTN Index; - EFI_STATUS Status; - UINTN VirOffValue; - - Index = 0; - Status = EFI_SUCCESS; - VirOffValue = 0; - - if ((Fv == NULL) || (Offset == NULL)) { - return EFI_ABORTED; - } - Status = GetAddressByGuid ( - Fv, - &gVfrArrayAttractGuid, - Length, - Offset, - NumOfMachingOffset - ); - if (Status != EFI_SUCCESS) { - return EFI_ABORTED; - } - - while (Index < *NumOfMachingOffset) { - // - // Got the virOffset after the GUID - // - VirOffValue = *(UINTN *)((UINTN)Fv + *(*Offset + Index)); - // - //Transfer the offset to the VA address. One modules may own more VfrBin address. - // - *(*Offset + Index) = (UINTN) EfiAddr + VirOffValue; - Index++; - } - return EFI_SUCCESS; -} - -/** - Search the UniBin Base address. - - According the known GUID gUniStrArrayAttractGuid to get the base address from FFS. - - @param Fv the Pointer to the FFS - @param EfiAddr the Pointer to the EFI in FFS - @param Length the length of Fv - @param Offset the Pointer to the Addr (Offset) - - @retval Base address Get the address successfully. -**/ -EFI_STATUS -SearchUniBinInFFS ( - IN VOID *Fv, - IN VOID *EfiAddr, - IN UINTN Length, - OUT UINTN **Offset - ) -{ - UINT8 NumOfMachingOffset; - EFI_STATUS Status; - UINTN VirOffValue; - - NumOfMachingOffset = 0; - Status = EFI_SUCCESS; - VirOffValue = 0; - - if ((Fv == NULL) || (Offset == NULL)) { - return EFI_ABORTED; - } - Status = GetAddressByGuid ( - Fv, - &gUniStrArrayAttractGuid, - Length, - Offset, - &NumOfMachingOffset - ); - if (Status != EFI_SUCCESS) { - return EFI_ABORTED; - } - // - //Transfer the offset to the VA address. There is only one UniArray in one modules. - // - if (NumOfMachingOffset == 1) { - VirOffValue = *(UINTN *)((UINTN)Fv + **Offset); - **Offset = (UINTN) EfiAddr + VirOffValue; - } else { - printf ("Error. Find more than 1 UniBin in FFS.\n"); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SearchNvStoreDatabaseInFd( - IN VOID *Fv, - IN UINTN length - ) -{ - EFI_STATUS Status; - UINTN Offset; - PCD_NV_STORE_DEFAULT_BUFFER_HEADER *NvStoreHeader; - Status = EFI_SUCCESS; - Offset = 0; - if (Fv == NULL) { - printf ("The FV is NULL."); - return EFI_ABORTED; - } - while (Offset < (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER))){ - NvStoreHeader = (PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)((UINT8*)Fv + Offset); - if (NvStoreHeader->Signature == PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE) { - gEfiFdInfo.ExistNvStoreDatabase = TRUE; - gEfiFdInfo.NvStoreDatabase = (UINT8 *) NvStoreHeader; - break; - } - Offset++; - } - if (Offset == (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) || gEfiFdInfo.ExistNvStoreDatabase != TRUE) { - //printf ("Not found the PcdNvStoreDefaultValueBuffer\n"); - return Status; - } - return Status; -} - -/** - Get the address by Guid. - - Parse the FD image, and find the GUID address.There may be some Guids matching the - searched Guid. - - @param Fv the Pointer to the image. - @param Guid The Guid need to find. - @param Offset The dual Pointer to the offset. - @param NumOfMatchGuid The number of matching Guid offset. - - @retval EFI_SUCCESS The Search was complete successfully - @return EFI_ABORTED An error occurred -**/ -EFI_STATUS -GetVariableAddressByGuid ( - IN VOID *Fv, - IN EFI_GUID *Guid, - IN UINTN Len, - OUT UINTN **Offset, - OUT UINT8 *NumOfMatchGuid - ) -{ - UINTN NextOffset; - UINT8 Flag; - - if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) ){ - return EFI_ABORTED; - } - - Flag = 0; - NextOffset = 0; - - if (NumOfMatchGuid != NULL) { - *NumOfMatchGuid = 0; - } - while (GetNextOffset(Fv, Guid, Len, &NextOffset)) { - Flag = 1; - if (NumOfMatchGuid != NULL && Offset != NULL) { - if (*NumOfMatchGuid == 0) { - *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM); - if (*Offset == NULL) { - return EFI_ABORTED; - } - memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM); - } - *(*Offset + *NumOfMatchGuid) = NextOffset; - (*NumOfMatchGuid)++; - } else { - return EFI_SUCCESS; - } - } - - if( Flag == 0 ) { - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - -/** - Search the EFI Variable Base address. - - According the known GUID gEfiSystemNvDataFvGuid to get the base address from FFS. - - @param Fv the Pointer to the FFS - @param Length the length of Fv - @param Offset the Pointer to the Addr (Offset) - @param NumOfMachingOffset the number of IFR array in one FFS - - @retval EFI_SUCCESS Get the address successfully. - @retval EFI_ABORTED An error occured. -**/ -EFI_STATUS -SearchEfiVarInFFS ( - IN VOID *Fv, - IN UINTN Length, - OUT UINTN **Offset, - OUT UINT8 *NumOfMachingOffset - ) -{ - EFI_STATUS Status; - UINT8 Index; - - Status = EFI_SUCCESS; - Index = 0; - - if ((Fv == NULL) || (Offset == NULL)) { - printf ("The FV or offset is NULL."); - return EFI_ABORTED; - } - Status = GetVariableAddressByGuid ( - Fv, - &gEfiSystemNvDataFvGuid, - Length, - Offset, - NumOfMachingOffset - ); - if (Status != EFI_SUCCESS) { - return EFI_ABORTED; - } - // - //Transfer the offset to the VA address. - // - while (Index < *NumOfMachingOffset) { - *(*Offset + Index) = (UINTN) Fv + *(*Offset + Index); - Index++; - } - return EFI_SUCCESS; -} - -/** - Parse the Ffs header to get the size. - - @param InputFile The pointer to the input file - @param FvSize The pointer to the file size - - @return EFI_SUCCESS Get the file size successfully -**/ -EFI_STATUS -ReadFfsHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize - ) -{ - EFI_FFS_FILE_HEADER FfsHeader; - EFI_FV_FILETYPE Type; - - // - // Check input parameters - // - if ((InputFile == NULL) || (FvSize == NULL)) { - return EFI_ABORTED; - } - // - // Read the header - // - fread ( - &FfsHeader, - sizeof (EFI_FFS_FILE_HEADER), - 1, - InputFile - ); - Type = FfsHeader.Type; - - if (Type == EFI_FV_FILETYPE_DRIVER) { - *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff; - } else if (Type == EFI_FV_FILETYPE_APPLICATION) { - *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff; - } else if (Type == EFI_FV_FILETYPE_FREEFORM) { - *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff; - } else { - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - -/* - Read the length of the whole FD - - This function determines the size of the FV. - - @param InputFile The file that contains the FV image. - @param FvSize The size of the FV. - - @retval EFI_SUCCESS The application exited normally. - @retval EFI_ABORTED An error occurred. - -**/ -static -EFI_STATUS -ReadFdHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize - ) -{ - // - // Check input parameters - // - if ((InputFile == NULL) || (FvSize == NULL)) { - return EFI_ABORTED; - } - *FvSize = 0; - // - // Get the total size of FD file (Fixed the length) - // - fseek(InputFile,0,SEEK_END); - *FvSize = ftell(InputFile); - fseek(InputFile,0,SEEK_SET); - - if (*FvSize == 0) { - return EFI_ABORTED; - } - return EFI_SUCCESS; -} - -/** - Read the file to memory. - - @param InputFile The file that contains the FV image. - @param Size The size of the file. - - @retval The pointer to the begining position of memory. -**/ -VOID * -ReadFileToMemory ( - IN CHAR8 *FileName, - OUT UINT32 *Size - ) -{ - FILE *InFile; - VOID *Address; - UINT32 BytesRead; - EFI_STATUS Status; - - InFile = NULL; - Address = NULL; - BytesRead = 0; - Status = EFI_SUCCESS; - - InFile = fopen (FileName,"rb"); - if (InFile == NULL) { - return NULL; - } - // - // Determine the size of FV - // - Status = ReadFdHeader (InFile, Size); - if (Status != EFI_SUCCESS) { - fclose (InFile); - return NULL; - } - // - // Allocate a buffer for the FV image - // - Address = malloc (*Size); - if (Address == NULL) { - fclose (InFile); - return NULL; - } - memset (Address, 0, *Size); - // - // Seek to the start of the image, then read the entire FV to the buffer - // - fseek (InFile, 0, SEEK_SET); - BytesRead = fread (Address, 1, *Size, InFile); - fclose (InFile); - if ((UINTN) BytesRead != *Size) { - free (Address); - return NULL; - } - return Address; -} - -/** - Search the EFI variables address in Fd. - - Open and read the *.fd to the memory, initialize the global structure. - Update the EFI variables addr and the begining position of memory. - - @retval EFI_SUCCESS Get the address successfully. -**/ -EFI_STATUS -GetEfiVariablesAddr ( - BOOLEAN UqiIsSet - ) -{ - VOID *FdImage; - UINT32 FdSize; - EFI_STATUS Status; - UINTN *EfiVarAddr; - UINT8 NumOfMachingVar; - UINT32 Index; - BOOLEAN GotFlag; - EFI_FIRMWARE_VOLUME_HEADER *Variable; - BOOLEAN AuthencitatedMonotonicOrNot; - BOOLEAN AuthencitatedBasedTimeOrNot; - BOOLEAN NormalOrNot; - - FdImage = NULL; - FdSize = 0; - Status = EFI_SUCCESS; - EfiVarAddr = NULL; - NumOfMachingVar = 0; - Index = 0; - GotFlag = TRUE; - Variable = NULL; - - FdImage = ReadFileToMemory (mInputFdName, &FdSize); - if (FdImage == NULL) { - return EFI_ABORTED; - } - if (!UqiIsSet) { - Status = SearchNvStoreDatabaseInFd(FdImage, FdSize); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } - Status = SearchEfiVarInFFS ( - FdImage, - FdSize, - &EfiVarAddr, - &NumOfMachingVar - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Check the signature "_FVH" - // - Index = 0; - GotFlag = FALSE; - - while (Index < NumOfMachingVar) { - Variable = (EFI_FIRMWARE_VOLUME_HEADER *)(*(EfiVarAddr + Index) - 0x20); - if (Variable->Signature == 0x4856465F) { - AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore ((UINT8 *)Variable + Variable->HeaderLength); - AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength); - NormalOrNot = CheckNormalVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength); - if (AuthencitatedMonotonicOrNot || AuthencitatedBasedTimeOrNot || NormalOrNot) { - GotFlag = TRUE; - gEfiFdInfo.EfiVariableAddr = (UINTN)Variable; - break; - } - } - Index++; - } - free (EfiVarAddr); - if (!GotFlag) { - return EFI_ABORTED; - } - gEfiFdInfo.Fd = FdImage; - gEfiFdInfo.FdSize = FdSize; - - return EFI_SUCCESS; -} - -/** - Pick up the FFS which includes IFR section. - - Parse all FFS extracted by BfmLib, and save all which includes IFR - Binary to gEfiFdInfo structure. - - @retval EFI_SUCCESS Get the address successfully. - @retval EFI_BUFFER_TOO_SMALL Memory can't be allocated. - @retval EFI_ABORTED Read FFS Failed. -**/ -EFI_STATUS -FindFileInFolder ( - IN CHAR8 *FolderName, - OUT BOOLEAN *ExistStorageInBfv, - OUT BOOLEAN *SizeOptimized -) -{ - CHAR8 *FileName; - CHAR8 *CurFolderName; - EFI_STATUS Status; - UINTN MaxFileNameLen; - UINTN Index; - CHAR8 FileNameArry[MAX_FILENAME_LEN]; - FILE *FfsFile; - UINTN FileSize; - VOID *FfsImage; - UINTN BytesRead; -#ifndef __GNUC__ - HANDLE FindHandle; - WIN32_FIND_DATA FindFileData; -#else - struct dirent *pDirent; - DIR *pDir; -#endif - - FileName = NULL; - CurFolderName = NULL; - Status = EFI_SUCCESS; - MaxFileNameLen = 0; - Index = 0; - FileSize = 0; - BytesRead = 0; - FfsImage = NULL; - FfsFile = NULL; - - MaxFileNameLen = strlen (FolderName) + MAX_FILENAME_LEN; - CurFolderName = (CHAR8 *)calloc( - strlen (FolderName) + strlen (OS_SEP_STR) + strlen ("*.*")+ 1, - sizeof(CHAR8) - ); - if (CurFolderName == NULL) { - return EFI_BUFFER_TOO_SMALL; - } - strcpy (CurFolderName, FolderName); - strcat (CurFolderName, OS_SEP_STR); - strcat (CurFolderName, "*.*"); - FileName = (CHAR8 *)calloc( - MaxFileNameLen, - sizeof(CHAR8) - ); - if (FileName == NULL) { - free (CurFolderName); - return EFI_BUFFER_TOO_SMALL; - } - -#ifndef __GNUC__ - if((FindHandle = FindFirstFile(CurFolderName, &FindFileData)) != INVALID_HANDLE_VALUE){ - do { - memset (FileName, 0, MaxFileNameLen); - if ((strcmp (FindFileData.cFileName, ".") == 0) - || (strcmp (FindFileData.cFileName, "..") == 0) - ) { - continue; - } - if (strlen(FolderName) + strlen ("\\") + strlen (FindFileData.cFileName) > MAX_FILENAME_LEN - 1) { - Status = EFI_ABORTED; - goto Done; - } - snprintf (FileNameArry, MAX_FILENAME_LEN, "%s%c%s", FolderName, OS_SEP, FindFileData.cFileName); - FfsFile = fopen (FileNameArry, "rb"); - if (FfsFile == NULL) { - Status = EFI_ABORTED; - goto Done; - } - Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize); - if (EFI_ERROR (Status)) { - fclose (FfsFile); - Status = EFI_SUCCESS; - continue; - } - // - // Allocate a buffer for the FFS file - // - FfsImage = malloc (FileSize); - if (FfsImage == NULL) { - fclose (FfsFile); - Status = EFI_BUFFER_TOO_SMALL; - goto Done; - } - // - // Seek to the start of the image, then read the entire FV to the buffer - // - fseek (FfsFile, 0, SEEK_SET); - BytesRead = fread (FfsImage, 1, FileSize, FfsFile); - fclose (FfsFile); - - if ((UINTN) BytesRead != FileSize) { - free (FfsImage); - Status = EFI_ABORTED; - goto Done; - } - // - // Check whether exists the storage ffs in BFV for multi-platform mode - // - if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) { - *ExistStorageInBfv = TRUE; - *SizeOptimized = FALSE; - gEfiFdInfo.StorageFfsInBfv = FfsImage; - continue; - } - // - // Check whether exists the optimized storage ffs in BFV for multi-platform mode - // - if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) { - *ExistStorageInBfv = TRUE; - *SizeOptimized = TRUE; - gEfiFdInfo.StorageFfsInBfv = FfsImage; - continue; - } - // - // Check whether current FFS includes IFR - // - Status = GetAddressByGuid ( - FfsImage, - &gVfrArrayAttractGuid, - FileSize, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - free (FfsImage); - Status = EFI_SUCCESS; - } else { - // - // Check whether existed same IFR binary. If existed, not insert the new one. - // - if (NotExistSameFfsIfr (FfsImage)) { - gEfiFdInfo.FfsArray[Index] = FfsImage; - gEfiFdInfo.Length[Index++] = FileSize; - } - } - - } while (FindNextFile (FindHandle, &FindFileData)); - FindClose(FindHandle); - } else { - Status = EFI_ABORTED; - goto Done; - } - -Done: - free (CurFolderName); - free (FileName); - -#else - if((pDir = opendir(FolderName)) != NULL){ - while ((pDirent = readdir(pDir)) != NULL){ - memset (FileName, 0, MaxFileNameLen); - if ((strcmp (pDirent->d_name, ".") == 0) - || (strcmp (pDirent->d_name, "..") == 0) - ) { - continue; - } - sprintf (FileNameArry, "%s%c%s", FolderName, OS_SEP, pDirent->d_name); - FfsFile = fopen (FileNameArry, "rb"); - Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize); - if (EFI_ERROR (Status)) { - fclose (FfsFile); - Status = EFI_SUCCESS; - continue; - } - // - // Allocate a buffer for the FFS file - // - FfsImage = malloc (FileSize); - if (FfsImage == NULL) { - fclose (FfsFile); - Status = EFI_BUFFER_TOO_SMALL; - goto Done; - } - // - // Seek to the start of the image, then read the entire FV to the buffer - // - fseek (FfsFile, 0, SEEK_SET); - BytesRead = fread (FfsImage, 1, FileSize, FfsFile); - fclose (FfsFile); - - if ((UINTN) BytesRead != FileSize) { - free (FfsImage); - Status = EFI_ABORTED; - goto Done; - } - // - // Check whether exists the storage ffs in BFV for multi-platform mode - // - if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) { - *ExistStorageInBfv = TRUE; - *SizeOptimized = FALSE; - gEfiFdInfo.StorageFfsInBfv = FfsImage; - continue; - } - // - // Check whether exists the optimized storage ffs in BFV for multi-platform mode - // - if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) { - *ExistStorageInBfv = TRUE; - *SizeOptimized = TRUE; - gEfiFdInfo.StorageFfsInBfv = FfsImage; - continue; - } - // - // Check whether current FFS includes IFR - // - Status = GetAddressByGuid ( - FfsImage, - &gVfrArrayAttractGuid, - FileSize, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - free (FfsImage); - Status = EFI_SUCCESS; - } else { - // - // Check whether existed same IFR binary. If existed, not insert the new one. - // - if (NotExistSameFfsIfr (FfsImage)) { - gEfiFdInfo.FfsArray[Index] = FfsImage; - gEfiFdInfo.Length[Index++] = FileSize; - } - } - - } - closedir(pDir); - } else { - Status = EFI_ABORTED; - goto Done; - } - -Done: - free (CurFolderName); - free (FileName); -#endif - return Status; -} - diff --git a/BaseTools/Source/C/FCE/BinaryParse.h b/BaseTools/Source/C/FCE/BinaryParse.h deleted file mode 100644 index a3995b8b79..0000000000 --- a/BaseTools/Source/C/FCE/BinaryParse.h +++ /dev/null @@ -1,187 +0,0 @@ -/** @file - - The API to parse the binary. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#ifndef _BINARY_PARSE_H_ -#define _BINARY_PARSE_H_ 1 - -#include -#include "Compress.h" -#include "Decompress.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "FirmwareVolumeBufferLib.h" -#include "OsPath.h" -#include "ParseGuidedSectionTools.h" -#include "StringFuncs.h" -#include "ParseInf.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -#define OS_SEP '/' -#define OS_SEP_STR "/" -#else -#define OS_SEP '\\' -#define OS_SEP_STR "\\" -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define snprintf _snprintf -#endif - -#define TEMP_DIR_NAME "Temp" -#define MAX_FILENAME_LEN 200 -#define MAX_MATCH_GUID_NUM 100 -#define MAX_EFI_IN_FFS_NUM 100 - -typedef struct { - VOID *Fd; - UINT32 FdSize; - UINTN EfiVariableAddr; - UINTN Length[MAX_EFI_IN_FFS_NUM]; - VOID *FfsArray[MAX_EFI_IN_FFS_NUM]; - VOID *StorageFfsInBfv; - VOID *NvStoreDatabase; - BOOLEAN ExistNvStoreDatabase; -} G_EFI_FD_INFO; - -/// -///Define the structure for th sections -/// -typedef struct { - UINTN BufferBase; - UINTN UncompressedBuffer[MAX_EFI_IN_FFS_NUM]; - UINTN Length; - UINT8 UnCompressIndex; -} EFI_SECTION_STRUCT; - -// {d0bc7cb4-6a47-495f-aa11-710746da06a2} -#define EFI_VFR_ATTRACT_GUID \ -{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } } - -// {8913C5E0-33F6-4d86-9BF1-43EF89FC0666} -#define EFI_UNI_STR_ATTRACT_GUID \ -{ 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } - -// {FFF12B8D-7696-4C8B-A985-2747075B4F50} -#define EFI_SYSTEM_NVDATA_FV_GUID \ -{ 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} - -/** - Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS. - - @param SectionBuffer The section base address - @param BufferLength The length of FFS. - @param EfiBufferHeader The structure dual pointer to the efi informations - - @retval EFI_SUCCESS The application exited normally. - @retval EFI_ABORTED An error occurred. - -**/ -EFI_STATUS -ParseSection ( - IN BOOLEAN IsFfsOrEfi, - IN OUT UINT8 *SectionBuffer, - IN UINT32 BufferLength, - IN OUT EFI_SECTION_STRUCT **EfiBufferHeader - ); - -/** - Search the VfrBin Base address. - - According the known GUID gVfrArrayAttractGuid to get the base address from FFS. - - @param Fv the Pointer to the FFS - @param EfiAddr the Pointer to the EFI in FFS - @param Length the length of Fv - @param Offset the Pointer to the Addr (Offset) - @param NumOfMachingOffset the number of Addr (Offset) - - @retval EFI_SUCCESS Get the address successfully. -**/ -EFI_STATUS -SearchVfrBinInFFS ( - IN VOID *Fv, - IN VOID *EfiAddr, - IN UINTN Length, - OUT UINTN **Offset, - OUT UINT8 *NumOfMachingOffset - ); - -/** - Search the UniBin Base address. - - According the known GUID gUniStrArrayAttractGuid to get the base address from FFS. - - @param Fv the Pointer to the FFS - @param EfiAddr the Pointer to the EFI in FFS - @param Length the length of Fv - @param Offset the Pointer to the Addr (Offset) - - @retval Base address Get the address successfully. -**/ -EFI_STATUS -SearchUniBinInFFS ( - IN VOID *Fv, - IN VOID *EfiAddr, - IN UINTN Length, - OUT UINTN **Offset - ); - -/** - Read the file to memory. - - @param InputFile The file that contains the FV image. - @param Size The size of the file. - - @retval The pointer to the begining position of memory. -**/ -VOID * -ReadFileToMemory ( - IN CHAR8 *FileName, - OUT UINT32 *Size - ); - -/** - Search the EFI variables address in Fd. - - Open and read the *.fd to the memory, initialize the global structure. - Update the EFI variables addr and the begining position of memory. - - @retval EFI_SUCCESS Get the address successfully. -**/ -EFI_STATUS -GetEfiVariablesAddr ( - BOOLEAN UqiIsSet - ); - -/** - Pick up the FFS which includes IFR section. - - Parse all FFS extracted by BfmLib, and save all which includes IFR - Binary to gEfiFdInfo structure. - - @retval EFI_SUCCESS Get the address successfully. - @retval EFI_BUFFER_TOO_SMALL Memory can't be allocated. - @retval EFI_ABORTED Read FFS Failed. -**/ -EFI_STATUS -FindFileInFolder ( - IN CHAR8 *FolderName, - OUT BOOLEAN *ExistStorageInBfv, - OUT BOOLEAN *SizeOptimized -); - -#endif - diff --git a/BaseTools/Source/C/FCE/Common.c b/BaseTools/Source/C/FCE/Common.c deleted file mode 100644 index 9b14a24a9b..0000000000 --- a/BaseTools/Source/C/FCE/Common.c +++ /dev/null @@ -1,2183 +0,0 @@ -/** @file - - Common library. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include "Common.h" - -#define WARNING_STATUS_NUMBER 4 -#define ERROR_STATUS_NUMBER 24 - -CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - -CONST CHAR8 *mStatusString[] = { - "Success", // RETURN_SUCCESS = 0 - "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1 - "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2 - "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3 - "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4 - "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT - "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT - "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT - "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT - "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT - "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT - "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT - "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT - "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT - "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT - "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT - "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT - "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT - "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT - "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT - "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT - "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT - "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT - "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT - "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT - "Aborted", // RETURN_ABORTED = 21 | MAX_BIT - "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT - "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT - "Protocol Error" // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT -}; - -/** - Copies one Null-terminated Unicode string to another Null-terminated Unicode - string and returns the new Unicode string. - - This function copies the contents of the Unicode string Source to the Unicode - string Destination, and returns Destination. If Source and Destination - overlap, then the results are undefined. - - If Destination is NULL, then return NULL. - If Destination is not aligned on a 16-bit boundary, then return NULL. - - @param Destination A pointer to a Null-terminated Unicode string. - @param Source A pointer to a Null-terminated Unicode string. - - @return Destination. - -**/ -CHAR16 * -StrCpy ( - OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ) -{ - CHAR16 *ReturnValue; - - ReturnValue = NULL; - - if ((Destination == NULL) || ((UINTN) Destination % 2 != 0)) { - return NULL; - } - - ReturnValue = Destination; - while (*Source != 0) { - *(Destination++) = *(Source++); - } - *Destination = 0; - return ReturnValue; -} - -/** - Returns the length of a Null-terminated Unicode string. - - This function returns the number of Unicode characters in the Null-terminated - Unicode string specified by String. - - If String is NULL, then return 0. - - @param String A pointer to a Null-terminated Unicode string. - - @return The length of String. - -**/ -UINTN -FceStrLen ( - IN CONST CHAR16 *String - ) -{ - UINTN Length; - - if (String == NULL) { - return 0; - } - for (Length = 0; *String != L'\0'; String++, Length++) { - ; - } - return Length; -} - -/** - Returns the size of a Null-terminated Unicode string in bytes, including the - Null terminator. - - This function returns the size, in bytes, of the Null-terminated Unicode string - specified by String. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @return The size of String. - -**/ -UINTN -FceStrSize ( - IN CONST CHAR16 *String - ) -{ - return (FceStrLen (String) + 1) * sizeof (*String); -} - -/** - Compares two Null-terminated Unicode strings, and returns the difference - between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString. If FirstString is identical to - SecondString, then 0 is returned. Otherwise, the value returned is the first - mismatched Unicode character in SecondString subtracted from the first - mismatched Unicode character in FirstString. - - @param FirstString A pointer to a Null-terminated Unicode string. - @param SecondString A pointer to a Null-terminated Unicode string. - - @retval 0 FirstString is identical to SecondString. - @return others FirstString is not identical to SecondString. - -**/ -INTN -FceStrCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString - ) -{ - while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { - FirstString++; - SecondString++; - } - return *FirstString - *SecondString; -} - -/** - Concatenates one Null-terminated Unicode string to another Null-terminated - Unicode string, and returns the concatenated Unicode string. - - This function concatenates two Null-terminated Unicode strings. The contents - of Null-terminated Unicode string Source are concatenated to the end of - Null-terminated Unicode string Destination. The Null-terminated concatenated - Unicode String is returned. If Source and Destination overlap, then the - results are undefined. - - If Destination is NULL, then ASSERT(). - If Destination is not aligned on a 16-bit boundary, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source is not aligned on a 16-bit boundary, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Destination contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Source contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination - and Source results in a Unicode string with more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param Destination A pointer to a Null-terminated Unicode string. - @param Source A pointer to a Null-terminated Unicode string. - - @return Destination. - -**/ -CHAR16 * -StrCat ( - IN OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ) -{ - StrCpy (Destination + FceStrLen (Destination), Source); - - // - // Size of the resulting string should never be zero. - // PcdMaximumUnicodeStringLength is tested inside FceStrLen(). - // - ASSERT (FceStrSize (Destination) != 0); - return Destination; -} - -/** - Returns the first occurrence of a Null-terminated Unicode sub-string - in a Null-terminated Unicode string. - - This function scans the contents of the Null-terminated Unicode string - specified by String and returns the first occurrence of SearchString. - If SearchString is not found in String, then NULL is returned. If - the length of SearchString is zero, then String is - returned. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If SearchString is NULL, then ASSERT(). - If SearchString is not aligned on a 16-bit boundary, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and SearchString - or String contains more than PcdMaximumUnicodeStringLength Unicode - characters, not including the Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - @param SearchString A pointer to a Null-terminated Unicode string to search for. - - @retval NULL If the SearchString does not appear in String. - @return others If there is a match. - -**/ -CHAR16 * -StrStr ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *SearchString - ) -{ - CONST CHAR16 *FirstMatch; - CONST CHAR16 *SearchStringTmp; - - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside FceStrLen(). - // - ASSERT (FceStrSize (String) != 0); - ASSERT (FceStrSize (SearchString) != 0); - - if (*SearchString == L'\0') { - return (CHAR16 *) String; - } - - while (*String != L'\0') { - SearchStringTmp = SearchString; - FirstMatch = String; - - while ((*String == *SearchStringTmp) - && (*String != L'\0')) { - String++; - SearchStringTmp++; - } - - if (*SearchStringTmp == L'\0') { - return (CHAR16 *) FirstMatch; - } - - if (*String == L'\0') { - return NULL; - } - - String = FirstMatch + 1; - } - - return NULL; -} - -/** - Convert one Null-terminated ASCII string to a Null-terminated - Unicode string and returns the Unicode string. - - This function converts the contents of the ASCII string Source to the Unicode - string Destination, and returns Destination. The function terminates the - Unicode string Destination by appending a Null-terminator character at the end. - The caller is responsible to make sure Destination points to a buffer with size - equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes. - - @param Source A pointer to a Null-terminated ASCII string. - @param Destination A pointer to a Null-terminated Unicode string. - - @return Destination. - @return NULL If Destination or Source is NULL, return NULL. - -**/ -CHAR16 * -AsciiStrToUnicodeStr ( - IN CONST CHAR8 *Source, - OUT CHAR16 *Destination - ) -{ - CHAR16 *ReturnValue; - - ReturnValue = NULL; - - if ((Destination == NULL) || (Source == NULL) || (strlen (Source) == 0)) { - return NULL; - } - ReturnValue = Destination; - while (*Source != '\0') { - *(Destination++) = (CHAR16) *(Source++); - } - // - // End the Destination with a NULL. - // - *Destination = '\0'; - - return ReturnValue; -} - -/** - Internal function that convert a number to a string in Buffer. - - Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer. - - @param Buffer Location to place the ASCII string of Value. - @param Value The value to convert to a Decimal or Hexadecimal string in Buffer. - @param Radix Radix of the value - - @return A pointer to the end of buffer filled with ASCII string. - -**/ -CHAR8 * -BasePrintLibValueToString ( - IN OUT CHAR8 *Buffer, - IN INT64 Value, - IN UINTN Radix - ) -{ - UINT32 Remainder; - - // - // Loop to convert one digit at a time in reverse order - // - *Buffer = 0; - do { - Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); - *(++Buffer) = mHexStr[Remainder]; - } while (Value != 0); - - // - // Return pointer of the end of filled buffer. - // - return Buffer; -} - -/** - Reads a 16-bit value from memory that may be unaligned. - - This function returns the 16-bit value pointed to by Buffer. The function - guarantees that the read operation does not produce an alignment fault. - - If the Buffer is NULL, then ASSERT(). - - @param Buffer A pointer to a 16-bit value that may be unaligned. - - @return The 16-bit value read from Buffer. - -**/ -UINT16 -FceReadUnaligned16 ( - IN CONST UINT16 *Buffer - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer; -} - -/** - Reads a 32-bit value from memory that may be unaligned. - - This function returns the 32-bit value pointed to by Buffer. The function - guarantees that the read operation does not produce an alignment fault. - - If the Buffer is NULL, then ASSERT(). - - @param Buffer A pointer to a 32-bit value that may be unaligned. - - @return The 32-bit value read from Buffer. - -**/ -UINT32 -ReadUnaligned32 ( - IN CONST UINT32 *Buffer - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer; -} - -/** - Internal function that places the character into the Buffer. - - Internal function that places ASCII or Unicode character into the Buffer. - - @param Buffer The buffer to place the Unicode or ASCII string. - @param EndBuffer The end of the input Buffer. No characters will be - placed after that. - @param Length The count of character to be placed into Buffer. - (Negative value indicates no buffer fill.) - @param Character The character to be placed into Buffer. - @param Increment The character increment in Buffer. - - @return Buffer. - -**/ -CHAR8 * -BasePrintLibFillBuffer ( - OUT CHAR8 *Buffer, - IN CHAR8 *EndBuffer, - IN INTN Length, - IN UINTN Character, - IN INTN Increment - ) -{ - INTN Index; - - for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) { - *Buffer = (CHAR8) Character; - if (Increment != 1) { - *(Buffer + 1) = (CHAR8)(Character >> 8); - } - Buffer += Increment; - } - - return Buffer; -} - -/** - Worker function that produces a Null-terminated string in an output buffer - based on a Null-terminated format string and a VA_LIST argument list. - - VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this routine allows the nesting of Vararg routines. Thus - this is the main print working routine. - - If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all. - - @param[out] Buffer The character buffer to print the results of the - parsing of Format into. - @param[in] BufferSize The maximum number of characters to put into - buffer. - @param[in] Flags Initial flags value. - Can only have FORMAT_UNICODE, OUTPUT_UNICODE, - and COUNT_ONLY_NO_PRINT set. - @param[in] Format A Null-terminated format string. - @param[in] VaListMarker VA_LIST style variable argument list consumed by - processing Format. - @param[in] BaseListMarker BASE_LIST style variable argument list consumed - by processing Format. - - @return The number of characters printed not including the Null-terminator. - If COUNT_ONLY_NO_PRINT was set returns the same, but without any - modification to Buffer. - -**/ -UINTN -BasePrintLibSPrintMarker ( - OUT CHAR8 *Buffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *Format, - IN VA_LIST VaListMarker, OPTIONAL - IN BASE_LIST BaseListMarker OPTIONAL - ) -{ - CHAR8 *OriginalBuffer; - CHAR8 *EndBuffer; - CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; - UINT32 BytesPerOutputCharacter; - UINTN BytesPerFormatCharacter; - UINTN FormatMask; - UINTN FormatCharacter; - UINTN Width; - UINTN Precision; - INT64 Value; - CONST CHAR8 *ArgumentString; - UINTN Character; - EFI_GUID *TmpGuid; - TIME *TmpTime; - UINTN Count; - UINTN ArgumentMask; - INTN BytesPerArgumentCharacter; - UINTN ArgumentCharacter; - BOOLEAN Done; - UINTN Index; - CHAR8 Prefix; - BOOLEAN ZeroPad; - BOOLEAN Comma; - UINTN Digits; - UINTN Radix; - RETURN_STATUS Status; - UINT32 GuidData1; - UINT16 GuidData2; - UINT16 GuidData3; - UINTN LengthToReturn; - - // - // If you change this code be sure to match the 2 versions of this function. - // Nearly identical logic is found in the BasePrintLib and - // DxePrintLibPrint2Protocol (both PrintLib instances). - // - - if ((Flags & COUNT_ONLY_NO_PRINT) != 0) { - if (BufferSize == 0) { - Buffer = NULL; - } - } else { - // - // We can run without a Buffer for counting only. - // - if (BufferSize == 0) { - return 0; - } - ASSERT (Buffer != NULL); - } - - if ((Flags & OUTPUT_UNICODE) != 0) { - BytesPerOutputCharacter = 2; - } else { - BytesPerOutputCharacter = 1; - } - - LengthToReturn = 0; - - // - // Reserve space for the Null terminator. - // - BufferSize--; - OriginalBuffer = Buffer; - - // - // Set the tag for the end of the input Buffer. - // - EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter; - - if ((Flags & FORMAT_UNICODE) != 0) { - // - // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength - // Unicode characters if PcdMaximumUnicodeStringLength is not zero. - // - ASSERT (FceStrSize ((CHAR16 *) Format) != 0); - BytesPerFormatCharacter = 2; - FormatMask = 0xffff; - } else { - // - // Make sure format string cannot contain more than PcdMaximumAsciiStringLength - // Ascii characters if PcdMaximumAsciiStringLength is not zero. - // - ASSERT (strlen (Format) + 1 != 0); - BytesPerFormatCharacter = 1; - FormatMask = 0xff; - } - - // - // Get the first character from the format string - // - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - - // - // Loop until the end of the format string is reached or the output buffer is full - // - while (FormatCharacter != 0 && Buffer < EndBuffer) { - // - // Clear all the flag bits except those that may have been passed in - // - Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT); - - // - // Set the default width to zero, and the default precision to 1 - // - Width = 0; - Precision = 1; - Prefix = 0; - Comma = FALSE; - ZeroPad = FALSE; - Count = 0; - Digits = 0; - - switch (FormatCharacter) { - case '%': - // - // Parse Flags and Width - // - for (Done = FALSE; !Done; ) { - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - switch (FormatCharacter) { - case '.': - Flags |= PRECISION; - break; - case '-': - Flags |= LEFT_JUSTIFY; - break; - case '+': - Flags |= PREFIX_SIGN; - break; - case ' ': - Flags |= PREFIX_BLANK; - break; - case ',': - Flags |= COMMA_TYPE; - break; - case 'L': - case 'l': - Flags |= LONG_TYPE; - break; - case '*': - if ((Flags & PRECISION) == 0) { - Flags |= PAD_TO_WIDTH; - if (BaseListMarker == NULL) { - Width = VA_ARG (VaListMarker, UINTN); - } else { - Width = BASE_ARG (BaseListMarker, UINTN); - } - } else { - if (BaseListMarker == NULL) { - Precision = VA_ARG (VaListMarker, UINTN); - } else { - Precision = BASE_ARG (BaseListMarker, UINTN); - } - } - break; - case '0': - if ((Flags & PRECISION) == 0) { - Flags |= PREFIX_ZERO; - } - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){ - Count = (Count * 10) + FormatCharacter - '0'; - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - } - Format -= BytesPerFormatCharacter; - if ((Flags & PRECISION) == 0) { - Flags |= PAD_TO_WIDTH; - Width = Count; - } else { - Precision = Count; - } - break; - - case '\0': - // - // Make no output if Format string terminates unexpectedly when - // looking up for flag, width, precision and type. - // - Format -= BytesPerFormatCharacter; - Precision = 0; - // - // break skipped on purpose. - // - default: - Done = TRUE; - break; - } - } - - // - // Handle each argument type - // - switch (FormatCharacter) { - case 'p': - // - // Flag space, +, 0, L & l are invalid for type p. - // - Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE); - if (sizeof (VOID *) > 4) { - Flags |= LONG_TYPE; - } - case 'X': - Flags |= PREFIX_ZERO; - // - // break skipped on purpose - // - case 'x': - Flags |= RADIX_HEX; - // - // break skipped on purpose - // - case 'd': - if ((Flags & LONG_TYPE) == 0) { - // - // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int". - // This assumption is made so the format string definition is compatible with the ANSI C - // Specification for formatted strings. It is recommended that the Base Types be used - // everywhere, but in this one case, compliance with ANSI C is more important, and - // provides an implementation that is compatible with that largest possible set of CPU - // architectures. This is why the type "int" is used in this one case. - // - if (BaseListMarker == NULL) { - Value = VA_ARG (VaListMarker, int); - } else { - Value = BASE_ARG (BaseListMarker, int); - } - } else { - if (BaseListMarker == NULL) { - Value = VA_ARG (VaListMarker, INT64); - } else { - Value = BASE_ARG (BaseListMarker, INT64); - } - } - if ((Flags & PREFIX_BLANK) != 0) { - Prefix = ' '; - } - if ((Flags & PREFIX_SIGN) != 0) { - Prefix = '+'; - } - if ((Flags & COMMA_TYPE) != 0) { - Comma = TRUE; - } - if ((Flags & RADIX_HEX) == 0) { - Radix = 10; - if (Comma) { - Flags &= (~PREFIX_ZERO); - Precision = 1; - } - if (Value < 0) { - Flags |= PREFIX_SIGN; - Prefix = '-'; - Value = -Value; - } - } else { - Radix = 16; - Comma = FALSE; - if ((Flags & LONG_TYPE) == 0 && Value < 0) { - // - // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int". - // This assumption is made so the format string definition is compatible with the ANSI C - // Specification for formatted strings. It is recommended that the Base Types be used - // everywhere, but in this one case, compliance with ANSI C is more important, and - // provides an implementation that is compatible with that largest possible set of CPU - // architectures. This is why the type "unsigned int" is used in this one case. - // - Value = (unsigned int)Value; - } - } - // - // Convert Value to a reversed string - // - Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer; - if (Value == 0 && Precision == 0) { - Count = 0; - } - ArgumentString = (CHAR8 *)ValueBuffer + Count; - - Digits = Count % 3; - if (Digits != 0) { - Digits = 3 - Digits; - } - if (Comma && Count != 0) { - Count += ((Count - 1) / 3); - } - if (Prefix != 0) { - Count++; - Precision++; - } - Flags |= ARGUMENT_REVERSED; - ZeroPad = TRUE; - if ((Flags & PREFIX_ZERO) != 0) { - if ((Flags & LEFT_JUSTIFY) == 0) { - if ((Flags & PAD_TO_WIDTH) != 0) { - if ((Flags & PRECISION) == 0) { - Precision = Width; - } - } - } - } - break; - - case 's': - case 'S': - Flags |= ARGUMENT_UNICODE; - // - // break skipped on purpose - // - case 'a': - if (BaseListMarker == NULL) { - ArgumentString = VA_ARG (VaListMarker, CHAR8 *); - } else { - ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *); - } - if (ArgumentString == NULL) { - Flags &= (~ARGUMENT_UNICODE); - ArgumentString = ""; - } - // - // Set the default precision for string to be zero if not specified. - // - if ((Flags & PRECISION) == 0) { - Precision = 0; - } - break; - - case 'c': - if (BaseListMarker == NULL) { - Character = VA_ARG (VaListMarker, UINTN) & 0xffff; - } else { - Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff; - } - ArgumentString = (CHAR8 *)&Character; - Flags |= ARGUMENT_UNICODE; - break; - - case 'g': - if (BaseListMarker == NULL) { - TmpGuid = VA_ARG (VaListMarker, EFI_GUID *); - } else { - TmpGuid = BASE_ARG (BaseListMarker, EFI_GUID *); - } - if (TmpGuid == NULL) { - ArgumentString = ""; - } else { - GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1)); - GuidData2 = FceReadUnaligned16 (&(TmpGuid->Data2)); - GuidData3 = FceReadUnaligned16 (&(TmpGuid->Data3)); - BasePrintLibSPrint ( - ValueBuffer, - MAXIMUM_VALUE_CHARACTERS, - 0, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - GuidData1, - GuidData2, - GuidData3, - TmpGuid->Data4[0], - TmpGuid->Data4[1], - TmpGuid->Data4[2], - TmpGuid->Data4[3], - TmpGuid->Data4[4], - TmpGuid->Data4[5], - TmpGuid->Data4[6], - TmpGuid->Data4[7] - ); - ArgumentString = ValueBuffer; - } - break; - - case 't': - if (BaseListMarker == NULL) { - TmpTime = VA_ARG (VaListMarker, TIME *); - } else { - TmpTime = BASE_ARG (BaseListMarker, TIME *); - } - if (TmpTime == NULL) { - ArgumentString = ""; - } else { - BasePrintLibSPrint ( - ValueBuffer, - MAXIMUM_VALUE_CHARACTERS, - 0, - "%02d/%02d/%04d %02d:%02d", - TmpTime->Month, - TmpTime->Day, - TmpTime->Year, - TmpTime->Hour, - TmpTime->Minute - ); - ArgumentString = ValueBuffer; - } - break; - - case 'r': - if (BaseListMarker == NULL) { - Status = VA_ARG (VaListMarker, RETURN_STATUS); - } else { - Status = BASE_ARG (BaseListMarker, RETURN_STATUS); - } - ArgumentString = ValueBuffer; - if (RETURN_ERROR (Status)) { - // - // Clear error bit - // - Index = Status & ~MAX_BIT; - if (Index > 0 && Index <= ERROR_STATUS_NUMBER) { - ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER]; - } - } else { - Index = Status; - if (Index <= WARNING_STATUS_NUMBER) { - ArgumentString = mStatusString [Index]; - } - } - if (ArgumentString == ValueBuffer) { - BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status); - } - break; - - case '\r': - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - if (FormatCharacter == '\n') { - // - // Translate '\r\n' to '\r\n' - // - ArgumentString = "\r\n"; - } else { - // - // Translate '\r' to '\r' - // - ArgumentString = "\r"; - Format -= BytesPerFormatCharacter; - } - break; - - case '\n': - // - // Translate '\n' to '\r\n' and '\n\r' to '\r\n' - // - ArgumentString = "\r\n"; - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - if (FormatCharacter != '\r') { - Format -= BytesPerFormatCharacter; - } - break; - - case '%': - default: - // - // if the type is '%' or unknown, then print it to the screen - // - ArgumentString = (CHAR8 *)&FormatCharacter; - Flags |= ARGUMENT_UNICODE; - break; - } - break; - - case '\r': - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - if (FormatCharacter == '\n') { - // - // Translate '\r\n' to '\r\n' - // - ArgumentString = "\r\n"; - } else { - // - // Translate '\r' to '\r' - // - ArgumentString = "\r"; - Format -= BytesPerFormatCharacter; - } - break; - - case '\n': - // - // Translate '\n' to '\r\n' and '\n\r' to '\r\n' - // - ArgumentString = "\r\n"; - Format += BytesPerFormatCharacter; - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - if (FormatCharacter != '\r') { - Format -= BytesPerFormatCharacter; - } - break; - - default: - ArgumentString = (CHAR8 *)&FormatCharacter; - Flags |= ARGUMENT_UNICODE; - break; - } - - // - // Retrieve the ArgumentString attriubutes - // - if ((Flags & ARGUMENT_UNICODE) != 0) { - ArgumentMask = 0xffff; - BytesPerArgumentCharacter = 2; - } else { - ArgumentMask = 0xff; - BytesPerArgumentCharacter = 1; - } - if ((Flags & ARGUMENT_REVERSED) != 0) { - BytesPerArgumentCharacter = -BytesPerArgumentCharacter; - } else { - // - // Compute the number of characters in ArgumentString and store it in Count - // ArgumentString is either null-terminated, or it contains Precision characters - // - for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) { - ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask; - if (ArgumentCharacter == 0) { - break; - } - } - } - - if (Precision < Count) { - Precision = Count; - } - - // - // Pad before the string - // - if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) { - LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter); - } - } - - if (ZeroPad) { - if (Prefix != 0) { - LengthToReturn += (1 * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter); - } - } - LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter); - } - } else { - LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter); - } - if (Prefix != 0) { - LengthToReturn += (1 * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter); - } - } - } - - // - // Output the Prefix character if it is present - // - Index = 0; - if (Prefix != 0) { - Index++; - } - - // - // Copy the string into the output buffer performing the required type conversions - // - while (Index < Count) { - ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask; - - LengthToReturn += (1 * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter); - } - ArgumentString += BytesPerArgumentCharacter; - Index++; - if (Comma) { - Digits++; - if (Digits == 3) { - Digits = 0; - Index++; - if (Index < Count) { - LengthToReturn += (1 * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter); - } - } - } - } - } - - // - // Pad after the string - // - if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) { - LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter); - if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) { - Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter); - } - } - - // - // Get the next character from the format string - // - Format += BytesPerFormatCharacter; - - // - // Get the next character from the format string - // - FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; - } - - if ((Flags & COUNT_ONLY_NO_PRINT) != 0) { - return (LengthToReturn / BytesPerOutputCharacter); - } - - ASSERT (Buffer != NULL); - // - // Null terminate the Unicode or ASCII string - // - BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter); - // - // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength - // Unicode characters if PcdMaximumUnicodeStringLength is not zero. - // - ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (FceStrSize ((CHAR16 *) OriginalBuffer) != 0)); - // - // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength - // ASCII characters if PcdMaximumAsciiStringLength is not zero. - // - ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || ((strlen (OriginalBuffer) + 1) != 0)); - - return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter); -} - -/** - Worker function that produces a Null-terminated string in an output buffer - based on a Null-terminated format string and variable argument list. - - VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this routine allows the nesting of Vararg routines. Thus - this is the main print working routine - - @param StartOfBuffer The character buffer to print the results of the parsing - of Format into. - @param BufferSize The maximum number of characters to put into buffer. - Zero means no limit. - @param Flags Initial flags value. - Can only have FORMAT_UNICODE and OUTPUT_UNICODE set - @param FormatString A Null-terminated format string. - @param ... The variable argument list. - - @return The number of characters printed. - -**/ -UINTN -BasePrintLibSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL); -} - -/** - Produces a Null-terminated Unicode string in an output buffer based on - a Null-terminated Unicode format string and a VA_LIST argument list - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list specified by Marker based on the - contents of the format string. - The number of Unicode characters in the produced output buffer is returned not including - the Null-terminator. - If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. - - If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). - If BufferSize > 1 and FormatString is NULL, then ASSERT(). - If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then - ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters not including the - Null-terminator, then ASSERT(). - - @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString A Null-terminated Unicode format string. - @param Marker VA_LIST marker for the variable argument list. - - @return The number of Unicode characters in the produced output buffer not including the - Null-terminator. - -**/ -UINTN -UnicodeVSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - IN VA_LIST Marker - ) -{ - ASSERT_UNICODE_BUFFER (StartOfBuffer); - ASSERT_UNICODE_BUFFER (FormatString); - return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker, NULL); -} - -/** - Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated - Unicode format string and variable argument list. - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the format string. - The number of Unicode characters in the produced output buffer is returned not including - the Null-terminator. - If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. - - If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). - If BufferSize > 1 and FormatString is NULL, then ASSERT(). - If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then - ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters not including the - Null-terminator, then ASSERT(). - - @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString A Null-terminated Unicode format string. - @param ... Variable argument list whose contents are accessed based on the - format string specified by FormatString. - - @return The number of Unicode characters in the produced output buffer not including the - Null-terminator. - -**/ -UINTN -UnicodeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); -} - -/** - Convert a Null-terminated Unicode string to a Null-terminated - ASCII string and returns the ASCII string. - - This function converts the content of the Unicode string Source - to the ASCII string Destination by copying the lower 8 bits of - each Unicode character. It returns Destination. The function terminates - the ASCII string Destination by appending a Null-terminator character - at the end. The caller is responsible to make sure Destination points - to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source is not aligned on a 16-bit boundary, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - If any Unicode characters in Source contain non-zero value in - the upper 8 bits, then ASSERT(). - - @param Source Pointer to a Null-terminated Unicode string. - @param Destination Pointer to a Null-terminated ASCII string. - - @reture Destination - -**/ -CHAR8 * -UnicodeStrToAsciiStr ( - IN CONST CHAR16 *Source, - OUT CHAR8 *Destination - ) -{ - CHAR8 *ReturnValue; - - ReturnValue = Destination; - assert (Destination != NULL); - assert (Source != NULL); - assert (((UINTN) Source & 0x01) == 0); - - while (*Source != L'\0') { - // - // If any Unicode characters in Source contain - // non-zero value in the upper 8 bits, then ASSERT(). - // - assert (*Source < 0x100); - *(ReturnValue++) = (CHAR8) *(Source++); - } - - *ReturnValue = '\0'; - - return Destination; -} - -/** - Allocate new memory and then copy the Unicode string Source to Destination. - - @param Dest Location to copy string - @param Src String to copy - -**/ -VOID -NewStringCpy ( - IN OUT CHAR16 **Dest, - IN CHAR16 *Src - ) -{ - if (*Dest != NULL) { - FreePool (*Dest); - } - *Dest = FceAllocateCopyPool (FceStrSize (Src), Src); - ASSERT (*Dest != NULL); -} - -/** - Check if a Unicode character is a decimal character. - - This internal function checks if a Unicode character is a - decimal character. The valid decimal character is from - L'0' to L'9'. - - @param Char The character to check against. - - @retval TRUE If the Char is a decmial character. - @retval FALSE If the Char is not a decmial character. - -**/ -BOOLEAN -FceInternalIsDecimalDigitCharacter ( - IN CHAR16 Char - ) -{ - return (BOOLEAN) ((Char >= L'0') && (Char <= L'9')); -} - -/** - Convert a Unicode character to upper case only if - it maps to a valid small-case ASCII character. - - This internal function only deal with Unicode character - which maps to a valid small-case ASCII character, i.e. - L'a' to L'z'. For other Unicode character, the input character - is returned directly. - - @param Char The character to convert. - - @retval LowerCharacter If the Char is with range L'a' to L'z'. - @retval Unchanged Otherwise. - -**/ -CHAR16 -FceInternalCharToUpper ( - IN CHAR16 Char - ) -{ - if ((Char >= L'a') && (Char <= L'z')) { - return (CHAR16) (Char - (L'a' - L'A')); - } - - return Char; -} - -/** - Convert a Unicode character to numerical value. - - This internal function only deal with Unicode character - which maps to a valid hexadecimal ASII character, i.e. - L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other - Unicode character, the value returned does not make sense. - - @param Char The character to convert. - - @return The numerical value converted. - -**/ -UINTN -FceInternalHexCharToUintn ( - IN CHAR16 Char - ) -{ - if (FceInternalIsDecimalDigitCharacter (Char)) { - return Char - L'0'; - } - - return (UINTN) (10 + FceInternalCharToUpper (Char) - L'A'); -} - -/** - Check if a Unicode character is a hexadecimal character. - - This internal function checks if a Unicode character is a - decimal character. The valid hexadecimal character is - L'0' to L'9', L'a' to L'f', or L'A' to L'F'. - - - @param Char The character to check against. - - @retval TRUE If the Char is a hexadecmial character. - @retval FALSE If the Char is not a hexadecmial character. - -**/ -BOOLEAN -FceInternalIsHexaDecimalDigitCharacter ( - IN CHAR16 Char - ) -{ - - return (BOOLEAN) (FceInternalIsDecimalDigitCharacter (Char) || - ((Char >= L'A') && (Char <= L'F')) || - ((Char >= L'a') && (Char <= L'f'))); -} - - -/** - Convert a Null-terminated Unicode decimal string to a value of - type UINT64. - - This function returns a value of type UINT64 by interpreting the contents - of the Unicode string specified by String as a decimal number. The format - of the input Unicode string String is: - - [spaces] [decimal digits]. - - The valid decimal digit character is in the range [0-9]. The - function will ignore the pad space, which includes spaces or - tab characters, before [decimal digits]. The running zero in the - beginning of [decimal digits] will be ignored. Then, the function - stops at the first character that is a not a valid decimal character - or a Null-terminator, whichever one comes first. - - If String is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If String has only pad spaces, then 0 is returned. - If String has no pad spaces or valid decimal digits, - then 0 is returned. - If the number represented by String overflows according - to the range defined by UINT64, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and String contains - more than PcdMaximumUnicodeStringLength Unicode characters, not including - the Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @retval Value translated from String. - -**/ -UINT64 -FceStrDecimalToUint64 ( - IN CONST CHAR16 *String - ) -{ - UINT64 Result; - - // - // ASSERT String is less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside FceStrLen(). - // - ASSERT (FceStrSize (String) != 0); - - // - // Ignore the pad spaces (space or tab) - // - while ((*String == L' ') || (*String == L'\t')) { - String++; - } - - // - // Ignore leading Zeros after the spaces - // - while (*String == L'0') { - String++; - } - - Result = 0; - - while (FceInternalIsDecimalDigitCharacter (*String)) { - // - // If the number represented by String overflows according - // to the range defined by UINTN, then ASSERT(). - // - ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10)); - - Result = MultU64x32 (Result, 10) + (*String - L'0'); - String++; - } - - return Result; -} - - -/** - Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64. - - This function returns a value of type UINT64 by interpreting the contents - of the Unicode string specified by String as a hexadecimal number. - The format of the input Unicode string String is - - [spaces][zeros][x][hexadecimal digits]. - - The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. - The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. - If "x" appears in the input string, it must be prefixed with at least one 0. - The function will ignore the pad space, which includes spaces or tab characters, - before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or - [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the - first valid hexadecimal digit. Then, the function stops at the first character that is - a not a valid hexadecimal character or NULL, whichever one comes first. - - If String is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If String has only pad spaces, then zero is returned. - If String has no leading pad spaces, leading zeros or valid hexadecimal digits, - then zero is returned. - If the number represented by String overflows according to the range defined by - UINT64, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, - then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @retval Value translated from String. - -**/ -UINT64 -FceStrHexToUint64 ( - IN CONST CHAR16 *String - ) -{ - UINT64 Result; - - // - // ASSERT String is less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside FceStrLen(). - // - ASSERT (FceStrSize (String) != 0); - - // - // Ignore the pad spaces (space or tab) - // - while ((*String == L' ') || (*String == L'\t')) { - String++; - } - - // - // Ignore leading Zeros after the spaces - // - while (*String == L'0') { - String++; - } - - if (FceInternalCharToUpper (*String) == L'X') { - ASSERT (*(String - 1) == L'0'); - if (*(String - 1) != L'0') { - return 0; - } - // - // Skip the 'X' - // - String++; - } - - Result = 0; - - while (FceInternalIsHexaDecimalDigitCharacter (*String)) { - // - // If the Hex Number represented by String overflows according - // to the range defined by UINTN, then ASSERT(). - // - ASSERT (Result <= RShiftU64 (((UINT64) ~0) - FceInternalHexCharToUintn (*String) , 4)); - - Result = LShiftU64 (Result, 4); - Result = Result + FceInternalHexCharToUintn (*String); - String++; - } - - return Result; -} - - -CHAR16 -ToUpper ( - CHAR16 a - ) -{ - if (('a' <= a) && (a <= 'z')) { - return (CHAR16) (a - 0x20); - } else { - return a; - } -} - -CHAR16 -ToLower ( - CHAR16 a - ) -{ - if (('A' <= a) && (a <= 'Z')) { - return (CHAR16) (a + 0x20); - } else { - return a; - } -} - -/** - Performs a case-insensitive comparison between a Null-terminated - Unicode pattern string and a Null-terminated Unicode string. - - @param String - A pointer to a Null-terminated Unicode string. - @param Pattern - A pointer to a Null-terminated Unicode pattern string. - - - @retval TRUE - Pattern was found in String. - @retval FALSE - Pattern was not found in String. - -**/ -BOOLEAN -MetaiMatch ( - IN CHAR16 *String, - IN CHAR16 *Pattern - ) -{ - CHAR16 c; - CHAR16 p; - - assert (String != NULL); - assert (Pattern != NULL); - - for (;;) { - p = *Pattern; - Pattern += 1; - - if (p == 0) { - // - // End of pattern. If end of string, TRUE match - // - if (*String) { - return FALSE; - } else { - return TRUE; - } - - } else { - - c = *String; - if (ToUpper (c) != ToUpper (p)) { - return FALSE; - } - - String += 1; - - } - - } - -} -/** - Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and - generates a 64-bit unsigned result. - - This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit - unsigned value Multiplier and generates a 64-bit unsigned result. This 64- - bit unsigned result is returned. - - @param Multiplicand A 64-bit unsigned value. - @param Multiplier A 32-bit unsigned value. - - @return Multiplicand * Multiplier. - -**/ -UINT64 -MultU64x32 ( - IN UINT64 Multiplicand, - IN UINT32 Multiplier - ) -{ - return Multiplicand * Multiplier; -} - -/** - Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates - a 64-bit unsigned result. - - This function divides the 64-bit unsigned value Dividend by the 32-bit - unsigned value Divisor and generates a 64-bit unsigned quotient. This - function returns the 64-bit unsigned quotient. - - If Divisor is 0, then ASSERT(). - - @param Dividend A 64-bit unsigned value. - @param Divisor A 32-bit unsigned value. - - @return Dividend / Divisor - -**/ -UINT64 -DivU64x32 ( - IN UINT64 Dividend, - IN UINT32 Divisor - ) -{ - ASSERT (Divisor != 0); - return Dividend / Divisor; -} - -/** - Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled - with zeros. The shifted value is returned. - - This function shifts the 64-bit value Operand to the left by Count bits. The - low Count bits are set to zero. The shifted value is returned. - - If Count is greater than 63, then ASSERT(). - - @param Operand The 64-bit operand to shift left. - @param Count The number of bits to shift left. - - @return Operand << Count. - -**/ -UINT64 -LShiftU64 ( - IN UINT64 Operand, - IN UINTN Count - ) -{ - ASSERT (Count < 64); - return Operand << Count; -} - -/** - Shifts a 64-bit integer right between 0 and 63 bits. This high bits are - filled with zeros. The shifted value is returned. - - This function shifts the 64-bit value Operand to the right by Count bits. The - high Count bits are set to zero. The shifted value is returned. - - If Count is greater than 63, then ASSERT(). - - @param Operand The 64-bit operand to shift right. - @param Count The number of bits to shift right. - - @return Operand >> Count. - -**/ -UINT64 -RShiftU64 ( - IN UINT64 Operand, - IN UINTN Count - ) - -{ - ASSERT (Count < 64); - return Operand >> Count; -} - - -/** - Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates - a 64-bit unsigned result and an optional 32-bit unsigned remainder. - - This function divides the 64-bit unsigned value Dividend by the 32-bit - unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder - is not NULL, then the 32-bit unsigned remainder is returned in Remainder. - This function returns the 64-bit unsigned quotient. - - If Divisor is 0, then ASSERT(). - - @param Dividend A 64-bit unsigned value. - @param Divisor A 32-bit unsigned value. - @param Remainder A pointer to a 32-bit unsigned value. This parameter is - optional and may be NULL. - - @return Dividend / Divisor - -**/ -UINT64 -DivU64x32Remainder ( - IN UINT64 Dividend, - IN UINT32 Divisor, - OUT UINT32 *Remainder - ) -{ - ASSERT (Divisor != 0); - - if (Remainder != NULL) { - *Remainder = (UINT32)(Dividend % Divisor); - } - return Dividend / Divisor; -} - -/** - Copies a buffer to an allocated buffer. - - Allocates the number bytes specified by AllocationSize, copies allocationSize bytes - from Buffer to the newly allocated buffer, and returns a pointer to the allocated - buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -FceAllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - Memory = NULL; - - if ((Buffer == NULL) || (AllocationSize == 0)) { - return Memory; - } - - Memory = calloc (AllocationSize, sizeof (CHAR8)); - if (Memory != NULL) { - Memory = memcpy (Memory, Buffer, AllocationSize); - } - return Memory; -} - -/** - Initializes the head node of a doubly-linked list, and returns the pointer to - the head node of the doubly-linked list. - - Initializes the forward and backward links of a new linked list. After - initializing a linked list with this function, the other linked list - functions may be used to add and remove nodes from the linked list. It is up - to the caller of this function to allocate the memory for ListHead. - - If ListHead is NULL, then ASSERT(). - - @param ListHead A pointer to the head node of a new doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InitializeListHead ( - IN OUT LIST_ENTRY *ListHead - ) - -{ - assert (ListHead != NULL); - - ListHead->ForwardLink = ListHead; - ListHead->BackLink = ListHead; - return ListHead; -} - -/** - Adds a node to the beginning of a doubly-linked list, and returns the pointer - to the head node of the doubly-linked list. - - Adds the node Entry at the beginning of the doubly-linked list denoted by - ListHead, and returns ListHead. - - If ListHead is NULL, then ASSERT(). - If Entry is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number - of nodes in ListHead, including the ListHead node, is greater than or - equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - @param Entry A pointer to a node that is to be inserted at the beginning - of a doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InsertHeadList ( - IN OUT LIST_ENTRY *ListHead, - IN OUT LIST_ENTRY *Entry - ) -{ - assert ((ListHead != NULL) && (Entry != NULL)); - - Entry->ForwardLink = ListHead->ForwardLink; - Entry->BackLink = ListHead; - Entry->ForwardLink->BackLink = Entry; - ListHead->ForwardLink = Entry; - return ListHead; -} - -/** - Adds a node to the end of a doubly-linked list, and returns the pointer to - the head node of the doubly-linked list. - - Adds the node Entry to the end of the doubly-linked list denoted by ListHead, - and returns ListHead. - - If ListHead is NULL, then ASSERT(). - If Entry is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number - of nodes in ListHead, including the ListHead node, is greater than or - equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - @param Entry A pointer to a node that is to be added at the end of the - doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InsertTailList ( - IN OUT LIST_ENTRY *ListHead, - IN OUT LIST_ENTRY *Entry - ) -{ - assert ((ListHead != NULL) && (Entry != NULL)); - - Entry->ForwardLink = ListHead; - Entry->BackLink = ListHead->BackLink; - Entry->BackLink->ForwardLink = Entry; - ListHead->BackLink = Entry; - return ListHead; -} - -/** - Retrieves the first node of a doubly-linked list. - - Returns the first node of a doubly-linked list. List must have been - initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - - @return The first node of a doubly-linked list. - @retval NULL The list is empty. - -**/ -LIST_ENTRY * -GetFirstNode ( - IN CONST LIST_ENTRY *List - ) -{ - assert (List != NULL); - - return List->ForwardLink; -} - -/** - Retrieves the next node of a doubly-linked list. - - Returns the node of a doubly-linked list that follows Node. - List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() - or InitializeListHead(). If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and List contains more than - PcdMaximumLinkedListLenth nodes, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @return A pointer to the next node if one exists. Otherwise List is returned. - -**/ -LIST_ENTRY * -GetNextNode ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ) -{ - assert ((List != NULL) && (Node != NULL)); - - return Node->ForwardLink; -} - -/** - Retrieves the previous node of a doubly-linked list. - - Returns the node of a doubly-linked list that precedes Node. - List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() - or InitializeListHead(). If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and List contains more than - PcdMaximumLinkedListLenth nodes, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @return A pointer to the previous node if one exists. Otherwise List is returned. - -**/ -LIST_ENTRY * -GetPreviousNode ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ) -{ - assert ((List != NULL) && (Node != NULL)); - - return Node->BackLink; -} - -/** - Checks to see if a doubly-linked list is empty or not. - - Checks to see if the doubly-linked list is empty. If the linked list contains - zero nodes, this function returns TRUE. Otherwise, it returns FALSE. - - If ListHead is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - - @retval TRUE The linked list is empty. - @retval FALSE The linked list is not empty. - -**/ -BOOLEAN -IsListEmpty ( - IN CONST LIST_ENTRY *ListHead - ) -{ - assert (ListHead != NULL); - - return (BOOLEAN)(ListHead->ForwardLink == ListHead); -} - -/** - Determines if a node in a doubly-linked list is the head node of a the same - doubly-linked list. This function is typically used to terminate a loop that - traverses all the nodes in a doubly-linked list starting with the head node. - - Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the - nodes in the doubly-linked list specified by List. List must have been - initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(), - then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not - equal to List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @retval TRUE Node is the head of the doubly-linked list pointed by List. - @retval FALSE Node is not the head of the doubly-linked list pointed by List. - -**/ -BOOLEAN -IsNull ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ) -{ - assert ((List != NULL) && (Node != NULL)); - - return (BOOLEAN)(Node == List); -} - -/** - Determines if a node the last node in a doubly-linked list. - - Returns TRUE if Node is the last node in the doubly-linked list specified by - List. Otherwise, FALSE is returned. List must have been initialized with - INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @retval TRUE Node is the last node in the linked list. - @retval FALSE Node is not the last node in the linked list. - -**/ -BOOLEAN -IsNodeAtEnd ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ) -{ - assert ((List != NULL) && (Node != NULL)); - - return (BOOLEAN)(!IsNull (List, Node) && (List->BackLink == Node)); -} - -/** - Removes a node from a doubly-linked list, and returns the node that follows - the removed node. - - Removes the node Entry from a doubly-linked list. It is up to the caller of - this function to release the memory used by this node if that is required. On - exit, the node following Entry in the doubly-linked list is returned. If - Entry is the only node in the linked list, then the head node of the linked - list is returned. - - If Entry is NULL, then ASSERT(). - If Entry is the head node of an empty list, then ASSERT(). - If PcdMaximumLinkedListLength is not zero, and the number of nodes in the - linked list containing Entry, including the Entry node, is greater than - or equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param Entry A pointer to a node in a linked list. - - @return Entry. - -**/ -LIST_ENTRY * -RemoveEntryList ( - IN CONST LIST_ENTRY *Entry - ) -{ - assert (!IsListEmpty (Entry)); - - Entry->ForwardLink->BackLink = Entry->BackLink; - Entry->BackLink->ForwardLink = Entry->ForwardLink; - return Entry->ForwardLink; -} - diff --git a/BaseTools/Source/C/FCE/Common.h b/BaseTools/Source/C/FCE/Common.h deleted file mode 100644 index 6b21974878..0000000000 --- a/BaseTools/Source/C/FCE/Common.h +++ /dev/null @@ -1,999 +0,0 @@ -/** @file - - Common library. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#ifndef _COMMON_LIB_H_ -#define _COMMON_LIB_H_ - -#include -#include -#include -#ifdef __GNUC__ -#include -#else -#include -#include -#endif -#include -#include -#include -#include "CommonLib.h" -#include - -#define MAX_QUI_PARAM_LEN 2000 -#define ERROR_INFO_LENGTH 400 -#define MAX_STR_LEN_FOR_PICK_UQI 200 -#define MAX_PLATFORM_DEFAULT_ID_NUM 1000 -#define _MAX_BUILD_VERSION 100 -#define _MAXIMUM_SECTION_FILE_NUM 1000 - -#ifndef _MAX_PATH -#define _MAX_PATH 500 -#endif - -/// -/// Variable attributes. -/// -#define EFI_VARIABLE_NON_VOLATILE 0x00000001 -#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 -#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 - -/// -/// This attribute is identified by the mnemonic 'HR' -/// elsewhere in this specification. -/// -#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 - -#define VARSTORE_LIST_TYPE 0x0000000000000001ULL -#define EFI_VARSTORE_LIST_TYPE 0x0000000000000002ULL -#define PLATFORM_DEFAULT_ID_TYPE 0x0000000000000004ULL -#define UQI_LIST_TYPE 0x0000000000000008ULL -#define HII_OBJ_LIST_TYPE 0x0000000000000010ULL - -/// -/// LIST_ENTRY structure definition. -/// -typedef struct _LIST_ENTRY { - struct _LIST_ENTRY *ForwardLink; - struct _LIST_ENTRY *BackLink; -} LIST_ENTRY; - -#define CR(Record, TYPE, Field, TestSignature) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) -#define AllocateZeroPool(a) calloc(a, sizeof (CHAR8)) -#define FreePool(a) free(a) -#define CopyMem(a, b, c) memcpy(a, b, c) -#define ZeroMem(a, b) memset(a, 0, b) -#define CompareMem(a, b, c) memcmp(a, b, c) -#define AllocatePool(a) malloc(a) - -/** - Returns a 16-bit signature built from 2 ASCII characters. - - This macro returns a 16-bit value built from the two ASCII characters specified - by A and B. - - @param A The first ASCII character. - @param B The second ASCII character. - - @return A 16-bit value built from the two ASCII characters specified by A and B. - -**/ -#define SIGNATURE_16(A, B) ((A) | (B << 8)) - -/** - Returns a 32-bit signature built from 4 ASCII characters. - - This macro returns a 32-bit value built from the four ASCII characters specified - by A, B, C, and D. - - @param A The first ASCII character. - @param B The second ASCII character. - @param C The third ASCII character. - @param D The fourth ASCII character. - - @return A 32-bit value built from the two ASCII characters specified by A, B, - C and D. - -**/ -#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) - -#define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0) - -/** - Returns an argument of a specified type from a variable argument list and updates - the pointer to the variable argument list to point to the next argument. - - This function returns an argument of the type specified by TYPE from the beginning - of the variable argument list specified by Marker. Marker is then updated to point - to the next argument in the variable argument list. The method for computing the - pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI. - - @param Marker The pointer to the beginning of a variable argument list. - @param TYPE The type of argument to retrieve from the beginning - of the variable argument list. - - @return An argument of the type specified by TYPE. - -**/ -#define BASE_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE))) - -/// -/// Define the maximum number of characters that are required to -/// encode with a NULL terminator a decimal, hexadecimal, GUID, -/// or TIME value. -/// -/// Maximum Length Decimal String = 28 -/// "-9,223,372,036,854,775,808" -/// Maximum Length Hexadecimal String = 17 -/// "FFFFFFFFFFFFFFFF" -/// Maximum Length GUID = 37 -/// "00000000-0000-0000-0000-000000000000" -/// Maximum Length TIME = 18 -/// "12/12/2006 12:12" -/// -#define MAXIMUM_VALUE_CHARACTERS 38 - -/// -/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *. -/// -typedef UINTN *BASE_LIST; - -/** - Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary. - - @param TYPE The date type to determine the size of. - - @return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary. -**/ -#define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN)) - -// -// Print primitives -// -#define PREFIX_SIGN BIT1 -#define PREFIX_BLANK BIT2 -#define LONG_TYPE BIT4 -#define OUTPUT_UNICODE BIT6 -#define FORMAT_UNICODE BIT8 -#define PAD_TO_WIDTH BIT9 -#define ARGUMENT_UNICODE BIT10 -#define PRECISION BIT11 -#define ARGUMENT_REVERSED BIT12 -#define COUNT_ONLY_NO_PRINT BIT13 - -/// -/// Flags bitmask values use in UnicodeValueToString() and -/// AsciiValueToString() -/// -#define LEFT_JUSTIFY 0x01 -#define COMMA_TYPE 0x08 -#define PREFIX_ZERO 0x20 -#define RADIX_HEX 0x80 - -// -// Record date and time information -// -typedef struct { - UINT16 Year; - UINT8 Month; - UINT8 Day; - UINT8 Hour; - UINT8 Minute; - UINT8 Second; - UINT8 Pad1; - UINT32 Nanosecond; - INT16 TimeZone; - UINT8 Daylight; - UINT8 Pad2; -} TIME; - - -/** - Copies one Null-terminated Unicode string to another Null-terminated Unicode - string and returns the new Unicode string. - - This function copies the contents of the Unicode string Source to the Unicode - string Destination, and returns Destination. If Source and Destination - overlap, then the results are undefined. - - If Destination is NULL, then return NULL. - If Destination is not aligned on a 16-bit boundary, then return NULL. - - @param Destination A pointer to a Null-terminated Unicode string. - @param Source A pointer to a Null-terminated Unicode string. - - @return Destination. - -**/ -CHAR16 * -StrCpy ( - OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ); - -/** - Returns the length of a Null-terminated Unicode string. - - This function returns the number of Unicode characters in the Null-terminated - Unicode string specified by String. - - If String is NULL, then return 0. - - @param String A pointer to a Null-terminated Unicode string. - - @return The length of String. - -**/ -UINTN -FceStrLen ( - IN CONST CHAR16 *String - ); - -/** - Returns the size of a Null-terminated Unicode string in bytes, including the - Null terminator. - - This function returns the size, in bytes, of the Null-terminated Unicode string - specified by String. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @return The size of String. - -**/ -UINTN -FceStrSize ( - IN CONST CHAR16 *String - ); - -/** - Compares two Null-terminated Unicode strings, and returns the difference - between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString. If FirstString is identical to - SecondString, then 0 is returned. Otherwise, the value returned is the first - mismatched Unicode character in SecondString subtracted from the first - mismatched Unicode character in FirstString. - - @param FirstString A pointer to a Null-terminated Unicode string. - @param SecondString A pointer to a Null-terminated Unicode string. - - @retval 0 FirstString is identical to SecondString. - @return others FirstString is not identical to SecondString. - -**/ -INTN -FceStrCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString - ); - -/** - Concatenates one Null-terminated Unicode string to another Null-terminated - Unicode string, and returns the concatenated Unicode string. - - This function concatenates two Null-terminated Unicode strings. The contents - of Null-terminated Unicode string Source are concatenated to the end of - Null-terminated Unicode string Destination. The Null-terminated concatenated - Unicode String is returned. If Source and Destination overlap, then the - results are undefined. - - If Destination is NULL, then ASSERT(). - If Destination is not aligned on a 16-bit boundary, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source is not aligned on a 16-bit boundary, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Destination contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Source contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination - and Source results in a Unicode string with more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param Destination A pointer to a Null-terminated Unicode string. - @param Source A pointer to a Null-terminated Unicode string. - - @return Destination. - -**/ -CHAR16 * -StrCat ( - IN OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ); - -/** - Returns the first occurrence of a Null-terminated Unicode sub-string - in a Null-terminated Unicode string. - - This function scans the contents of the Null-terminated Unicode string - specified by String and returns the first occurrence of SearchString. - If SearchString is not found in String, then NULL is returned. If - the length of SearchString is zero, then String is - returned. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If SearchString is NULL, then ASSERT(). - If SearchString is not aligned on a 16-bit boundary, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and SearchString - or String contains more than PcdMaximumUnicodeStringLength Unicode - characters, not including the Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - @param SearchString A pointer to a Null-terminated Unicode string to search for. - - @retval NULL If the SearchString does not appear in String. - @return others If there is a match. - -**/ -CHAR16 * -StrStr ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *SearchString - ); - -/** - Convert a Null-terminated Unicode decimal string to a value of - type UINT64. - - This function returns a value of type UINT64 by interpreting the contents - of the Unicode string specified by String as a decimal number. The format - of the input Unicode string String is: - - [spaces] [decimal digits]. - - The valid decimal digit character is in the range [0-9]. The - function will ignore the pad space, which includes spaces or - tab characters, before [decimal digits]. The running zero in the - beginning of [decimal digits] will be ignored. Then, the function - stops at the first character that is a not a valid decimal character - or a Null-terminator, whichever one comes first. - - If String is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If String has only pad spaces, then 0 is returned. - If String has no pad spaces or valid decimal digits, - then 0 is returned. - If the number represented by String overflows according - to the range defined by UINT64, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and String contains - more than PcdMaximumUnicodeStringLength Unicode characters, not including - the Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @retval Value translated from String. - -**/ -UINT64 -FceStrDecimalToUint64 ( - IN CONST CHAR16 *String - ); - - -/** - Convert one Null-terminated ASCII string to a Null-terminated - Unicode string and returns the Unicode string. - - This function converts the contents of the ASCII string Source to the Unicode - string Destination, and returns Destination. The function terminates the - Unicode string Destination by appending a Null-terminator character at the end. - The caller is responsible to make sure Destination points to a buffer with size - equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes. - - @param Source A pointer to a Null-terminated ASCII string. - @param Destination A pointer to a Null-terminated Unicode string. - - @return Destination. - @return NULL If Destination or Source is NULL, return NULL. - -**/ -CHAR16 * -AsciiStrToUnicodeStr ( - IN CONST CHAR8 *Source, - OUT CHAR16 *Destination - ); - -/** - Worker function that produces a Null-terminated string in an output buffer - based on a Null-terminated format string and variable argument list. - - VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this routine allows the nesting of Vararg routines. Thus - this is the main print working routine - - @param StartOfBuffer The character buffer to print the results of the parsing - of Format into. - @param BufferSize The maximum number of characters to put into buffer. - Zero means no limit. - @param Flags Initial flags value. - Can only have FORMAT_UNICODE and OUTPUT_UNICODE set - @param FormatString A Null-terminated format string. - @param ... The variable argument list. - - @return The number of characters printed. - -**/ -UINTN -BasePrintLibSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *FormatString, - ... - ); - -/** - Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated - Unicode format string and variable argument list. - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the format string. - The number of Unicode characters in the produced output buffer is returned not including - the Null-terminator. - If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. - - If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). - If BufferSize > 1 and FormatString is NULL, then ASSERT(). - If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then - ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters not including the - Null-terminator, then ASSERT(). - - @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString A Null-terminated Unicode format string. - @param ... Variable argument list whose contents are accessed based on the - format string specified by FormatString. - - @return The number of Unicode characters in the produced output buffer not including the - Null-terminator. - -**/ -UINTN -UnicodeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ); - -/** - Convert a Null-terminated Unicode string to a Null-terminated - ASCII string and returns the ASCII string. - - This function converts the content of the Unicode string Source - to the ASCII string Destination by copying the lower 8 bits of - each Unicode character. It returns Destination. The function terminates - the ASCII string Destination by appending a Null-terminator character - at the end. The caller is responsible to make sure Destination points - to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source is not aligned on a 16-bit boundary, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - If any Unicode characters in Source contain non-zero value in - the upper 8 bits, then ASSERT(). - - @param Source Pointer to a Null-terminated Unicode string. - @param Destination Pointer to a Null-terminated ASCII string. - - @reture Destination - -**/ -CHAR8 * -UnicodeStrToAsciiStr ( - IN CONST CHAR16 *Source, - OUT CHAR8 *Destination - ); - -/** - Allocate new memory and then copy the Unicode string Source to Destination. - - @param Dest Location to copy string - @param Src String to copy - -**/ -VOID -NewStringCpy ( - IN OUT CHAR16 **Dest, - IN CHAR16 *Src - ); - -/** - Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64. - - This function returns a value of type UINT64 by interpreting the contents - of the Unicode string specified by String as a hexadecimal number. - The format of the input Unicode string String is - - [spaces][zeros][x][hexadecimal digits]. - - The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. - The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. - If "x" appears in the input string, it must be prefixed with at least one 0. - The function will ignore the pad space, which includes spaces or tab characters, - before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or - [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the - first valid hexadecimal digit. Then, the function stops at the first character that is - a not a valid hexadecimal character or NULL, whichever one comes first. - - If String is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If String has only pad spaces, then zero is returned. - If String has no leading pad spaces, leading zeros or valid hexadecimal digits, - then zero is returned. - If the number represented by String overflows according to the range defined by - UINT64, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, - then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @retval Value translated from String. - -**/ -UINT64 -FceStrHexToUint64 ( - IN CONST CHAR16 *String - ); - - -CHAR16 -ToUpper ( - CHAR16 a - ); - -CHAR16 -ToLower ( - CHAR16 a - ); - -/** - Performs a case-insensitive comparison between a Null-terminated - Unicode pattern string and a Null-terminated Unicode string. - - @param String - A pointer to a Null-terminated Unicode string. - @param Pattern - A pointer to a Null-terminated Unicode pattern string. - - - @retval TRUE - Pattern was found in String. - @retval FALSE - Pattern was not found in String. - -**/ -BOOLEAN -MetaiMatch ( - IN CHAR16 *String, - IN CHAR16 *Pattern - ); - -/** - Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and - generates a 64-bit unsigned result. - - This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit - unsigned value Multiplier and generates a 64-bit unsigned result. This 64- - bit unsigned result is returned. - - @param Multiplicand A 64-bit unsigned value. - @param Multiplier A 32-bit unsigned value. - - @return Multiplicand * Multiplier. - -**/ -UINT64 -MultU64x32 ( - IN UINT64 Multiplicand, - IN UINT32 Multiplier - ); - -/** - Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates - a 64-bit unsigned result. - - This function divides the 64-bit unsigned value Dividend by the 32-bit - unsigned value Divisor and generates a 64-bit unsigned quotient. This - function returns the 64-bit unsigned quotient. - - If Divisor is 0, then ASSERT(). - - @param Dividend A 64-bit unsigned value. - @param Divisor A 32-bit unsigned value. - - @return Dividend / Divisor - -**/ -UINT64 -DivU64x32 ( - IN UINT64 Dividend, - IN UINT32 Divisor - ); - -/** - Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled - with zeros. The shifted value is returned. - - This function shifts the 64-bit value Operand to the left by Count bits. The - low Count bits are set to zero. The shifted value is returned. - - If Count is greater than 63, then ASSERT(). - - @param Operand The 64-bit operand to shift left. - @param Count The number of bits to shift left. - - @return Operand << Count. - -**/ -UINT64 -LShiftU64 ( - IN UINT64 Operand, - IN UINTN Count - ); - -/** - Shifts a 64-bit integer right between 0 and 63 bits. This high bits are - filled with zeros. The shifted value is returned. - - This function shifts the 64-bit value Operand to the right by Count bits. The - high Count bits are set to zero. The shifted value is returned. - - If Count is greater than 63, then ASSERT(). - - @param Operand The 64-bit operand to shift right. - @param Count The number of bits to shift right. - - @return Operand >> Count. - -**/ -UINT64 -RShiftU64 ( - IN UINT64 Operand, - IN UINTN Count - ); - - -/** - Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates - a 64-bit unsigned result and an optional 32-bit unsigned remainder. - - This function divides the 64-bit unsigned value Dividend by the 32-bit - unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder - is not NULL, then the 32-bit unsigned remainder is returned in Remainder. - This function returns the 64-bit unsigned quotient. - - If Divisor is 0, then ASSERT(). - - @param Dividend A 64-bit unsigned value. - @param Divisor A 32-bit unsigned value. - @param Remainder A pointer to a 32-bit unsigned value. This parameter is - optional and may be NULL. - - @return Dividend / Divisor - -**/ -UINT64 -DivU64x32Remainder ( - IN UINT64 Dividend, - IN UINT32 Divisor, - OUT UINT32 *Remainder - ); - -/** - Copies a buffer to an allocated buffer. - - Allocates the number bytes specified by AllocationSize, copies allocationSize bytes - from Buffer to the newly allocated buffer, and returns a pointer to the allocated - buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -FceAllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ); - -/** - Initializes the head node of a doubly-linked list, and returns the pointer to - the head node of the doubly-linked list. - - Initializes the forward and backward links of a new linked list. After - initializing a linked list with this function, the other linked list - functions may be used to add and remove nodes from the linked list. It is up - to the caller of this function to allocate the memory for ListHead. - - If ListHead is NULL, then ASSERT(). - - @param ListHead A pointer to the head node of a new doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InitializeListHead ( - IN OUT LIST_ENTRY *ListHead - ); - -/** - Adds a node to the beginning of a doubly-linked list, and returns the pointer - to the head node of the doubly-linked list. - - Adds the node Entry at the beginning of the doubly-linked list denoted by - ListHead, and returns ListHead. - - If ListHead is NULL, then ASSERT(). - If Entry is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number - of nodes in ListHead, including the ListHead node, is greater than or - equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - @param Entry A pointer to a node that is to be inserted at the beginning - of a doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InsertHeadList ( - IN OUT LIST_ENTRY *ListHead, - IN OUT LIST_ENTRY *Entry - ); - -/** - Adds a node to the end of a doubly-linked list, and returns the pointer to - the head node of the doubly-linked list. - - Adds the node Entry to the end of the doubly-linked list denoted by ListHead, - and returns ListHead. - - If ListHead is NULL, then ASSERT(). - If Entry is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number - of nodes in ListHead, including the ListHead node, is greater than or - equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - @param Entry A pointer to a node that is to be added at the end of the - doubly-linked list. - - @return ListHead - -**/ -LIST_ENTRY * -InsertTailList ( - IN OUT LIST_ENTRY *ListHead, - IN OUT LIST_ENTRY *Entry - ); - -/** - Retrieves the first node of a doubly-linked list. - - Returns the first node of a doubly-linked list. List must have been - initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - - @return The first node of a doubly-linked list. - @retval NULL The list is empty. - -**/ -LIST_ENTRY * -GetFirstNode ( - IN CONST LIST_ENTRY *List - ); - -/** - Retrieves the next node of a doubly-linked list. - - Returns the node of a doubly-linked list that follows Node. - List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() - or InitializeListHead(). If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and List contains more than - PcdMaximumLinkedListLenth nodes, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @return A pointer to the next node if one exists. Otherwise List is returned. - -**/ -LIST_ENTRY * -GetNextNode ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ); - -/** - Retrieves the previous node of a doubly-linked list. - - Returns the node of a doubly-linked list that precedes Node. - List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() - or InitializeListHead(). If List is empty, then List is returned. - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and List contains more than - PcdMaximumLinkedListLenth nodes, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @return A pointer to the previous node if one exists. Otherwise List is returned. - -**/ -LIST_ENTRY * -GetPreviousNode ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ); - -/** - Checks to see if a doubly-linked list is empty or not. - - Checks to see if the doubly-linked list is empty. If the linked list contains - zero nodes, this function returns TRUE. Otherwise, it returns FALSE. - - If ListHead is NULL, then ASSERT(). - If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - - @param ListHead A pointer to the head node of a doubly-linked list. - - @retval TRUE The linked list is empty. - @retval FALSE The linked list is not empty. - -**/ -BOOLEAN -IsListEmpty ( - IN CONST LIST_ENTRY *ListHead - ); - -/** - Determines if a node in a doubly-linked list is the head node of a the same - doubly-linked list. This function is typically used to terminate a loop that - traverses all the nodes in a doubly-linked list starting with the head node. - - Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the - nodes in the doubly-linked list specified by List. List must have been - initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(), - then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not - equal to List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @retval TRUE Node is the head of the doubly-linked list pointed by List. - @retval FALSE Node is not the head of the doubly-linked list pointed by List. - -**/ -BOOLEAN -IsNull ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ); - -/** - Determines if a node the last node in a doubly-linked list. - - Returns TRUE if Node is the last node in the doubly-linked list specified by - List. Otherwise, FALSE is returned. List must have been initialized with - INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). - - If List is NULL, then ASSERT(). - If Node is NULL, then ASSERT(). - If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or - InitializeListHead(), then ASSERT(). - If PcdMaximumLinkedListLenth is not zero, and the number of nodes - in List, including the List node, is greater than or equal to - PcdMaximumLinkedListLength, then ASSERT(). - If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). - - @param List A pointer to the head node of a doubly-linked list. - @param Node A pointer to a node in the doubly-linked list. - - @retval TRUE Node is the last node in the linked list. - @retval FALSE Node is not the last node in the linked list. - -**/ -BOOLEAN -IsNodeAtEnd ( - IN CONST LIST_ENTRY *List, - IN CONST LIST_ENTRY *Node - ); - -/** - Removes a node from a doubly-linked list, and returns the node that follows - the removed node. - - Removes the node Entry from a doubly-linked list. It is up to the caller of - this function to release the memory used by this node if that is required. On - exit, the node following Entry in the doubly-linked list is returned. If - Entry is the only node in the linked list, then the head node of the linked - list is returned. - - If Entry is NULL, then ASSERT(). - If Entry is the head node of an empty list, then ASSERT(). - If PcdMaximumLinkedListLength is not zero, and the number of nodes in the - linked list containing Entry, including the Entry node, is greater than - or equal to PcdMaximumLinkedListLength, then ASSERT(). - - @param Entry A pointer to a node in a linked list. - - @return Entry. - -**/ -LIST_ENTRY * -RemoveEntryList ( - IN CONST LIST_ENTRY *Entry - ); - -#endif diff --git a/BaseTools/Source/C/FCE/Expression.c b/BaseTools/Source/C/FCE/Expression.c deleted file mode 100644 index 34b310d97f..0000000000 --- a/BaseTools/Source/C/FCE/Expression.c +++ /dev/null @@ -1,2367 +0,0 @@ -/** @file - - Utility functions for expression evaluation. - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "IfrParse.h" - -#define gEmptyString L"" -// -// Global stack used to evaluate boolean expresions -// -EFI_HII_VALUE *mOpCodeScopeStack = NULL; -EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL; -EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL; - -EFI_HII_VALUE *mExpressionEvaluationStack = NULL; -EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL; -EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL; -UINTN mExpressionEvaluationStackOffset = 0; - -EFI_HII_VALUE *mCurrentExpressionStack = NULL; -EFI_HII_VALUE *mCurrentExpressionEnd = NULL; -EFI_HII_VALUE *mCurrentExpressionPointer = NULL; - -EFI_HII_VALUE *mMapExpressionListStack = NULL; -EFI_HII_VALUE *mMapExpressionListEnd = NULL; -EFI_HII_VALUE *mMapExpressionListPointer = NULL; - -/** - Get Value for given Name from a NameValue Storage. - - @param Storage The NameValue Storage. - @param Name The Name. - @param Value The retured Value. - - @retval EFI_SUCCESS Value found for given Name. - @retval EFI_NOT_FOUND No such Name found in NameValue storage. - -**/ -EFI_STATUS -GetValueByName ( - IN FORMSET_STORAGE *Storage, - IN CHAR16 *Name, - IN OUT CHAR16 **Value - ) -{ - LIST_ENTRY *Link; - NAME_VALUE_NODE *Node; - - *Value = NULL; - - Link = GetFirstNode (&Storage->NameValueListHead); - while (!IsNull (&Storage->NameValueListHead, Link)) { - Node = NAME_VALUE_NODE_FROM_LINK (Link); - - if (FceStrCmp (Name, Node->Name) == 0) { - NewStringCpy (Value, Node->EditValue); - return EFI_SUCCESS; - } - - Link = GetNextNode (&Storage->NameValueListHead, Link); - } - - return EFI_NOT_FOUND; -} - -/** - Grow size of the stack. - - This is an internal function. - - @param Stack On input: old stack; On output: new stack - @param StackPtr On input: old stack pointer; On output: new stack - pointer - @param StackEnd On input: old stack end; On output: new stack end - - @retval EFI_SUCCESS Grow stack success. - @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. - -**/ -EFI_STATUS -GrowStack ( - IN OUT EFI_HII_VALUE **Stack, - IN OUT EFI_HII_VALUE **StackPtr, - IN OUT EFI_HII_VALUE **StackEnd - ) -{ - UINTN Size; - EFI_HII_VALUE *NewStack; - - Size = EXPRESSION_STACK_SIZE_INCREMENT; - if (*StackPtr != NULL) { - Size = Size + (*StackEnd - *Stack); - } - - NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE)); - if (NewStack == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (*StackPtr != NULL) { - // - // Copy from Old Stack to the New Stack - // - CopyMem ( - NewStack, - *Stack, - (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE) - ); - - // - // Free The Old Stack - // - FreePool (*Stack); - } - - // - // Make the Stack pointer point to the old data in the new stack - // - *StackPtr = NewStack + (*StackPtr - *Stack); - *Stack = NewStack; - *StackEnd = NewStack + Size; - - return EFI_SUCCESS; -} - - -/** - Push an element onto the Boolean Stack. - - @param Stack On input: old stack; On output: new stack - @param StackPtr On input: old stack pointer; On output: new stack - pointer - @param StackEnd On input: old stack end; On output: new stack end - @param Data Data to push. - - @retval EFI_SUCCESS Push stack success. - -**/ -EFI_STATUS -PushStack ( - IN OUT EFI_HII_VALUE **Stack, - IN OUT EFI_HII_VALUE **StackPtr, - IN OUT EFI_HII_VALUE **StackEnd, - IN EFI_HII_VALUE *Data - ) -{ - EFI_STATUS Status; - - // - // Check for a stack overflow condition - // - if (*StackPtr >= *StackEnd) { - // - // Grow the stack - // - Status = GrowStack (Stack, StackPtr, StackEnd); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Push the item onto the stack - // - CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE)); - *StackPtr = *StackPtr + 1; - - return EFI_SUCCESS; -} - - -/** - Pop an element from the stack. - - @param Stack On input: old stack - @param StackPtr On input: old stack pointer; On output: new stack pointer - @param Data Data to pop. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack - -**/ -EFI_STATUS -PopStack ( - IN EFI_HII_VALUE *Stack, - IN OUT EFI_HII_VALUE **StackPtr, - OUT EFI_HII_VALUE *Data - ) -{ - // - // Check for a stack underflow condition - // - if (*StackPtr == Stack) { - return EFI_ACCESS_DENIED; - } - - // - // Pop the item off the stack - // - *StackPtr = *StackPtr - 1; - CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE)); - return EFI_SUCCESS; -} - - -/** - Reset stack pointer to begin of the stack. - -**/ -VOID -ResetCurrentExpressionStack ( - VOID - ) -{ - mCurrentExpressionPointer = mCurrentExpressionStack; -} - - -/** - Push current expression onto the Stack - - @param Pointer Pointer to current expression. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PushCurrentExpression ( - IN VOID *Pointer - ) -{ - EFI_HII_VALUE Data; - - Data.Type = EFI_IFR_TYPE_NUM_SIZE_64; - Data.Value.u64 = (UINT64) (UINTN) Pointer; - - return PushStack ( - &mCurrentExpressionStack, - &mCurrentExpressionPointer, - &mCurrentExpressionEnd, - &Data - ); -} - - -/** - Pop current expression from the Stack - - @param Pointer Pointer to current expression to be pop. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PopCurrentExpression ( - OUT VOID **Pointer - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Data; - - Status = PopStack ( - mCurrentExpressionStack, - &mCurrentExpressionPointer, - &Data - ); - - *Pointer = (VOID *) (UINTN) Data.Value.u64; - - return Status; -} - -/** - Reset stack pointer to begin of the stack. - -**/ -VOID -ResetMapExpressionListStack ( - VOID - ) -{ - mMapExpressionListPointer = mMapExpressionListStack; -} - - -/** - Push the list of map expression onto the Stack - - @param Pointer Pointer to the list of map expression to be pushed. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PushMapExpressionList ( - IN VOID *Pointer - ) -{ - EFI_HII_VALUE Data; - - Data.Type = EFI_IFR_TYPE_NUM_SIZE_64; - Data.Value.u64 = (UINT64) (UINTN) Pointer; - - return PushStack ( - &mMapExpressionListStack, - &mMapExpressionListPointer, - &mMapExpressionListEnd, - &Data - ); -} - - -/** - Pop the list of map expression from the Stack - - @param Pointer Pointer to the list of map expression to be pop. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PopMapExpressionList ( - OUT VOID **Pointer - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Data; - - Status = PopStack ( - mMapExpressionListStack, - &mMapExpressionListPointer, - &Data - ); - - *Pointer = (VOID *) (UINTN) Data.Value.u64; - - return Status; -} - -/** - Reset stack pointer to begin of the stack. - -**/ -VOID -ResetScopeStack ( - VOID - ) -{ - mOpCodeScopeStackPointer = mOpCodeScopeStack; -} - - -/** - Push an Operand onto the Stack - - @param Operand Operand to push. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the - stack. - -**/ -EFI_STATUS -PushScope ( - IN UINT8 Operand - ) -{ - EFI_HII_VALUE Data; - - Data.Type = EFI_IFR_TYPE_NUM_SIZE_8; - Data.Value.u8 = Operand; - - return PushStack ( - &mOpCodeScopeStack, - &mOpCodeScopeStackPointer, - &mOpCodeScopeStackEnd, - &Data - ); -} - - -/** - Pop an Operand from the Stack - - @param Operand Operand to pop. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the - stack. - -**/ -EFI_STATUS -PopScope ( - OUT UINT8 *Operand - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Data; - - Status = PopStack ( - mOpCodeScopeStack, - &mOpCodeScopeStackPointer, - &Data - ); - - *Operand = Data.Value.u8; - - return Status; -} - - -/** - Push an Expression value onto the Stack - - @param Value Expression value to push. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the - stack. - -**/ -EFI_STATUS -PushExpression ( - IN EFI_HII_VALUE *Value - ) -{ - return PushStack ( - &mExpressionEvaluationStack, - &mExpressionEvaluationStackPointer, - &mExpressionEvaluationStackEnd, - Value - ); -} - - -/** - Pop an Expression value from the stack. - - @param Value Expression value to pop. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack - -**/ -EFI_STATUS -PopExpression ( - OUT EFI_HII_VALUE *Value - ) -{ - return PopStack ( - mExpressionEvaluationStack + mExpressionEvaluationStackOffset, - &mExpressionEvaluationStackPointer, - Value - ); -} - -/** - Get current stack offset from stack start. - - @return Stack offset to stack start. -**/ -UINTN -SaveExpressionEvaluationStackOffset ( - ) -{ - UINTN TempStackOffset; - TempStackOffset = mExpressionEvaluationStackOffset; - mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack; - return TempStackOffset; -} - -/** - Restore stack offset based on input stack offset - - @param StackOffset Offset to stack start. - -**/ -VOID -RestoreExpressionEvaluationStackOffset ( - UINTN StackOffset - ) -{ - mExpressionEvaluationStackOffset = StackOffset; -} - - -/** - Search a Question in Form scope using its QuestionId. - - @param Form The form which contains this Question. - @param QuestionId Id of this Question. - - @retval Pointer The Question. - @retval NULL Specified Question not found in the form. - -**/ -FORM_BROWSER_STATEMENT * -IdToQuestion2 ( - IN FORM_BROWSER_FORM *Form, - IN UINT16 QuestionId - ) -{ - LIST_ENTRY *Link; - FORM_BROWSER_STATEMENT *Question; - - if (QuestionId == 0) { - // - // The value of zero is reserved - // - return NULL; - } - - Link = GetFirstNode (&Form->StatementListHead); - while (!IsNull (&Form->StatementListHead, Link)) { - Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link); - - if (Question->QuestionId == QuestionId) { - return Question; - } - - Link = GetNextNode (&Form->StatementListHead, Link); - } - - return NULL; -} - - -/** - Search a Question in Formset scope using its QuestionId. - - @param FormSet The formset which contains this form. - @param Form The form which contains this Question. - @param QuestionId Id of this Question. - - @retval Pointer The Question. - @retval NULL Specified Question not found in the form. - -**/ -FORM_BROWSER_STATEMENT * -IdToQuestion ( - IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_FORM *Form, - IN UINT16 QuestionId - ) -{ - LIST_ENTRY *Link; - FORM_BROWSER_STATEMENT *Question; - - // - // Search in the form scope first - // - Question = IdToQuestion2 (Form, QuestionId); - if (Question != NULL) { - return Question; - } - - // - // Search in the formset scope - // - Link = GetFirstNode (&FormSet->FormListHead); - while (!IsNull (&FormSet->FormListHead, Link)) { - Form = FORM_BROWSER_FORM_FROM_LINK (Link); - - Question = IdToQuestion2 (Form, QuestionId); - if (Question != NULL) { - return Question; - } - - Link = GetNextNode (&FormSet->FormListHead, Link); - } - - return NULL; -} - - -/** - Get Expression given its RuleId. - - @param Form The form which contains this Expression. - @param RuleId Id of this Expression. - - @retval Pointer The Expression. - @retval NULL Specified Expression not found in the form. - -**/ -FORM_EXPRESSION * -RuleIdToExpression ( - IN FORM_BROWSER_FORM *Form, - IN UINT8 RuleId - ) -{ - LIST_ENTRY *Link; - FORM_EXPRESSION *Expression; - - Link = GetFirstNode (&Form->ExpressionListHead); - while (!IsNull (&Form->ExpressionListHead, Link)) { - Expression = FORM_EXPRESSION_FROM_LINK (Link); - - if ((Expression->Type == EFI_HII_EXPRESSION_RULE) && (Expression->RuleId == RuleId)) { - return Expression; - } - - Link = GetNextNode (&Form->ExpressionListHead, Link); - } - - return NULL; -} - -/** - Convert the input Unicode character to upper. - - @param String Th Unicode character to be converted. - -**/ -VOID -IfrStrToUpper ( - IN CHAR16 *String - ) -{ - while (*String != 0) { - if ((*String >= 'a') && (*String <= 'z')) { - *String = (UINT16) ((*String) & ((UINT16) ~0x20)); - } - String++; - } -} - -/** - Evaluate opcode EFI_IFR_TO_STRING. - - @param FormSet Formset which contains this opcode. - @param Format String format in EFI_IFR_TO_STRING. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrToString ( - IN FORM_BROWSER_FORMSET *FormSet, - IN UINT8 Format, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *PrintFormat; - CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS]; - UINTN BufferSize; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - - switch (Value.Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - case EFI_IFR_TYPE_NUM_SIZE_16: - case EFI_IFR_TYPE_NUM_SIZE_32: - case EFI_IFR_TYPE_NUM_SIZE_64: - BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16); - switch (Format) { - case EFI_IFR_STRING_UNSIGNED_DEC: - case EFI_IFR_STRING_SIGNED_DEC: - PrintFormat = L"%ld"; - break; - - case EFI_IFR_STRING_LOWERCASE_HEX: - PrintFormat = L"%lx"; - break; - - case EFI_IFR_STRING_UPPERCASE_HEX: - PrintFormat = L"%lX"; - break; - - default: - return EFI_UNSUPPORTED; - } - UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64); - break; - - case EFI_IFR_TYPE_STRING: - CopyMem (Result, &Value, sizeof (EFI_HII_VALUE)); - return EFI_SUCCESS; - - case EFI_IFR_TYPE_BOOLEAN: - break; - - default: - return EFI_UNSUPPORTED; - } - - Result->Type = EFI_IFR_TYPE_STRING; - //Result->Value.string = NewString (String, FormSet->HiiHandle); - return EFI_SUCCESS; -} - -/** - Evaluate opcode EFI_IFR_TO_UINT. - - @param FormSet Formset which contains this opcode. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrToUint ( - IN FORM_BROWSER_FORMSET *FormSet, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String; - CHAR16 *StringPtr; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Value.Type >= EFI_IFR_TYPE_OTHER) { - return EFI_UNSUPPORTED; - } - - Status = EFI_SUCCESS; - if (Value.Type == EFI_IFR_TYPE_STRING) { - String = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String == NULL) { - return EFI_NOT_FOUND; - } - - IfrStrToUpper (String); - StringPtr = StrStr (String, L"0X"); - if (StringPtr != NULL) { - // - // Hex string - // - Result->Value.u64 = FceStrHexToUint64 (String); - } else { - // - // decimal string - // - Result->Value.u64 = FceStrDecimalToUint64 (String); - } - FreePool (String); - } else { - CopyMem (Result, &Value, sizeof (EFI_HII_VALUE)); - } - - Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; - return Status; -} - -/** - Evaluate opcode EFI_IFR_CATENATE. - - @param FormSet Formset which contains this opcode. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrCatenate ( - IN FORM_BROWSER_FORMSET *FormSet, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String[2]; - UINTN Index; - CHAR16 *StringPtr; - UINTN Size; - - // - // String[0] - The second string - // String[1] - The first string - // - String[0] = NULL; - String[1] = NULL; - StringPtr = NULL; - Status = EFI_SUCCESS; - - for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value.Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String[Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - } - - Size = FceStrSize (String[0]); - StringPtr= AllocatePool (FceStrSize (String[1]) + Size); - ASSERT (StringPtr != NULL); - StrCpy (StringPtr, String[1]); - StrCat (StringPtr, String[0]); - - Result->Type = EFI_IFR_TYPE_STRING; - //Result->Value.string = NewString (StringPtr, FormSet->HiiHandle); - -Done: - if (String[0] != NULL) { - FreePool (String[0]); - } - if (String[1] != NULL) { - FreePool (String[1]); - } - if (StringPtr != NULL) { - FreePool (StringPtr); - } - - return Status; -} - -/** - Evaluate opcode EFI_IFR_MATCH. - - @param FormSet Formset which contains this opcode. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrMatch ( - IN FORM_BROWSER_FORMSET *FormSet, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String[2]; - UINTN Index; - - // - // String[0] - The string to search - // String[1] - pattern - // - String[0] = NULL; - String[1] = NULL; - Status = EFI_SUCCESS; - for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value.Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String [Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - } - - Result->Type = EFI_IFR_TYPE_BOOLEAN; - Result->Value.b = MetaiMatch (String[0], String[1]); - -Done: - if (String[0] != NULL) { - FreePool (String[0]); - } - if (String[1] != NULL) { - FreePool (String[1]); - } - - return Status; -} - - -/** - Evaluate opcode EFI_IFR_FIND. - - @param FormSet Formset which contains this opcode. - @param Format Case sensitive or insensitive. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrFind ( - IN FORM_BROWSER_FORMSET *FormSet, - IN UINT8 Format, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String[2]; - UINTN Base; - CHAR16 *StringPtr; - UINTN Index; - - if (Format > EFI_IFR_FF_CASE_INSENSITIVE) { - return EFI_UNSUPPORTED; - } - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; - } - Base = (UINTN) Value.Value.u64; - - // - // String[0] - sub-string - // String[1] - The string to search - // - String[0] = NULL; - String[1] = NULL; - for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value.Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String[Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - if (Format == EFI_IFR_FF_CASE_INSENSITIVE) { - // - // Case insensitive, convert both string to upper case - // - IfrStrToUpper (String[Index]); - } - } - - Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; - if (Base >= FceStrLen (String[1])) { - Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL; - } else { - StringPtr = StrStr (String[1] + Base, String[0]); - Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]); - } - -Done: - if (String[0] != NULL) { - FreePool (String[0]); - } - if (String[1] != NULL) { - FreePool (String[1]); - } - - return Status; -} - - -/** - Evaluate opcode EFI_IFR_MID. - - @param FormSet Formset which contains this opcode. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrMid ( - IN FORM_BROWSER_FORMSET *FormSet, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String; - UINTN Base; - UINTN Length; - CHAR16 *SubString; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; - } - Length = (UINTN) Value.Value.u64; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; - } - Base = (UINTN) Value.Value.u64; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type != EFI_IFR_TYPE_STRING) { - return EFI_UNSUPPORTED; - } - String = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String == NULL) { - return EFI_NOT_FOUND; - } - - if ((Length == 0) || (Base >= FceStrLen (String))) { - SubString = gEmptyString; - } else { - SubString = String + Base; - if ((Base + Length) < FceStrLen (String)) { - SubString[Length] = L'\0'; - } - } - - Result->Type = EFI_IFR_TYPE_STRING; - //Result->Value.string = NewString (SubString, FormSet->HiiHandle); - - FreePool (String); - - return Status; -} - -/** - Evaluate opcode EFI_IFR_TOKEN. - - @param FormSet Formset which contains this opcode. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrToken ( - IN FORM_BROWSER_FORMSET *FormSet, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String[2]; - UINTN Count; - CHAR16 *Delimiter; - CHAR16 *SubString; - CHAR16 *StringPtr; - UINTN Index; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; - } - Count = (UINTN) Value.Value.u64; - - // - // String[0] - Delimiter - // String[1] - The string to search - // - String[0] = NULL; - String[1] = NULL; - for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value.Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String[Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - } - - Delimiter = String[0]; - SubString = String[1]; - while (Count > 0) { - SubString = StrStr (SubString, Delimiter); - if (SubString != NULL) { - // - // Skip over the delimiter - // - SubString = SubString + FceStrLen (Delimiter); - } else { - break; - } - Count--; - } - - if (SubString == NULL) { - // - // nth delimited sub-string not found, push an empty string - // - SubString = gEmptyString; - } else { - // - // Put a NULL terminator for nth delimited sub-string - // - StringPtr = StrStr (SubString, Delimiter); - if (StringPtr != NULL) { - *StringPtr = L'\0'; - } - } - - Result->Type = EFI_IFR_TYPE_STRING; - //Result->Value.string = NewString (SubString, FormSet->HiiHandle); - -Done: - if (String[0] != NULL) { - FreePool (String[0]); - } - if (String[1] != NULL) { - FreePool (String[1]); - } - - return Status; -} - - -/** - Evaluate opcode EFI_IFR_SPAN. - - @param FormSet Formset which contains this opcode. - @param Flags FIRST_MATCHING or FIRST_NON_MATCHING. - @param Result Evaluation result for this opcode. - - @retval EFI_SUCCESS Opcode evaluation success. - @retval Other Opcode evaluation failed. - -**/ -EFI_STATUS -IfrSpan ( - IN FORM_BROWSER_FORMSET *FormSet, - IN UINT8 Flags, - OUT EFI_HII_VALUE *Result - ) -{ - EFI_STATUS Status; - EFI_HII_VALUE Value; - CHAR16 *String[2]; - CHAR16 *Charset; - UINTN Base; - UINTN Index; - CHAR16 *StringPtr; - BOOLEAN Found; - - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - return Status; - } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; - } - Base = (UINTN) Value.Value.u64; - - // - // String[0] - Charset - // String[1] - The string to search - // - String[0] = NULL; - String[1] = NULL; - for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value.Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary); - if (String [Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - } - - if (Base >= FceStrLen (String[1])) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - Found = FALSE; - StringPtr = String[1] + Base; - Charset = String[0]; - while (*StringPtr != 0 && !Found) { - Index = 0; - while (Charset[Index] != 0) { - if ((*StringPtr >= Charset[Index]) && (*StringPtr <= Charset[Index + 1])) { - if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) { - Found = TRUE; - break; - } - } else { - if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) { - Found = TRUE; - break; - } - } - // - // Skip characters pair representing low-end of a range and high-end of a range - // - Index += 2; - } - - if (!Found) { - StringPtr++; - } - } - - Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; - Result->Value.u64 = StringPtr - String[1]; - -Done: - if (String[0] != NULL) { - FreePool (String[0]); - } - if (String[1] != NULL) { - FreePool (String[1]); - } - - return Status; -} - - -/** - Zero extend integer/boolean/date/time to UINT64 for comparing. - - @param Value HII Value to be converted. - -**/ -VOID -ExtendValueToU64 ( - IN EFI_HII_VALUE *Value - ) -{ - UINT64 Temp; - - Temp = 0; - switch (Value->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - Temp = Value->Value.u8; - break; - - case EFI_IFR_TYPE_NUM_SIZE_16: - Temp = Value->Value.u16; - break; - - case EFI_IFR_TYPE_NUM_SIZE_32: - Temp = Value->Value.u32; - break; - - case EFI_IFR_TYPE_BOOLEAN: - Temp = Value->Value.b; - break; - - case EFI_IFR_TYPE_TIME: - Temp = Value->Value.u32 & 0xffffff; - break; - - case EFI_IFR_TYPE_DATE: - Temp = Value->Value.u32; - break; - - default: - return; - } - - Value->Value.u64 = Temp; -} - - -/** - Compare two Hii value. - - @param Value1 Expression value to compare on left-hand. - @param Value2 Expression value to compare on right-hand. - @param FormSet The pointer to the Formset. - - @retval EFI_INVALID_PARAMETER Could not perform compare on two values. - @retval 0 Two operators equal. - @return Positive value if Value1 is greater than Value2. - @retval Negative value if Value1 is less than Value2. - -**/ -INTN -CompareHiiValue ( - IN EFI_HII_VALUE *Value1, - IN EFI_HII_VALUE *Value2, - IN FORM_BROWSER_FORMSET *FormSet - ) -{ - INTN Result; - INT64 Temp64; - CHAR16 *Str1; - CHAR16 *Str2; - - if ((Value1->Type >= EFI_IFR_TYPE_OTHER) || (Value2->Type >= EFI_IFR_TYPE_OTHER) ) { - return EFI_INVALID_PARAMETER; - } - - if ((Value1->Type == EFI_IFR_TYPE_STRING) || (Value2->Type == EFI_IFR_TYPE_STRING) ) { - if (Value1->Type != Value2->Type) { - // - // Both Operator should be type of String - // - return EFI_INVALID_PARAMETER; - } - - if ((Value1->Value.string == 0) || (Value2->Value.string == 0)) { - // - // StringId 0 is reserved - // - return EFI_INVALID_PARAMETER; - } - - if (Value1->Value.string == Value2->Value.string) { - return 0; - } - - Str1 = GetToken (Value1->Value.string, FormSet->UnicodeBinary); - if (Str1 == NULL) { - // - // String not found - // - return EFI_INVALID_PARAMETER; - } - - Str2 = GetToken (Value2->Value.string, FormSet->UnicodeBinary); - if (Str2 == NULL) { - FreePool (Str1); - return EFI_INVALID_PARAMETER; - } - - Result = FceStrCmp (Str1, Str2); - - FreePool (Str1); - FreePool (Str2); - - return Result; - } - - // - // Take remain types(integer, boolean, date/time) as integer - // - Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64); - if (Temp64 > 0) { - Result = 1; - } else if (Temp64 < 0) { - Result = -1; - } else { - Result = 0; - } - - return Result; -} - -/** - Tell whether this Operand is an constant Expression or not - - @param Operand Operand of an IFR OpCode. - - @retval TRUE This is an Expression OpCode. - @retval FALSE Not an Expression OpCode. - -**/ -BOOLEAN -IsConstantExpressionOpCode ( - IN UINT8 Operand - ) -{ - if ((Operand == EFI_IFR_EQ_ID_VAL_OP) || - (Operand == EFI_IFR_EQ_ID_ID_OP) || - (Operand == EFI_IFR_EQ_ID_VAL_LIST_OP )|| - (Operand == EFI_IFR_QUESTION_REF1_OP) || - (Operand == EFI_IFR_QUESTION_REF2_OP) || - (Operand == EFI_IFR_QUESTION_REF3_OP) || - (Operand == EFI_IFR_THIS_OP ) || - (Operand == EFI_IFR_SECURITY_OP) || - (Operand == EFI_IFR_GET_OP) || - (Operand == EFI_IFR_SET_OP) - ) { - return FALSE; - } else { - return TRUE; - } -} - -/** - Update the HiiValue of question from its variable. - - @param FormSet FormSet associated with this expression. - @param Question The pointer to the Question - - @return EFI_SUCCESS - @return EFI_NOT_FOUND -**/ -EFI_STATUS -UpdateHiiValue ( - IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_STATEMENT *Question - ) -{ - EFI_STATUS Status; - FORMSET_STORAGE *VarList; - UINT8 *VarBuffer; - EFI_HII_VALUE *HiiValue; - - Status = EFI_SUCCESS; - HiiValue = &Question->HiiValue; - - Status = SearchVarStorage ( - Question, - NULL, - Question->VarStoreInfo.VarOffset, - FormSet->StorageListHead, - (CHAR8 **)&VarBuffer, - &VarList - ); - if (EFI_ERROR(Status)) { - return Status; - } - if (Question->QuestionReferToBitField) { - GetBitsQuestionValue (Question, VarBuffer, &HiiValue->Value.u32); - } else { - CopyMem (&HiiValue->Value.u64, VarBuffer, Question->StorageWidth); - } - return Status; -} -/** - Evaluate the result of a HII expression. - - If Expression is NULL, then ASSERT. - - @param FormSet FormSet associated with this expression. - @param Form Form associated with this expression. - @param Expression Expression to be evaluated. - @param ConstantExpression The pointer to the flag of constant expression. If constant, will return TRUE. - - @retval EFI_SUCCESS The expression evaluated successfuly - @retval EFI_NOT_FOUND The Question which referenced by a QuestionId - could not be found. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the - stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack - @retval EFI_INVALID_PARAMETER Syntax error with the Expression - -**/ -EFI_STATUS -EvaluateExpression ( - IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_FORM *Form, - IN OUT FORM_EXPRESSION *Expression, - IN OUT BOOLEAN *ConstantExpression - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - EXPRESSION_OPCODE *OpCode; - FORM_BROWSER_STATEMENT *Question; - FORM_BROWSER_STATEMENT *Question2; - UINT16 Index; - EFI_HII_VALUE Data1; - EFI_HII_VALUE Data2; - EFI_HII_VALUE Data3; - FORM_EXPRESSION *RuleExpression; - EFI_HII_VALUE *Value; - INTN Result; - CHAR16 *StrPtr; - UINT32 TempValue; - LIST_ENTRY *SubExpressionLink; - FORM_EXPRESSION *SubExpression; - UINTN StackOffset; - UINTN TempLength; - CHAR16 TempStr[5]; - UINT8 DigitUint8; - UINT8 *TempBuffer; - - // - // Save current stack offset. - // - StackOffset = SaveExpressionEvaluationStackOffset (); - - ASSERT (Expression != NULL); - Expression->Result.Type = EFI_IFR_TYPE_OTHER; - - Link = GetFirstNode (&Expression->OpCodeListHead); - while (!IsNull (&Expression->OpCodeListHead, Link)) { - OpCode = EXPRESSION_OPCODE_FROM_LINK (Link); - - Link = GetNextNode (&Expression->OpCodeListHead, Link); - - ZeroMem (&Data1, sizeof (EFI_HII_VALUE)); - ZeroMem (&Data2, sizeof (EFI_HII_VALUE)); - ZeroMem (&Data3, sizeof (EFI_HII_VALUE)); - - Value = &Data3; - Value->Type = EFI_IFR_TYPE_BOOLEAN; - Status = EFI_SUCCESS; - - // - // Check whether it is a constant expression or not - // - if (*ConstantExpression) { - *ConstantExpression = IsConstantExpressionOpCode (OpCode->Operand); - } - - switch (OpCode->Operand) { - // - // Built-in functions - // - case EFI_IFR_EQ_ID_VAL_OP: - Question = IdToQuestion (FormSet, Form, OpCode->QuestionId); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - UpdateHiiValue (FormSet, Question); - Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, FormSet); - if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE); - break; - - case EFI_IFR_EQ_ID_ID_OP: - Question = IdToQuestion (FormSet, Form, OpCode->QuestionId); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2); - if (Question2 == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - UpdateHiiValue (FormSet, Question); - UpdateHiiValue (FormSet, Question2); - Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet); - if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE); - break; - - case EFI_IFR_EQ_ID_VAL_LIST_OP: - - Question = IdToQuestion (FormSet, Form, OpCode->QuestionId); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - UpdateHiiValue (FormSet, Question); - Value->Value.b = FALSE; - for (Index =0; Index < OpCode->ListLength; Index++) { - if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) { - Value->Value.b = TRUE; - break; - } - } - break; - - case EFI_IFR_DUP_OP: - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = PushExpression (Value); - break; - - case EFI_IFR_QUESTION_REF1_OP: - case EFI_IFR_THIS_OP: - Question = IdToQuestion (FormSet, Form, OpCode->QuestionId); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - UpdateHiiValue (FormSet, Question); - Value = &Question->HiiValue; - break; - - case EFI_IFR_SECURITY_OP: - // - // Do nothing, as no need for static scaning - // - break; - - case EFI_IFR_GET_OP: - // - // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore. - // - Value->Type = EFI_IFR_TYPE_UNDEFINED; - Value->Value.u8 = 0; - if (OpCode->VarStorage != NULL) { - switch (OpCode->VarStorage->Type) { - case EFI_IFR_VARSTORE_OP: - // - // Get value from Buffer - // - Value->Type = OpCode->ValueType; - CopyMem (&Value->Value, OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth); - break; - - case EFI_IFR_VARSTORE_EFI_OP: - // - // Get value from Buffer - // - if (OpCode->VarStorage->NewEfiVarstore) { - Value->Type = OpCode->ValueType; - CopyMem (&Value->Value, OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth); - } else { - CopyMem (&Value->Value, OpCode->VarStorage->Buffer, OpCode->ValueWidth); - } - - - break; - case EFI_HII_VARSTORE_NAME_VALUE: - if (OpCode->ValueType != EFI_IFR_TYPE_STRING) { - // - // Get value from string except for STRING value. - // - Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr); - if (!EFI_ERROR (Status)) { - ASSERT (StrPtr != NULL); - TempLength = FceStrLen (StrPtr); - if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) { - Value->Type = OpCode->ValueType; - TempBuffer = (UINT8 *) &Value->Value; - ZeroMem (TempStr, sizeof (TempStr)); - for (Index = 0; Index < TempLength; Index ++) { - TempStr[0] = StrPtr[TempLength - Index - 1]; - DigitUint8 = (UINT8) FceStrHexToUint64 (TempStr); - if ((Index & 1) == 0) { - TempBuffer [Index/2] = DigitUint8; - } else { - TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]); - } - } - } - free (StrPtr); - StrPtr = NULL; - } - } - break; - default: - // - // Not recognize storage. - // - Status = EFI_UNSUPPORTED; - goto Done; - } - } - - break; - - case EFI_IFR_QUESTION_REF3_OP: - if (OpCode->DevicePath == 0) { - // - // EFI_IFR_QUESTION_REF3 - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Validate the expression value - // - if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Question = IdToQuestion (FormSet, Form, Value->Value.u16); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // push the questions' value on to the expression stack - // - Value = &Question->HiiValue; - } else { - // - // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3, - // since it is impractical to evaluate the value of a Question in another - // Hii Package list. - // - ZeroMem (Value, sizeof (EFI_HII_VALUE)); - } - break; - - case EFI_IFR_RULE_REF_OP: - // - // Find expression for this rule - // - RuleExpression = RuleIdToExpression (Form, OpCode->RuleId); - if (RuleExpression == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Evaluate this rule expression - // - Status = EvaluateExpression (FormSet, Form, RuleExpression, ConstantExpression); - if (EFI_ERROR (Status)) { - goto Done; - } - - Value = &RuleExpression->Result; - break; - - case EFI_IFR_STRING_REF1_OP: - Value->Type = EFI_IFR_TYPE_STRING; - Value->Value.string = OpCode->Value.Value.string; - break; - - // - // Constant - // - case EFI_IFR_TRUE_OP: - case EFI_IFR_FALSE_OP: - case EFI_IFR_ONE_OP: - case EFI_IFR_ONES_OP: - case EFI_IFR_UINT8_OP: - case EFI_IFR_UINT16_OP: - case EFI_IFR_UINT32_OP: - case EFI_IFR_UINT64_OP: - case EFI_IFR_UNDEFINED_OP: - case EFI_IFR_VERSION_OP: - case EFI_IFR_ZERO_OP: - Value = &OpCode->Value; - break; - - // - // unary-op - // - case EFI_IFR_LENGTH_OP: - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Value->Type != EFI_IFR_TYPE_STRING) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary); - if (StrPtr == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; - Value->Value.u64 = FceStrLen (StrPtr); - FreePool (StrPtr); - break; - - case EFI_IFR_NOT_OP: - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Value->Type != EFI_IFR_TYPE_BOOLEAN) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - Value->Value.b = (BOOLEAN) (!Value->Value.b); - break; - - case EFI_IFR_QUESTION_REF2_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Validate the expression value - // - if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Question = IdToQuestion (FormSet, Form, Value->Value.u16); - if (Question == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Value = &Question->HiiValue; - break; - - case EFI_IFR_STRING_REF2_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Validate the expression value - // - if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Value->Type = EFI_IFR_TYPE_STRING; - StrPtr = GetToken (Value->Value.u16, FormSet->UnicodeBinary); - if (StrPtr == NULL) { - // - // If String not exit, push an empty string - // - //Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle); - } else { - Index = (UINT16) Value->Value.u64; - Value->Value.string = Index; - FreePool (StrPtr); - } - break; - - case EFI_IFR_TO_BOOLEAN_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Convert an expression to a Boolean - // - if (Value->Type <= EFI_IFR_TYPE_DATE) { - // - // When converting from an unsigned integer, zero will be converted to - // FALSE and any other value will be converted to TRUE. - // - Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0); - - Value->Type = EFI_IFR_TYPE_BOOLEAN; - } else if (Value->Type == EFI_IFR_TYPE_STRING) { - // - // When converting from a string, if case-insensitive compare - // with "true" is True, then push True. If a case-insensitive compare - // with "false" is True, then push False. Otherwise, push Undefined. - // - StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary); - if (StrPtr == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - IfrStrToUpper (StrPtr); - if (FceStrCmp (StrPtr, L"TRUE") == 0){ - Value->Value.b = TRUE; - } else if (FceStrCmp (StrPtr, L"FALSE") == 0) { - Value->Value.b = FALSE; - } else { - Status = EFI_INVALID_PARAMETER; - FreePool (StrPtr); - goto Done; - } - FreePool (StrPtr); - Value->Type = EFI_IFR_TYPE_BOOLEAN; - } - break; - - case EFI_IFR_TO_STRING_OP: - //Status = IfrToString (FormSet, OpCode->Format, Value); - break; - - case EFI_IFR_TO_UINT_OP: - Status = IfrToUint (FormSet, Value); - break; - - case EFI_IFR_TO_LOWER_OP: - case EFI_IFR_TO_UPPER_OP: - - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - if (Value->Type != EFI_IFR_TYPE_STRING) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary); - if (StrPtr == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - // - // Do nothing here, as these two Opcode are to change or update the String Package - // - FreePool (StrPtr); - break; - - case EFI_IFR_BITWISE_NOT_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Value->Type > EFI_IFR_TYPE_DATE) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; - Value->Value.u64 = ~Value->Value.u64; - break; - - case EFI_IFR_SET_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - Data1.Type = EFI_IFR_TYPE_BOOLEAN; - Data1.Value.b = FALSE; - // - // Not support SetOpcode for static scaning - // - if (OpCode->VarStorage != NULL) { - switch (OpCode->VarStorage->Type) { - - case EFI_IFR_VARSTORE_OP: - CopyMem (OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth); - Data1.Value.b = TRUE; - break; - case EFI_IFR_VARSTORE_EFI_OP: - if (OpCode->VarStorage->NewEfiVarstore) { - CopyMem (OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth); - Data1.Value.b = TRUE; - } else { - CopyMem (OpCode->VarStorage->Buffer, &Value->Value, OpCode->ValueWidth); - Data1.Value.b = TRUE; - } - break; - case EFI_HII_VARSTORE_NAME_VALUE: - - break; - break; - default: - // - // Not recognize storage. - // - Status = EFI_UNSUPPORTED; - goto Done; - break; - } - Value = &Data1; - } - break; - - // - // binary-op - // - case EFI_IFR_ADD_OP: - case EFI_IFR_SUBTRACT_OP: - case EFI_IFR_MULTIPLY_OP: - case EFI_IFR_DIVIDE_OP: - case EFI_IFR_MODULO_OP: - case EFI_IFR_BITWISE_AND_OP: - case EFI_IFR_BITWISE_OR_OP: - case EFI_IFR_SHIFT_LEFT_OP: - case EFI_IFR_SHIFT_RIGHT_OP: - // - // Pop an expression from the expression stack - // - Status = PopExpression (&Data2); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Data2.Type > EFI_IFR_TYPE_DATE) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Pop another expression from the expression stack - // - Status = PopExpression (&Data1); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Data1.Type > EFI_IFR_TYPE_DATE) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; - - switch (OpCode->Operand) { - case EFI_IFR_ADD_OP: - Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64; - break; - - case EFI_IFR_SUBTRACT_OP: - Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64; - break; - - case EFI_IFR_MULTIPLY_OP: - Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64); - break; - - case EFI_IFR_DIVIDE_OP: - Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64); - break; - - case EFI_IFR_MODULO_OP: - DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue); - Value->Value.u64 = TempValue; - break; - - case EFI_IFR_BITWISE_AND_OP: - Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64; - break; - - case EFI_IFR_BITWISE_OR_OP: - Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64; - break; - - case EFI_IFR_SHIFT_LEFT_OP: - Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); - break; - - case EFI_IFR_SHIFT_RIGHT_OP: - Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); - break; - - default: - break; - } - break; - - case EFI_IFR_AND_OP: - case EFI_IFR_OR_OP: - // - // Two Boolean operator - // - Status = PopExpression (&Data2); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Pop another expression from the expression stack - // - Status = PopExpression (&Data1); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - if (OpCode->Operand == EFI_IFR_AND_OP) { - Value->Value.b = (BOOLEAN) (Data1.Value.b && Data2.Value.b); - } else { - Value->Value.b = (BOOLEAN) (Data1.Value.b || Data2.Value.b); - } - break; - - case EFI_IFR_EQUAL_OP: - case EFI_IFR_NOT_EQUAL_OP: - case EFI_IFR_GREATER_EQUAL_OP: - case EFI_IFR_GREATER_THAN_OP: - case EFI_IFR_LESS_EQUAL_OP: - case EFI_IFR_LESS_THAN_OP: - // - // Compare two integer, string, boolean or date/time - // - Status = PopExpression (&Data2); - if (EFI_ERROR (Status)) { - goto Done; - } - if ((Data2.Type > EFI_IFR_TYPE_BOOLEAN) && (Data2.Type != EFI_IFR_TYPE_STRING)) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Pop another expression from the expression stack - // - Status = PopExpression (&Data1); - if (EFI_ERROR (Status)) { - goto Done; - } - - Result = CompareHiiValue (&Data1, &Data2, FormSet); - if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - switch (OpCode->Operand) { - case EFI_IFR_EQUAL_OP: - Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE); - break; - - case EFI_IFR_NOT_EQUAL_OP: - Value->Value.b = (BOOLEAN) ((Result != 0) ? TRUE : FALSE); - break; - - case EFI_IFR_GREATER_EQUAL_OP: - Value->Value.b = (BOOLEAN) ((Result >= 0) ? TRUE : FALSE); - break; - - case EFI_IFR_GREATER_THAN_OP: - Value->Value.b = (BOOLEAN) ((Result > 0) ? TRUE : FALSE); - break; - - case EFI_IFR_LESS_EQUAL_OP: - Value->Value.b = (BOOLEAN) ((Result <= 0) ? TRUE : FALSE); - break; - - case EFI_IFR_LESS_THAN_OP: - Value->Value.b = (BOOLEAN) ((Result < 0) ? TRUE : FALSE); - break; - - default: - break; - } - break; - - case EFI_IFR_MATCH_OP: - Status = IfrMatch (FormSet, Value); - break; - - case EFI_IFR_CATENATE_OP: - Status = IfrCatenate (FormSet, Value); - break; - - // - // ternary-op - // - case EFI_IFR_CONDITIONAL_OP: - // - // Pop third expression from the expression stack - // - Status = PopExpression (&Data3); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Pop second expression from the expression stack - // - Status = PopExpression (&Data2); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Pop first expression from the expression stack - // - Status = PopExpression (&Data1); - if (EFI_ERROR (Status)) { - goto Done; - } - if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - if (Data1.Value.b) { - Value = &Data3; - } else { - Value = &Data2; - } - break; - - case EFI_IFR_FIND_OP: - Status = IfrFind (FormSet, OpCode->Format, Value); - break; - - case EFI_IFR_MID_OP: - Status = IfrMid (FormSet, Value); - break; - - case EFI_IFR_TOKEN_OP: - Status = IfrToken (FormSet, Value); - break; - - case EFI_IFR_SPAN_OP: - Status = IfrSpan (FormSet, OpCode->Flags, Value); - break; - - case EFI_IFR_MAP_OP: - // - // Pop the check value - // - Status = PopExpression (&Data1); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Check MapExpression list is valid. - // - if (OpCode->MapExpressionList.ForwardLink == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - // - // Go through map expression list. - // - SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList); - while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) { - SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink); - // - // Evaluate the first expression in this pair. - // - Status = EvaluateExpression (FormSet, Form, SubExpression, ConstantExpression); - if (EFI_ERROR (Status)) { - goto Done; - } - // - // Compare the expression value with current value - // - if (CompareHiiValue (&Data1, &SubExpression->Result, FormSet) == 0) { - // - // Try get the map value. - // - SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink); - if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink); - Status = EvaluateExpression (FormSet, Form, SubExpression, ConstantExpression); - if (EFI_ERROR (Status)) { - goto Done; - } - Value = &SubExpression->Result; - break; - } - // - // Skip the second expression on this pair. - // - SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink); - if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - // - // Goto the first expression on next pair. - // - SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink); - } - - // - // No map value is found. - // - if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) { - Value->Type = EFI_IFR_TYPE_UNDEFINED; - Value->Value.u8 = 0; - } - break; - - default: - break; - } - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = PushExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - } - - // - // Pop the final result from expression stack - // - Value = &Data1; - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // After evaluating an expression, there should be only one value left on the expression stack - // - if (PopExpression (Value) != EFI_ACCESS_DENIED) { - Status = EFI_INVALID_PARAMETER; - } - -Done: - RestoreExpressionEvaluationStackOffset (StackOffset); - if (!EFI_ERROR (Status)) { - CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE)); - } - - return Status; -} diff --git a/BaseTools/Source/C/FCE/Fce.c b/BaseTools/Source/C/FCE/Fce.c deleted file mode 100644 index 1845c508b5..0000000000 --- a/BaseTools/Source/C/FCE/Fce.c +++ /dev/null @@ -1,6449 +0,0 @@ -/** @file - - FCE is a tool which enables developers to retrieve and change HII configuration ("Setup") - data in Firmware Device files (".fd" files). - - Copyright (c) 2011-2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "Fce.h" - -#ifndef __GNUC__ -#define COPY_STR "copy \"%s\" \"%s\" > NUL" -#define RMDIR_STR "rmdir /S /Q \"%s\" > NUL" -#define DEL_STR "del \"%s\" > NUL" -#else -#define COPY_STR "cp \"%s\" \"%s\" > /dev/null" -#define RMDIR_STR "rm -r \"%s\" > /dev/null" -#define DEL_STR "rm \"%s\" > /dev/null" -#endif - -// -// Utility global variables -// -OPERATION_TYPE Operations; - -CHAR8 mInputFdName[MAX_FILENAME_LEN]; -CHAR8 mOutputFdName[MAX_FILENAME_LEN]; -CHAR8 mOutTxtName[MAX_FILENAME_LEN]; -CHAR8 mSetupTxtName[MAX_FILENAME_LEN]; - -CHAR8* mUtilityFilename = NULL; -UINT32 mEfiVariableAddr = 0; - -UQI_PARAM_LIST *mUqiList = NULL; -UQI_PARAM_LIST *mLastUqiList = NULL; -LIST_ENTRY mVarListEntry; -LIST_ENTRY mBfvVarListEntry; -LIST_ENTRY mAllVarListEntry; -LIST_ENTRY mFormSetListEntry; - -// -// Store GUIDed Section guid->tool mapping -// -EFI_HANDLE mParsedGuidedSectionTools = NULL; - -CHAR8* mGuidToolDefinition = "GuidToolDefinitionConf.ini"; - -// -//gFfsArray is used to store all the FFS informations of Fd -// -G_EFI_FD_INFO gEfiFdInfo; -// -//mMultiPlatformParam is used to store the structures about multi-platform support -// -MULTI_PLATFORM_PARAMETERS mMultiPlatformParam; - -UINT32 mFormSetOrderRead; -UINT32 mFormSetOrderParse; - -CHAR8 mFullGuidToolDefinitionDir[_MAX_PATH]; - -CHAR8 *mFvNameGuidString = NULL; - -/** - Check the revision of BfmLib. If not matched, return an error. - - @retval EFI_SUCCESS If revision matched, return EFI_SUCCESS. - @retval EFI_UNSUPPORTED Other cases. -**/ -static -EFI_STATUS -CheckBfmLibRevision ( - VOID - ) -{ - CHAR8 *SystemCommandFormatString; - CHAR8 *SystemCommand; - CHAR8 *TempSystemCommand; - CHAR8 *Revision; - FILE *FileHandle; - CHAR8 RevisionStr[_MAX_BUILD_VERSION]; - UINT32 Len; - - SystemCommandFormatString = NULL; - SystemCommand = NULL; - TempSystemCommand = NULL; - Revision = "Revision.txt"; - - memset (RevisionStr, 0, _MAX_BUILD_VERSION); - - // - // Construction 'system' command string - // - SystemCommandFormatString = "BfmLib -v > %s"; - SystemCommand = malloc ( - strlen (SystemCommandFormatString) + strlen (Revision) + 1 - ); - if (SystemCommand == NULL) { - return EFI_UNSUPPORTED; - } - sprintf ( - SystemCommand, - "BfmLib -v > %s", - Revision - ); - - if (mFullGuidToolDefinitionDir[0] != 0) { - TempSystemCommand = SystemCommand; - SystemCommand = malloc ( - strlen (mFullGuidToolDefinitionDir) + strlen (OS_SEP_STR) + strlen (SystemCommandFormatString) + strlen (Revision) + 1 - ); - - if (SystemCommand == NULL) { - free (TempSystemCommand); - return EFI_UNSUPPORTED; - } - strcpy (SystemCommand, mFullGuidToolDefinitionDir); - strcat (SystemCommand, OS_SEP_STR); - strcat (SystemCommand, TempSystemCommand); - free (TempSystemCommand); - } - - system (SystemCommand); - free (SystemCommand); - FileHandle = fopen (Revision, "r"); - if (FileHandle == NULL) { - printf ("Error. Read the revision file of BfmLib failed.\n"); - return EFI_ABORTED; - } - fgets(RevisionStr, _MAX_BUILD_VERSION, FileHandle); - Len = strlen(RevisionStr); - if (RevisionStr[Len - 1] == '\n') { - RevisionStr[Len - 1] = 0; - } - fclose (FileHandle); - remove (Revision); - - if (strlen (RevisionStr) > _MAX_BUILD_VERSION - 1) { - printf ("The revision string is too long"); - return EFI_UNSUPPORTED; - } - if (strcmp (RevisionStr, __BUILD_VERSION) == 0) { - return EFI_SUCCESS; - } - return EFI_UNSUPPORTED; -} - -/** - Transfer the Ascii string to the Dec Number - - @param InStr The Ascii string. - - @retval DecNum Return the Dec number. -**/ -static -UINT64 -StrToDec ( - IN CHAR8 *InStr - ) -{ - UINT8 Index; - UINTN DecNum; - UINTN Temp; - - Index = 0; - DecNum = 0; - Temp = 0; - - if (InStr == NULL) { - return (UINT64)-1; - } - while (Index < strlen (InStr)) { - - if ((*(InStr + Index) >= '0') && (*(InStr + Index) <= '9')) { - Temp = *(InStr + Index) - '0'; - } else if ((*(InStr + Index) >= 'a') && (*(InStr + Index) <= 'f')) { - Temp = *(InStr + Index) - 'a' + 10; - } else if ((*(InStr + Index) >= 'A') && (*(InStr + Index) <= 'F')) { - Temp = *(InStr + Index) - 'A' + 10; - } - DecNum = DecNum + Temp * (UINTN) pow (16, strlen (InStr) - Index - 1); - Index++; - } - return DecNum; -} -/** - Check whether there are some errors in uqi parameters of One_of - - @param Question The pointer to the question Node. - @param UqiValue The value of One_of. - - @retval TRUE If existed error, return TRUE; - @return FALSE Otherwise, return FALSE; -**/ -static -BOOLEAN -CheckOneOfParamError ( - IN CONST FORM_BROWSER_STATEMENT *Question, - IN UINT64 UqiValue - ) -{ - LIST_ENTRY *Link; - QUESTION_OPTION *Option; - UINT64 Value; - - Link = NULL; - Option = NULL; - Value = 0; - - Link = GetFirstNode (&Question->OptionListHead); - while (!IsNull (&Question->OptionListHead, Link)) { - Option = QUESTION_OPTION_FROM_LINK (Link); - Value = 0; - CopyMem (&Value, &Option->Value.Value.u64, Question->StorageWidth); - if (Value == UqiValue) { - return FALSE; - } - Link = GetNextNode (&Question->OptionListHead, Link); - } - - return TRUE; -} - -/** - Check whether there are some errors in uqi parameters of Orderlist - - @param HiiObjList The pointer to the Hii Object Node. - @param UqiValue The pointer to the Uqi parameter. - - @retval TRUE If existed error, return TRUE; - @return FALSE Otherwise, return FALSE; -**/ -static -BOOLEAN -CheckOrderParamError ( - IN CONST FORM_BROWSER_STATEMENT *Question, - IN CHAR8 *UqiValue - ) -{ - UINT8 MaxNum; - MaxNum = UqiValue[0]; - - if (MaxNum != (UINT8)(Question->MaxContainers)) { - return TRUE; - } - - return FALSE; -} - -/** - Writes a Unicode string - - @param Package A pointer to the Unicode string. - - @return NULL -**/ -static -VOID -WriteUnicodeStr ( - IN CHAR16 *pcString - ) -{ - UINTN Index; - - if (pcString == NULL) { - return; - } - - for (Index = 0; pcString[Index] != 0; Index++) { - printf("%c", pcString[Index] & 0x00FF); - } -} - -/** - Parse and set the quick configure information by the command line. - - Read the UQI Config information from command line directly, and then compare it with the value in VarList. - Update the Update flag in Varlist. - - @param CurUqiList The pointer to the current uqi - @param DefaultId The default Id. - @param PlatformId The platform Id. - @param CurQuestion The pointer to the matched question - - @retval EFI_SUCCESS It was complete successfully - @retval EFI_UNSUPPORTED Update a read-only value - @return EFI_ABORTED An error occurred -**/ -static -EFI_STATUS -SetUqiParametersWithQuestion ( - IN UQI_PARAM_LIST *CurUqiList, - IN UINT16 DefaultId, - IN UINT64 PlatformId, - IN FORM_BROWSER_STATEMENT *CurQuestion - ) -{ - FORMSET_STORAGE *VarList; - BOOLEAN IsFound; - UINT8 *ValueAddrOfVar; - UINT16 Index; - UINT64 QuestionValue; - UINT64 UqiValue; - EFI_STATUS Status; - CHAR8 *ErrorStr; - FORM_BROWSER_FORMSET *FormSet; - LIST_ENTRY *FormSetLink; - UINT64 CurValue; - - VarList = NULL; - Index = 0; - ValueAddrOfVar = NULL; - QuestionValue = 0; - UqiValue = 0; - ErrorStr = NULL; - Status = EFI_SUCCESS; - FormSet = NULL; - FormSetLink = NULL; - CurValue = 0; - - // - // Search the Variable List by VarStoreId and Offset - // - IsFound = FALSE; - FormSetLink = GetFirstNode (&mFormSetListEntry); - while (!IsNull (&mFormSetListEntry, FormSetLink)) { - FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink); - Status = SearchVarStorage ( - CurQuestion, - NULL, - CurQuestion->VarStoreInfo.VarOffset, - FormSet->StorageListHead, - (CHAR8 **) &ValueAddrOfVar, - &VarList - ); - - if (!EFI_ERROR (Status)) { - IsFound = TRUE; - break; - } - FormSetLink = GetNextNode (&mFormSetListEntry, FormSetLink); - } - - if (!IsFound) { - if (CurUqiList->Header.ScriptsLine == 0) { - printf ("Error. The question in the command line doesn't store value by EFI_VARSTORE_IFR or EFI_VARSTORE_IFR_EFI.\n"); - } else { - printf ("Error. The question in the line %d of script doesn't store value by EFI_VARSTORE_IFR or EFI_VARSTORE_IFR_EFI.\n", CurUqiList->Header.ScriptsLine); - } - return EFI_ABORTED; - } - - // - // Check the length of variable value - // - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)&QuestionValue); - } else { - switch (CurQuestion->StorageWidth) { - - case sizeof (UINT8): - QuestionValue = *(UINT8 *)ValueAddrOfVar; - break; - - case sizeof (UINT16): - QuestionValue = *(UINT16 *)ValueAddrOfVar; - break; - - case sizeof (UINT32): - QuestionValue = *(UINT32 *)ValueAddrOfVar; - break; - - case sizeof (UINT64): - QuestionValue = *(UINT64 *)ValueAddrOfVar; - break; - - default: - // - // The storage width of ORDERED_LIST may not be any type above. - // - ; - break; - } - } - UqiValue = *(UINT64 *)CurUqiList->Header.Value; - CurUqiList->SameOrNot = TRUE; - - // - // Check and set the checkbox value - // - if (CurQuestion->Operand == EFI_IFR_CHECKBOX_OP) { - if ((UqiValue != 0) && (UqiValue != 1)) { - CurUqiList->ErrorOrNot = TRUE; - CurUqiList->SameOrNot = FALSE; - CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8)); - if (CurUqiList->Error == NULL) { - printf ("Fail to allocate memory!\n"); - return EFI_ABORTED; - } - memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH); - sprintf (CurUqiList->Error, "Error. The updated value of CHECKBOX 0x%llx is invalid.\n", (unsigned long long) UqiValue); - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } - } else { - if (QuestionValue != UqiValue) { - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - memcpy ( - ValueAddrOfVar, - CurUqiList->Header.Value, - CurQuestion->StorageWidth - ); - } - CurUqiList->SameOrNot = FALSE; - } - } - } - if (CurQuestion->Operand == EFI_IFR_STRING_OP) { - if ((FceStrLen((wchar_t *)CurUqiList->Header.Value) + 1) * 2 > CurQuestion->StorageWidth) { - CurUqiList->ErrorOrNot = TRUE; - CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8)); - if (CurUqiList->Error == NULL) { - printf ("Fail to allocate memory!\n"); - return EFI_ABORTED; - } - memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH); - sprintf (CurUqiList->Error, "Error. The updated value of STRING exceed its Size.\n"); - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } else { - if (memcmp((CHAR8 *)CurUqiList->Header.Value, ValueAddrOfVar, CurQuestion->StorageWidth) != 0) { - memcpy( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - memcpy( - ValueAddrOfVar, - CurUqiList->Header.Value, - CurQuestion->StorageWidth - ); - CurUqiList->SameOrNot = FALSE; - } - } - } - // - // Check and set the NUMERIC value - // - if (CurQuestion->Operand == EFI_IFR_NUMERIC_OP) { - if ((UqiValue < CurQuestion->Minimum) || (UqiValue > CurQuestion->Maximum)) { - CurUqiList->ErrorOrNot = TRUE; - CurUqiList->SameOrNot = FALSE; - CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8)); - if (CurUqiList->Error == NULL) { - printf ("Fail to allocate memory!\n"); - return EFI_ABORTED; - } - memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH); - sprintf (CurUqiList->Error, "Error. The updated value of NUMERIC 0x%llx is invalid.\n", (unsigned long long) UqiValue); - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } - } else { - if (QuestionValue != UqiValue) { - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - memcpy ( - ValueAddrOfVar, - CurUqiList->Header.Value, - CurQuestion->StorageWidth - ); - } - CurUqiList->SameOrNot = FALSE; - } - } - } - // - // Check and set the ONE_OF value - // - if (CurQuestion->Operand == EFI_IFR_ONE_OF_OP) { - if (CheckOneOfParamError (CurQuestion, UqiValue)) { - CurUqiList->ErrorOrNot = TRUE; - CurUqiList->SameOrNot = FALSE; - CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8)); - if (CurUqiList->Error == NULL) { - printf ("Fail to allocate memory!\n"); - return EFI_ABORTED; - } - memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH); - sprintf (CurUqiList->Error, "Error. The updated ONE_OF value 0x%llx is invalid.\n", (unsigned long long) UqiValue); - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } - } else { - if (QuestionValue != UqiValue) { - if (CurQuestion->QuestionReferToBitField) { - GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue); - SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value); - } else { - memcpy ( - CurUqiList->Header.DiffValue, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - memcpy ( - ValueAddrOfVar, - CurUqiList->Header.Value, - CurQuestion->StorageWidth - ); - } - CurUqiList->SameOrNot = FALSE; - } - } - } - // - // Check and set the ORDER_LIST value - // - if (CurQuestion->Operand == EFI_IFR_ORDERED_LIST_OP) { - // - // Synchronize the MaxContainers value - // - *CurUqiList->Header.DiffValue = (UINT8)CurQuestion->MaxContainers; - - if (CheckOrderParamError (CurQuestion, (CHAR8 *)CurUqiList->Header.Value)) { - - CurUqiList->ErrorOrNot = TRUE; - CurUqiList->SameOrNot = FALSE; - CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8)); - if (CurUqiList->Error == NULL) { - printf ("Fail to allocate memory!\n"); - return EFI_ABORTED; - } - memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH); - - ErrorStr = CurUqiList->Error; - sprintf (ErrorStr, "Error. The updated NORDERED_LIST value "); - ErrorStr = ErrorStr + strlen ("Error. The updated NORDERED_LIST value "); - - for (Index = 0; Index < CurQuestion->StorageWidth; Index++) { - sprintf (ErrorStr, "%02x ", *(CurUqiList->Header.Value + Index + 1)); - ErrorStr +=3; - } - sprintf (ErrorStr, "is invalid.\n"); - memcpy ( - CurUqiList->Header.DiffValue + 1, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } else { - for (Index = 0; Index < CurQuestion->StorageWidth/CurQuestion->MaxContainers; Index++) { - CurValue = 0; - memcpy ( - &CurValue, - (ValueAddrOfVar + Index * CurQuestion->StorageWidth/CurQuestion->MaxContainers), - CurQuestion->StorageWidth/CurQuestion->MaxContainers - ); - if (CurValue != *((UINT64 *)CurUqiList->Header.Value + Index + 1)) { - CurUqiList->SameOrNot = FALSE; - break; - } - } - if (!CurUqiList->SameOrNot) { - memcpy ( - CurUqiList->Header.DiffValue + 1, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - for (Index = 0; Index < CurQuestion->MaxContainers; Index++) { - switch (CurQuestion->StorageWidth/CurQuestion->MaxContainers) { - - case sizeof (UINT8): - *((UINT8 *)ValueAddrOfVar + Index) = *(UINT8 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index); - break; - - case sizeof (UINT16): - *((UINT16 *)ValueAddrOfVar + Index) = *(UINT16 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index); - break; - - case sizeof (UINT32): - *((UINT32 *)ValueAddrOfVar + Index) = *(UINT32 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index); - break; - - case sizeof (UINT64): - *((UINT64 *)ValueAddrOfVar + Index) = *((UINT64 *)CurUqiList->Header.Value + 1 + Index); - break; - - default: - *((UINT8 *)ValueAddrOfVar + Index) = *(UINT8 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index); - break; - } - } - // - // Update the vaule of ORDERED_LIST according to its size - // - CurUqiList->Header.Value = (UINT8 *)((UINT64 *)CurUqiList->Header.Value); - memcpy ( - CurUqiList->Header.Value + 1, - ValueAddrOfVar, - CurQuestion->StorageWidth - ); - } - } - } - - return EFI_SUCCESS; -} - -/** - Parse and set the quick configure information by the command line. - - Read the UQI Config information from command line directly, and then compare it with the value in VarList. - Update the Update flag in Varlist. - - @param UqiList The pointer to the uqi list - @param DefaultId The default Id. - @param PlatformId The platform Id. - - @retval EFI_SUCCESS It was complete successfully - @retval EFI_UNSUPPORTED Update a read-only value - @return EFI_ABORTED An error occurred -**/ -static -EFI_STATUS -SetUqiParameters ( - IN UQI_PARAM_LIST *UqiList, - IN UINT16 DefaultId, - IN UINT64 PlatformId - ) -{ - FORM_BROWSER_FORMSET *FormSet; - LIST_ENTRY *FormSetLink; - FORM_BROWSER_FORM *Form; - LIST_ENTRY *FormLink; - FORM_BROWSER_STATEMENT *Question; - LIST_ENTRY *QuestionLink; - LIST_ENTRY *FormSetEntryListHead; - UQI_PARAM_LIST *CurUqiList; - - FormSet = NULL; - FormSetLink = NULL; - Form = NULL; - FormLink = NULL; - Question = NULL; - QuestionLink = NULL; - FormSetEntryListHead = &mFormSetListEntry; - - FormSetLink = GetFirstNode (FormSetEntryListHead); - while (!IsNull (FormSetEntryListHead, FormSetLink)) { - FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink); - // - // Parse all forms in formset - // - FormLink = GetFirstNode (&FormSet->FormListHead); - - while (!IsNull (&FormSet->FormListHead, FormLink)) { - Form = FORM_BROWSER_FORM_FROM_LINK (FormLink); - // - // Parse five kinds of Questions in Form - // - QuestionLink = GetFirstNode (&Form->StatementListHead); - - while (!IsNull (&Form->StatementListHead, QuestionLink)) { - Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink); - QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink); - // - // Parse five kinds of Questions in Form - // - if ((Question->Operand == EFI_IFR_ONE_OF_OP) - || (Question->Operand == EFI_IFR_NUMERIC_OP) - || (Question->Operand == EFI_IFR_CHECKBOX_OP) - || (Question->Operand == EFI_IFR_ORDERED_LIST_OP) - || (Question->Operand == EFI_IFR_STRING_OP) - ) { - if (mMultiPlatformParam.MultiPlatformOrNot) { - // - // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode - // - if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) { - continue; - } - if ((Question->Type == EFI_IFR_VARSTORE_EFI_OP) - && Question->NewEfiVarstore - && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) { - continue; - } - } - - CurUqiList = UqiList; - while (CurUqiList != NULL) { - if ((PlatformId == CurUqiList->Header.PlatformId[0]) - && (DefaultId == CurUqiList->Header.DefaultId[0]) - && CompareUqiHeader (&(Question->Uqi), &(CurUqiList->Header)) - ) { - // - // Add further check to avoid a case that there are many options with a - // same UQI (en-Us), but always returns the first one. - // - if (!CurUqiList->ParseOrNot) { - CurUqiList->ParseOrNot = TRUE; - break; - } - } - CurUqiList = CurUqiList->Next; - } - if (CurUqiList != NULL) { - SetUqiParametersWithQuestion (CurUqiList, DefaultId, PlatformId, Question); - } - } - } - FormLink = GetNextNode (&FormSet->FormListHead, FormLink); - } - FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink); - } - - return EFI_SUCCESS; -} - -/** - Set question value per UqiList. - - @param UqiList The pointer to the uqi list - @param DefaultId The default Id. - @param PlatformId The platform Id. -**/ -VOID -SetUqiParametersMultiMode ( - IN UQI_PARAM_LIST *UqiList, - IN UINT16 DefaultId, - IN UINT64 PlatformId - ) -{ - UQI_PARAM_LIST *CurUqiList; - - CurUqiList = UqiList; - while (CurUqiList != NULL) { - if ((CurUqiList->ParseOrNot == FALSE) - && (PlatformId == CurUqiList->Header.PlatformId[0]) - && (DefaultId == CurUqiList->Header.DefaultId[0]) - ) { - CurUqiList->ParseOrNot = TRUE; - if (CurUqiList->Header.Question != NULL) { - SetUqiParametersWithQuestion (CurUqiList, DefaultId, PlatformId, CurUqiList->Header.Question); - } - } - CurUqiList = CurUqiList->Next; - } -} - -/** - Find the matched question for each UQI string in UqiList - -**/ -EFI_STATUS -ScanUqiFullList ( - IN UQI_PARAM_LIST *UqiList - ) -{ - FORM_BROWSER_FORMSET *FormSet; - LIST_ENTRY *FormSetLink; - FORM_BROWSER_FORM *Form; - LIST_ENTRY *FormLink; - FORM_BROWSER_STATEMENT *Question; - LIST_ENTRY *QuestionLink; - LIST_ENTRY *FormSetEntryListHead; - UQI_PARAM_LIST *CurUqiList; - UINT64 PlatformId; - UINT16 DefaultId; - - if (UqiList == NULL) { - return EFI_SUCCESS; - } - FormSet = NULL; - FormSetLink = NULL; - Form = NULL; - FormLink = NULL; - Question = NULL; - QuestionLink = NULL; - FormSetEntryListHead = &mFormSetListEntry; - - FormSetLink = FormSetEntryListHead->ForwardLink; - while (FormSetEntryListHead != FormSetLink) { - FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink); - // - // Parse all forms in formset - // - FormLink = FormSet->FormListHead.ForwardLink; - - while (&FormSet->FormListHead != FormLink) { - Form = FORM_BROWSER_FORM_FROM_LINK (FormLink); - // - // Parse five kinds of Questions in Form - // - QuestionLink = Form->StatementListHead.ForwardLink; - - while (&Form->StatementListHead != QuestionLink) { - Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink); - QuestionLink = QuestionLink->ForwardLink; - // - // Parse five kinds of Questions in Form - // - if ((Question->Operand == EFI_IFR_ONE_OF_OP) - || (Question->Operand == EFI_IFR_NUMERIC_OP) - || (Question->Operand == EFI_IFR_CHECKBOX_OP) - || (Question->Operand == EFI_IFR_ORDERED_LIST_OP) - || (Question->Operand == EFI_IFR_STRING_OP) - ) { - // - // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode - // - if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) { - continue; - } else if (Question->NewEfiVarstore - && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) { - continue; - } - - CurUqiList = UqiList; - PlatformId = 0xFFFFFFFF; - DefaultId = 0xFFFF; - while (CurUqiList != NULL) { - if ((CurUqiList->Header.Question == NULL) - && CompareUqiHeader (&(Question->Uqi), &(CurUqiList->Header)) - && ((PlatformId != CurUqiList->Header.PlatformId[0]) || (DefaultId != CurUqiList->Header.DefaultId[0])) - ) { - CurUqiList->Header.Question = Question; - PlatformId = CurUqiList->Header.PlatformId[0]; - DefaultId = CurUqiList->Header.DefaultId[0]; - } - CurUqiList = CurUqiList->Next; - } - } - } - FormLink = FormLink->ForwardLink; - } - FormSetLink = FormSetLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Create and insert the UQI Node to the UQI parameter list. - - @retval Node address If successed, return the node address. - @retval NULL An error occurred. - -**/ -static -UQI_PARAM_LIST * -CreateInsertUqiNode ( - ) -{ - UQI_PARAM_LIST *Node; - - Node = (UQI_PARAM_LIST *) malloc (sizeof (UQI_PARAM_LIST)); - if (Node == NULL) { - return NULL; - } - memset (Node, 0, sizeof (UQI_PARAM_LIST)); - - if (mUqiList == NULL) { - mUqiList = Node; - } else { - mLastUqiList->Next = Node; - } - - mLastUqiList = Node; - return Node; -} -/** - Parse the first part of QUI string - - @param **argv[] The dual array pointer to the parameters. - @param Number The pointer to the number of the first character of UQI. - @param Buffer The buffer to store the first part of UQI. - - @retval EFI_SUCCESS Parse the QUI parameters successfully. - @retval EFI_INVALID_PARAMETER An error occurred. - -**/ -static -EFI_STATUS -ParseFirstpartOfUqi ( - IN CHAR8 **argv[], - OUT UINT32 *Number, - OUT UINT16 **Buffer - ) -{ - UINT32 Index; - - Index = 0; - - *Number = (UINT32)StrToDec ((*argv)[0]); - - if ((*Number <= 0) || (*Number > MAX_QUI_PARAM_LEN)) { - printf ("Error. Invalid UQI.\n"); - return EFI_INVALID_PARAMETER; - } - - *Buffer = malloc ((*Number + 1) * sizeof (CHAR16)); - assert (*Buffer != NULL); - memset (*Buffer, 0, (*Number + 1) * sizeof (CHAR16)); - - for (Index = 0; Index < *Number; Index++) { - if (StrToDec ((*argv)[Index]) > 0xff) { - printf ("Error. Invalid UQI.\n"); - return EFI_INVALID_PARAMETER; - } - *(*Buffer + Index) = (UINT16)StrToDec ((*argv)[Index + 1]); - } - return EFI_SUCCESS; -} - -/** - Parse the QUI input parameters from the command line - - @param argc The pointer to the number of input parameters. - @param **argv[] The dual array pointer to the parameters. - - @retval EFI_SUCCESS Parse the QUI parameters successfully. - @retval EFI_INVALID_PARAMETER An error occurred. - -**/ -static -EFI_STATUS -ParseUqiParam ( - IN UINT32 *argc, - IN CHAR8 **argv[] - ) -{ - UINT32 Index; - UQI_PARAM_LIST *UqiNode; - EFI_STATUS Status; - - Index = 0; - UqiNode = NULL; - - if (*argc < 4) { - printf ("Error. The correct command is 'FCE updateq -i -o '.\n"); - return EFI_INVALID_PARAMETER; - } - - UqiNode = CreateInsertUqiNode (); - assert (UqiNode != NULL); - - UqiNode->Header.DefaultId = (UINT16 *) calloc (1, sizeof (UINT16)); - UqiNode->Header.PlatformId = (UINT64 *) calloc (1, sizeof (UINT64)); - - Status = ParseFirstpartOfUqi (argv, &(UqiNode->Header.HexNum), &(UqiNode->Header.Data)); - if (EFI_ERROR (Status)) { - return Status; - } - *argc -= (UqiNode->Header.HexNum + 1); - *argv += UqiNode->Header.HexNum + 1; - // - // Parse the TYPE and value - // - if (strcmp ("ONE_OF", (*argv)[0]) == 0) { - UqiNode->Header.Type = ONE_OF; - } else if (strcmp ("NUMERIC", (*argv)[0]) == 0) { - UqiNode->Header.Type = NUMERIC; - } else if (strcmp ("CHECKBOX", (*argv)[0]) == 0) { - UqiNode->Header.Type = CHECKBOX; - } else if (strcmp ("STRING", (*argv)[0]) == 0) { - UqiNode->Header.Type = STRING; - } else if (strcmp ("ORDERED_LIST", (*argv)[0]) == 0) { - UqiNode->Header.Type = ORDERED_LIST; - } else { - printf ("Error. The correct command is 'FCE updateq -i -o '.\n"); - return EFI_INVALID_PARAMETER; - } - *argc -= 1; - *argv += 1; - // - // Get the value according to the type of questions. - // - switch (UqiNode->Header.Type) { - - case ONE_OF: - case NUMERIC: - case CHECKBOX: - UqiNode->Header.Value = malloc (sizeof (UINT64)); - if (UqiNode->Header.Value == NULL) { - printf ("Fali to allocate memory!\n"); - return EFI_OUT_OF_RESOURCES; - } - memset (UqiNode->Header.Value, 0, sizeof (UINT64)); - - UqiNode->Header.DiffValue = malloc (sizeof (UINT64)); - if (UqiNode->Header.DiffValue == NULL) { - printf ("Fali to allocate memory!\n"); - return EFI_OUT_OF_RESOURCES; - } - memset ( - UqiNode->Header.DiffValue, - 0, - sizeof (UINT64) - ); - *(UINT64 *)(UqiNode->Header.Value) = (UINT64)StrToDec ((*argv)[0]); - break; - - case ORDERED_LIST: - UqiNode->Header.Value = malloc (((UINTN)StrToDec ((*argv)[0]) + 1) * sizeof (UINT64)); - if (UqiNode->Header.Value == NULL) { - printf ("Fali to allocate memory!\n"); - return EFI_OUT_OF_RESOURCES; - } - memset ( - UqiNode->Header.Value, - 0, - (UINTN)StrToDec(((*argv)[0]) + 1) * sizeof (UINT64) - ); - - UqiNode->Header.DiffValue = malloc (((UINTN)StrToDec ((*argv)[0]) + 1) * sizeof (UINT64)); - if (UqiNode->Header.DiffValue == NULL) { - printf ("Fali to allocate memory!\n"); - return EFI_OUT_OF_RESOURCES; - } - memset ( - UqiNode->Header.DiffValue, - 0, - (UINTN)(StrToDec ((*argv)[0]) + 1) * sizeof (UINT64) - ); - - *UqiNode->Header.Value = (UINT8)StrToDec ((*argv)[0]); - for (Index = 1; Index <= StrToDec ((*argv)[0]); Index++) { - *((UINT64 *)UqiNode->Header.Value + Index) = StrToDec ((*argv)[Index]); - } - *argc -= (UINTN)StrToDec ((*argv)[0]); - *argv += (UINTN)StrToDec ((*argv)[0]); - break; - - default: - break; - } - - *argc -= 1; - *argv += 1; - - if (*argc > 0) { - printf ("Error. The correct command is 'FCE updateq -i -o '.\n"); - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} -/** - Parse the input Fd file, and get the file name according to the FILETYPE. - - @param FdName The Name of Fd file - @param FILETYPE The type of Fd file - - @return EFI_SUCCESS Get the file name successfully - @return EFI_ABORTED An error occurred. -**/ -static -EFI_STATUS -ParseInFile ( - IN CHAR8 *FdName, - IN FILETYPE Type -) -{ - FILE *Fptr; - - Fptr = NULL; - - if ((Type == INFD) && ((FdName == NULL) || (Fptr = fopen (FdName, "r")) == NULL)) { - if (FdName != NULL) { - printf ("Error: The file doesn't exist '%s'\n", FdName); - } - return EFI_ABORTED; - } - if ((Type == OUTFD) && (FdName == NULL) ) { - printf ("Error: The name is NULL.\n"); - return EFI_ABORTED; - } - if ((Type == SETUPTXT) && (FdName == NULL) ) { - printf ("Error: The