+++ /dev/null
-#!/usr/bin/env bash\r
-\r
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here\r
-dir=$(dirname "$full_cmd")\r
-cmd=${full_cmd##*/}\r
-\r
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]\r
-then\r
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"\r
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]\r
-then\r
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]\r
- then\r
- echo "BaseTools C Tool binary was not found ($cmd)"\r
- echo "You may need to run:"\r
- echo " make -C $EDK_TOOLS_PATH/Source/C"\r
- else\r
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"\r
- fi\r
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]\r
-then\r
- exec "$dir/../../Source/C/bin/$cmd" "$@"\r
-else\r
- echo "Unable to find the real '$cmd' to run"\r
- echo "This message was printed by"\r
- echo " $0"\r
- exit 127\r
-fi\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The API to create the binary.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BinaryCreate.h"\r
-#ifndef __GNUC__\r
-#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > NUL"\r
-#else\r
-#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > /dev/null"\r
-#endif\r
-\r
-//\r
-// The guid is to for FFS of BFV.\r
-//\r
-EFI_GUID gEfiFfsBfvForMultiPlatformGuid = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID;\r
-EFI_GUID gEfiFfsBfvForMultiPlatformGuid2 = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2;\r
-\r
-/**\r
- Convert a GUID to a string.\r
-\r
- @param[in] Guid Pointer to GUID to print.\r
-\r
- @return The string after convert.\r
-**/\r
-static\r
-CHAR8 *\r
-LibBfmGuidToStr (\r
- IN EFI_GUID *Guid\r
-)\r
-{\r
- CHAR8 * Buffer;\r
-\r
- Buffer = NULL;\r
-\r
- if (Guid == NULL) {\r
- return NULL;\r
- }\r
-\r
- Buffer = (CHAR8 *) malloc (36 + 1);\r
-\r
- if (Buffer == NULL) {\r
- return NULL;\r
- }\r
- memset (Buffer, '\0', 36 + 1);\r
-\r
- sprintf (\r
- Buffer,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
- Guid->Data1,\r
- Guid->Data2,\r
- Guid->Data3,\r
- Guid->Data4[0],\r
- Guid->Data4[1],\r
- Guid->Data4[2],\r
- Guid->Data4[3],\r
- Guid->Data4[4],\r
- Guid->Data4[5],\r
- Guid->Data4[6],\r
- Guid->Data4[7]\r
- );\r
-\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Create the Ras section in FFS\r
-\r
- @param[in] InputFilePath .efi file, it's optional unless process PE/TE section.\r
- @param[in] OutputFilePath .te or .pe file\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-CreateRawSection (\r
- IN CHAR8* InputFilePath,\r
- IN CHAR8* OutputFilePath\r
- )\r
-{\r
- INT32 ReturnValue;\r
- CHAR8* SystemCommand;\r
-\r
- SystemCommand = NULL;\r
- SystemCommand = malloc (\r
- strlen (GENSEC_RAW) +\r
- strlen ("EFI_SECTION_RAW") +\r
- strlen (InputFilePath) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- GENSEC_RAW,\r
- "EFI_SECTION_RAW",\r
- InputFilePath,\r
- OutputFilePath\r
- );\r
- ReturnValue = system (SystemCommand);\r
- free(SystemCommand);\r
-\r
- if (ReturnValue != 0) {\r
- printf ("Error. Call GenSec failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Create the Ras type of FFS\r
-\r
- @param[in] InputFilePath .efi file, it's optional unless process PE/TE section.\r
- @param[in] OutputFilePath .te or .pe file\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-CreateRawFfs (\r
- IN CHAR8** InputFilePaths,\r
- IN CHAR8* OutputFilePath,\r
- IN BOOLEAN SizeOptimized\r
- )\r
-{\r
- INT32 ReturnValue;\r
- CHAR8* SystemCommandFormatString;\r
- CHAR8* SystemCommand;\r
- CHAR8* GuidStr;\r
- CHAR8* FilePathFormatStr;\r
- CHAR8* FilePathStr;\r
- UINT32 Index;\r
- UINT32 StrLen;\r
- UINT32 Size;\r
-\r
- SystemCommand = NULL;\r
- GuidStr = NULL;\r
- FilePathStr = NULL;\r
- StrLen = 0;\r
-\r
- FilePathFormatStr = " -i \"";\r
-\r
- for (Index = 0; InputFilePaths[Index] != NULL; Index++) {\r
- Size = strlen (FilePathFormatStr) + strlen (InputFilePaths[Index]) + 2; // 2 menas "" "\r
- if (FilePathStr == NULL) {\r
- FilePathStr = malloc (Size);\r
- if (NULL == FilePathStr) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- } else {\r
- FilePathStr = realloc (FilePathStr, StrLen + Size);\r
- if (NULL == FilePathStr) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- memset (FilePathStr + StrLen, ' ', Size);\r
- memcpy (FilePathStr + StrLen, FilePathFormatStr, strlen(FilePathFormatStr));\r
- memcpy(FilePathStr + StrLen + strlen(FilePathFormatStr), InputFilePaths[Index], strlen(InputFilePaths[Index]));\r
- StrLen += Size;\r
- *(FilePathStr + StrLen - 2) = '\"';\r
- }\r
- if (FilePathStr == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- *(FilePathStr + StrLen - 1)= '\0';\r
-\r
-\r
- if (SizeOptimized) {\r
- GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid2);\r
- } else {\r
- GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid);\r
- }\r
- if (NULL == GuidStr) {\r
- free (FilePathStr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- SystemCommandFormatString = "GenFfs -t %s %s -g %s -o \"%s\"";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) +\r
- strlen ("EFI_FV_FILETYPE_FREEFORM") +\r
- strlen (FilePathStr) +\r
- strlen (GuidStr) +\r
- strlen (OutputFilePath) +\r
- 1\r
- );\r
- if (NULL == SystemCommand) {\r
- free (GuidStr);\r
- free (FilePathStr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "GenFfs -t %s %s -g %s -o \"%s\"",\r
- "EFI_FV_FILETYPE_FREEFORM",// -t\r
- FilePathStr, // -i\r
- GuidStr, // -g\r
- OutputFilePath // -o\r
- );\r
- ReturnValue = system (SystemCommand);\r
- free(SystemCommand);\r
- free (FilePathStr);\r
- free (GuidStr);\r
-\r
- if (ReturnValue != 0) {\r
- printf ("Error. Call GenFfs failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The API to create the binary.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _BINARY_CREATE_H_\r
-#define _BINARY_CREATE_H_ 1\r
-\r
-#include <FvLib.h>\r
-#include "Compress.h"\r
-#include "Decompress.h"\r
-#include "CommonLib.h"\r
-#include "EfiUtilityMsgs.h"\r
-#include "FirmwareVolumeBufferLib.h"\r
-#include "OsPath.h"\r
-#include "ParseGuidedSectionTools.h"\r
-#include "StringFuncs.h"\r
-#include "ParseInf.h"\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Common/UefiInternalFormRepresentation.h>\r
-#include <Common/UefiCapsule.h>\r
-#include <Common/PiFirmwareFile.h>\r
-#include <Common/PiFirmwareVolume.h>\r
-#include <Guid/PiFirmwareFileSystem.h>\r
-#include <IndustryStandard/PeImage.h>\r
-#include <Protocol/GuidedSectionExtraction.h>\r
-\r
-//1AE42876-008F-4161-B2B7-1C0D15C5EF43\r
-#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID \\r
- { 0x1ae42876, 0x008f, 0x4161, { 0xb2, 0xb7, 0x1c, 0xd, 0x15, 0xc5, 0xef, 0x43 }}\r
-\r
-extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid;\r
-\r
-// {003E7B41-98A2-4BE2-B27A-6C30C7655225}\r
-#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2 \\r
- { 0x3e7b41, 0x98a2, 0x4be2, { 0xb2, 0x7a, 0x6c, 0x30, 0xc7, 0x65, 0x52, 0x25 }}\r
-\r
-extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid2;\r
-\r
-typedef UINT64 SKU_ID;\r
-\r
-typedef struct {\r
- UINT32 Offset:24;\r
- UINT32 Value:8;\r
-} PCD_DATA_DELTA;\r
-\r
-typedef struct {\r
- SKU_ID SkuId;\r
- UINT16 DefaultId;\r
- UINT8 Reserved[6];\r
-} PCD_DEFAULT_INFO;\r
-\r
-typedef struct {\r
- //\r
- // Full size, it must be at 8 byte alignment.\r
- //\r
- UINT32 DataSize;\r
- //\r
- // HeaderSize includes HeaderSize fields and DefaultInfo arrays\r
- //\r
- UINT32 HeaderSize;\r
- //\r
- // DefaultInfo arrays those have the same default setting.\r
- //\r
- PCD_DEFAULT_INFO DefaultInfo[1];\r
- //\r
- // Default data is stored as variable storage or the array of DATA_DELTA.\r
- //\r
-} PCD_DEFAULT_DATA;\r
-\r
-#define PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE SIGNATURE_32('N', 'S', 'D', 'B')\r
-\r
-typedef struct {\r
- //\r
- // PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE\r
- //\r
- UINT32 Signature;\r
- //\r
- // Length of the taken default buffer\r
- //\r
- UINT32 Length;\r
- //\r
- // Length of the total reserved buffer\r
- //\r
- UINT32 MaxLength;\r
- //\r
- // Reserved for 8 byte alignment\r
- //\r
- UINT32 Reserved;\r
- // one or more PCD_DEFAULT_DATA\r
-} PCD_NV_STORE_DEFAULT_BUFFER_HEADER;\r
-\r
-//\r
-// NvStoreDefaultValueBuffer layout:\r
-// +-------------------------------------+\r
-// | PCD_NV_STORE_DEFAULT_BUFFER_HEADER |\r
-// +-------------------------------------+\r
-// | PCD_DEFAULT_DATA (DEFAULT, Standard)|\r
-// +-------------------------------------+\r
-// | PCD_DATA_DELTA (DEFAULT, Standard)|\r
-// +-------------------------------------+\r
-// | ...... |\r
-// +-------------------------------------+\r
-// | PCD_DEFAULT_DATA (SKU A, Standard) |\r
-// +-------------------------------------+\r
-// | PCD_DATA_DELTA (SKU A, Standard) |\r
-// +-------------------------------------+\r
-// | ...... |\r
-// +-------------------------------------+\r
-//\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT16 Offset;\r
- UINT8 Value;\r
-} DATA_DELTA;\r
-\r
-#pragma pack()\r
-\r
-/**\r
- Create the Ras section in FFS\r
-\r
- @param[in] InputFilePath The input file path and name.\r
- @param[in] OutputFilePath The output file path and name.\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-CreateRawSection (\r
- IN CHAR8* InputFilePath,\r
- IN CHAR8* OutputFilePath\r
- );\r
-\r
-/**\r
- Create the Ras type of FFS\r
-\r
- @param[in] InputFilePath .efi file, it's optional unless process PE/TE section.\r
- @param[in] OutputFilePath .te or .pe file\r
-\r
- @retval EFI_SUCCESS\r
-\r
-**/\r
-EFI_STATUS\r
-CreateRawFfs (\r
- IN CHAR8** InputFilePaths,\r
- IN CHAR8* OutputFilePath,\r
- IN BOOLEAN SizeOptimized\r
- );\r
-\r
-#endif\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The API to parse the binary.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __GNUC__\r
-#include "windows.h"\r
-#else\r
-#include <sys/types.h>\r
-#include <dirent.h>\r
-#include <unistd.h>\r
-#endif\r
-#include "BinaryParse.h"\r
-#include "BinaryCreate.h"\r
-#include "VariableCommon.h"\r
-#include "FirmwareVolumeBufferLib.h"\r
-\r
-extern G_EFI_FD_INFO gEfiFdInfo;\r
-extern EFI_HANDLE mParsedGuidedSectionTools;\r
-extern CHAR8 mInputFdName[MAX_FILENAME_LEN];\r
-\r
-//\r
-// The Guid to sign the position of Vfr and Uni array in FV\r
-//\r
-EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;\r
-EFI_GUID gUniStrArrayAttractGuid = EFI_UNI_STR_ATTRACT_GUID;\r
-EFI_GUID gEfiSystemNvDataFvGuid = EFI_SYSTEM_NVDATA_FV_GUID;\r
-EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
-\r
-/**\r
- Converts a three byte length value into a UINT32.\r
-\r
- @param ThreeByteLength Pointer to the first of the 3 byte length.\r
-\r
- @retval Length Size of the section\r
-\r
-**/\r
-static\r
-UINT32\r
-Get3ByteLength (\r
- IN UINT8 *ThreeByteLength\r
- )\r
-{\r
- UINT32 Length;\r
-\r
- Length = 0;\r
-\r
- if (ThreeByteLength == NULL) {\r
- return 0;\r
- }\r
-\r
- Length = *((UINT32 *) ThreeByteLength);\r
- Length = Length & 0x00FFFFFF;\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Generate the unique template filename.\r
-**/\r
-CHAR8 *\r
-GenTempFile (\r
- VOID\r
- )\r
-{\r
- CHAR8 *TemString;\r
- TemString = NULL;\r
-#ifndef __GNUC__\r
- TemString = CloneString (tmpnam (NULL));\r
-#else\r
- CHAR8 tmp[] = "/tmp/fileXXXXXX";\r
- UINTN Fdtmp;\r
- Fdtmp = mkstemp(tmp);\r
- TemString = CloneString(tmp);\r
- close(Fdtmp);\r
-#endif\r
- return TemString;\r
-}\r
-\r
-/**\r
- Check whether exist the same Ifr FFS. If not existed, return TRUE.\r
-\r
- @param[in] FfsImage The pointer to the binary.\r
- @param[in] FileSize The size of binary.\r
-\r
- @return The string after convert.\r
-**/\r
-static\r
-BOOLEAN\r
-NotExistSameFfsIfr (\r
- IN VOID *FfsImage\r
-)\r
-{\r
- UINT32 Index;\r
-\r
- Index = 0;\r
-\r
- while (gEfiFdInfo.FfsArray[Index] != NULL) {\r
- if (memcmp (gEfiFdInfo.FfsArray[Index], FfsImage, sizeof (EFI_GUID)) == 0) {\r
- return FALSE;\r
- }\r
- Index++;\r
- }\r
- return TRUE;\r
-}\r
-\r
-/**\r
- This function returns the next larger size that meets the alignment\r
- requirement specified.\r
-\r
- @param ActualSize The size.\r
- @param Alignment The desired alignment.\r
-\r
- @retval The Occupied length\r
-\r
-**/\r
-static\r
-UINT32\r
-GetOccupiedSize (\r
- IN UINT32 ActualSize,\r
- IN UINT32 Alignment\r
- )\r
-{\r
- UINT32 OccupiedSize;\r
-\r
- OccupiedSize = ActualSize;\r
- while ((OccupiedSize & (Alignment - 1)) != 0) {\r
- OccupiedSize++;\r
- }\r
-\r
- return OccupiedSize;\r
-}\r
-\r
-\r
-/**\r
- Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS.\r
-\r
- @param SectionBuffer The section base address\r
- @param BufferLength The length of FFS.\r
- @param EfiBufferHeader The structure dual pointer to the efi informations\r
-\r
- @retval EFI_SUCCESS The application exited normally.\r
- @retval EFI_ABORTED An error occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSection (\r
- IN BOOLEAN IsFfsOrEfi,\r
- IN OUT UINT8 *SectionBuffer,\r
- IN UINT32 BufferLength,\r
- IN OUT EFI_SECTION_STRUCT **EfiBufferHeader\r
- )\r
-{\r
- UINT32 ParsedLength;\r
- EFI_SECTION_TYPE Type;\r
- UINT8 *Ptr;\r
- UINT32 SectionLength;\r
- UINT8 *CompressedBuffer;\r
- UINT32 CompressedLength;\r
- UINT8 *UncompressedBuffer;\r
- UINT32 UncompressedLength;\r
- UINT8 CompressionType;\r
- DECOMPRESS_FUNCTION DecompressFunction;\r
- GETINFO_FUNCTION GetInfoFunction;\r
- UINT32 ScratchSize;\r
- UINT8 *ScratchBuffer;\r
- EFI_STATUS Status;\r
- UINT32 DstSize;\r
- CHAR8 *ExtractionTool;\r
- CHAR8 *ToolInputFile;\r
- CHAR8 *ToolOutputFile;\r
- CHAR8 *SystemCommandFormatString;\r
- CHAR8 *SystemCommand;\r
- UINT8 *ToolOutputBuffer;\r
- UINT32 ToolOutputLength;\r
- BOOLEAN HasDepexSection;\r
-\r
- Ptr = NULL;\r
- SectionLength = 0;\r
- CompressedBuffer = NULL;\r
- CompressedLength = 0;\r
- UncompressedBuffer = NULL;\r
- UncompressedLength = 0;\r
- CompressionType = 0;\r
- ScratchSize = 0;\r
- ScratchBuffer = NULL;\r
- Status = EFI_SUCCESS;\r
- DstSize = 0;\r
- ExtractionTool = NULL;\r
- ToolInputFile = NULL;\r
- ToolOutputFile = NULL;\r
- SystemCommandFormatString = NULL;\r
- SystemCommand = NULL;\r
-\r
- //\r
- // Jump the FFS header\r
- //\r
- if (IsFfsOrEfi) {\r
- SectionBuffer = SectionBuffer + sizeof (EFI_FFS_FILE_HEADER);\r
- BufferLength = BufferLength - sizeof (EFI_FFS_FILE_HEADER);\r
- }\r
- ParsedLength = 0;\r
- HasDepexSection = FALSE;\r
- ExtractionTool = NULL;\r
- ToolOutputLength = 0;\r
- ToolOutputBuffer = NULL;\r
-\r
- (*EfiBufferHeader)->Length = BufferLength;\r
-\r
- while (ParsedLength < BufferLength) {\r
- Ptr = SectionBuffer + ParsedLength;\r
-\r
- SectionLength = Get3ByteLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
- Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
-\r
- //\r
- // This is sort of an odd check, but is necessary because FFS files are\r
- // padded to a QWORD boundary, meaning there is potentially a whole section\r
- // header worth of 0xFF bytes.\r
- //\r
- if ((SectionLength == 0xffffff) && (Type == 0xff)) {\r
- ParsedLength += 4;\r
- continue;\r
- }\r
-\r
- switch (Type) {\r
-\r
- case EFI_SECTION_PE32:\r
- case EFI_SECTION_TE:\r
- //\r
- //Got the correct address\r
- //\r
- (*EfiBufferHeader)->BufferBase = (UINTN)(Ptr + sizeof (EFI_COMMON_SECTION_HEADER));\r
- return EFI_SUCCESS;\r
-\r
- case EFI_SECTION_RAW:\r
- case EFI_SECTION_PIC:\r
- break;\r
-\r
- case EFI_SECTION_USER_INTERFACE:\r
- HasDepexSection = FALSE;\r
- break;\r
-\r
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
- case EFI_SECTION_COMPATIBILITY16:\r
- case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
- break;\r
-\r
- case EFI_SECTION_PEI_DEPEX:\r
- case EFI_SECTION_DXE_DEPEX:\r
- case EFI_SECTION_SMM_DEPEX:\r
- HasDepexSection = TRUE;\r
- break;\r
-\r
- case EFI_SECTION_VERSION:\r
- break;\r
- case EFI_SECTION_COMPRESSION:\r
- UncompressedBuffer = NULL;\r
- CompressedLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION);\r
- UncompressedLength = ((EFI_COMPRESSION_SECTION *) Ptr)->UncompressedLength;\r
- CompressionType = ((EFI_COMPRESSION_SECTION *) Ptr)->CompressionType;\r
-\r
- if (CompressionType == EFI_NOT_COMPRESSED) {\r
- if (CompressedLength != UncompressedLength) {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "file is not compressed, but the compressed length does not match the uncompressed length",\r
- NULL\r
- );\r
- return EFI_ABORTED;\r
- }\r
-\r
- UncompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION);\r
- } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
- GetInfoFunction = EfiGetInfo;\r
- DecompressFunction = EfiDecompress;\r
- CompressedBuffer = Ptr + sizeof (EFI_COMPRESSION_SECTION);\r
-\r
- Status = GetInfoFunction (\r
- CompressedBuffer,\r
- CompressedLength,\r
- &DstSize,\r
- &ScratchSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (DstSize != UncompressedLength) {\r
- Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
- return EFI_ABORTED;\r
- }\r
-\r
- ScratchBuffer = malloc (ScratchSize);\r
- if (ScratchBuffer == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- UncompressedBuffer = malloc (UncompressedLength);\r
- if (UncompressedBuffer == NULL) {\r
- free (ScratchBuffer);\r
- return EFI_ABORTED;\r
- }\r
- memset (UncompressedBuffer, 0, UncompressedLength);\r
-\r
- Status = DecompressFunction (\r
- CompressedBuffer,\r
- CompressedLength,\r
- UncompressedBuffer,\r
- UncompressedLength,\r
- ScratchBuffer,\r
- ScratchSize\r
- );\r
- free (ScratchBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- Error (NULL, 0, 0003, "decompress failed", NULL);\r
- free (UncompressedBuffer);\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Status = ParseSection (FALSE, UncompressedBuffer, UncompressedLength, EfiBufferHeader);\r
- if (Status != EFI_SUCCESS) {\r
- Error (NULL, 0, 0003, "failed to parse section", NULL);\r
- free (UncompressedBuffer);\r
- UncompressedBuffer = NULL;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Store the allocate memory address for UncompressedBuffer\r
- //\r
- if (UncompressedBuffer != NULL) {\r
- (*EfiBufferHeader)->UncompressedBuffer[(*EfiBufferHeader)->UnCompressIndex] = (UINTN) UncompressedBuffer;\r
- (*EfiBufferHeader)->UnCompressIndex = (*EfiBufferHeader)->UnCompressIndex + 1;\r
- }\r
- break;\r
-\r
- case EFI_SECTION_GUID_DEFINED:\r
- //\r
- // Decompress failed, and then check for CRC32 sections which we can handle internally if needed.\r
- // Maybe this section is no-compressed.\r
- //\r
- if (!CompareGuid (\r
- &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid,\r
- &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
- )) {\r
- //\r
- // CRC32 guided section\r
- //\r
- Status = ParseSection (\r
- FALSE,\r
- SectionBuffer + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,\r
- BufferLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,\r
- EfiBufferHeader\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
- return EFI_ABORTED;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- } else {\r
- ExtractionTool = LookupGuidedSectionToolPath (\r
- mParsedGuidedSectionTools,\r
- &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid\r
- );\r
-\r
- if (ExtractionTool != NULL) {\r
- ToolInputFile = GenTempFile ();\r
- ToolOutputFile = GenTempFile ();\r
- //\r
- // Construction 'system' command string\r
- //\r
- SystemCommandFormatString = "%s -d -o \"%s\" \"%s\"";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) \\r
- + strlen (ExtractionTool) \\r
- + strlen (ToolInputFile) \\r
- + strlen (ToolOutputFile) \\r
- + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- free (ExtractionTool);\r
- free (ToolInputFile);\r
- free (ToolOutputFile);\r
- return EFI_ABORTED;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "%s -d -o \"%s\" \"%s\"",\r
- ExtractionTool,\r
- ToolOutputFile,\r
- ToolInputFile\r
- );\r
- free (ExtractionTool);\r
-\r
- Status = PutFileImage (\r
- ToolInputFile,\r
- (CHAR8*) Ptr + ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset,\r
- SectionLength - ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset\r
- );\r
-\r
- if (HasDepexSection) {\r
- HasDepexSection = FALSE;\r
- }\r
-\r
- system (SystemCommand);\r
- remove (ToolInputFile);\r
- free (ToolInputFile);\r
- ToolInputFile = NULL;\r
- free (SystemCommand);\r
- SystemCommand = NULL;\r
-\r
- if (EFI_ERROR (Status)) {\r
- Error ("FCE", 0, 0004, "unable to decoded GUIDED section", NULL);\r
- free (ToolOutputFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Status = GetFileImage (\r
- ToolOutputFile,\r
- (CHAR8 **)&ToolOutputBuffer,\r
- &ToolOutputLength\r
- );\r
- remove (ToolOutputFile);\r
- free (ToolOutputFile);\r
- ToolOutputFile = NULL;\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- Status = ParseSection (\r
- FALSE,\r
- ToolOutputBuffer,\r
- ToolOutputLength,\r
- EfiBufferHeader\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
- return EFI_ABORTED;\r
- }\r
- }\r
- break;\r
-\r
- default:\r
- ;\r
- }\r
- ParsedLength += SectionLength;\r
- //\r
- // We make then next section begin on a 4-byte boundary\r
- //\r
- ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
- }\r
-\r
- return EFI_ABORTED;\r
-}\r
-\r
-static\r
-BOOLEAN\r
-GetNextOffset (\r
- IN UINT8 *Data,\r
- IN EFI_GUID *Guid,\r
- IN UINTN Len,\r
- IN OUT UINTN *Offset\r
- )\r
-{\r
- UINTN NextOffset;\r
- if (*Offset >= Len || Len - *Offset <= sizeof (EFI_GUID)) {\r
- return FALSE;\r
- }\r
-\r
- for (NextOffset = *Offset; NextOffset < Len - sizeof (EFI_GUID); NextOffset++) {\r
- if (CompareGuid(Guid, (EFI_GUID*)(Data + NextOffset)) == 0) {\r
- *Offset = NextOffset + sizeof(EFI_GUID);\r
- return TRUE;\r
- }\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Get the address by Guid.\r
-\r
- Parse the FFS image, and find the GUID address.There may be some Guids matching the\r
- searched Guid.\r
-\r
- @param Fv the Pointer to the image.\r
- @param Guid The Guid need to find.\r
- @param Offset The dual Pointer to the offset.\r
- @param NumOfMatchGuid The number of matching Guid offset.\r
-\r
- @retval EFI_SUCCESS The Search was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-GetAddressByGuid (\r
- IN VOID *Fv,\r
- IN EFI_GUID *Guid,\r
- IN UINTN Len,\r
- OUT UINTN **Offset,\r
- OUT UINT8 *NumOfMatchGuid\r
- )\r
-{\r
- VOID *LocalFv;\r
- UINT8 Flag;\r
-\r
- EFI_RAW_SECTION* Section;\r
- UINT8 *RawData;\r
- VOID* SectionStart;\r
- UINTN NextOffset;\r
- UINTN Key;\r
- UINTN TotalSectionsSize;\r
- UINTN SecLen;\r
- UINTN SecHdr;\r
- EFI_STATUS Status;\r
-\r
- if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) || Len == 0 ){\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalFv = Fv;\r
- Flag = 0;\r
- Section = NULL;\r
- Key = 0;\r
-\r
- if (NumOfMatchGuid != NULL) {\r
- *NumOfMatchGuid = 0;\r
- }\r
-\r
- SectionStart = (VOID*)((UINTN)LocalFv + FvBufGetFfsHeaderSize(LocalFv));\r
- TotalSectionsSize = Len - FvBufGetFfsHeaderSize(LocalFv);\r
- while (TRUE) {\r
- Status = FvBufFindNextSection (\r
- SectionStart,\r
- TotalSectionsSize,\r
- &Key,\r
- (VOID **)&Section\r
- );\r
- if (Section == NULL || EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (EFI_SECTION_RAW == Section->Type) {\r
- if ((*(UINT32 *)Section->Size & 0xffffff) == 0xffffff) {\r
- SecLen = ((EFI_RAW_SECTION2 *)Section)->ExtendedSize;\r
- SecHdr = sizeof(EFI_RAW_SECTION2);\r
- } else {\r
- SecLen = *(UINT32 *)Section->Size & 0xffffff;\r
- SecHdr = sizeof(EFI_RAW_SECTION);\r
- }\r
- if (SecLen <= SecHdr || SecLen - SecHdr < sizeof(EFI_GUID)) {\r
- continue;\r
- }\r
- RawData = (UINT8 *)Section + SecHdr;\r
- NextOffset = 0;\r
- while (GetNextOffset(RawData, Guid, SecLen - SecHdr, &NextOffset)) {\r
- Flag = 1;\r
- if ((NumOfMatchGuid != NULL) && (Offset != NULL)) {\r
- if (*NumOfMatchGuid == 0) {\r
- *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM);\r
- if (*Offset == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM);\r
- }\r
- *(*Offset + *NumOfMatchGuid) = NextOffset + (RawData - (UINT8 *)Fv);\r
- (*NumOfMatchGuid)++;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if( Flag == 0 ) {\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search the VfrBin Base address.\r
-\r
- According the known GUID gVfrArrayAttractGuid to get the base address from FFS.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param EfiAddr the Pointer to the EFI in FFS\r
- @param Length the length of Fv\r
- @param Offset the Pointer to the Addr (Offset)\r
- @param NumOfMachingOffset the number of Addr (Offset)\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-SearchVfrBinInFFS (\r
- IN VOID *Fv,\r
- IN VOID *EfiAddr,\r
- IN UINTN Length,\r
- OUT UINTN **Offset,\r
- OUT UINT8 *NumOfMachingOffset\r
- )\r
-{\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- UINTN VirOffValue;\r
-\r
- Index = 0;\r
- Status = EFI_SUCCESS;\r
- VirOffValue = 0;\r
-\r
- if ((Fv == NULL) || (Offset == NULL)) {\r
- return EFI_ABORTED;\r
- }\r
- Status = GetAddressByGuid (\r
- Fv,\r
- &gVfrArrayAttractGuid,\r
- Length,\r
- Offset,\r
- NumOfMachingOffset\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- while (Index < *NumOfMachingOffset) {\r
- //\r
- // Got the virOffset after the GUID\r
- //\r
- VirOffValue = *(UINTN *)((UINTN)Fv + *(*Offset + Index));\r
- //\r
- //Transfer the offset to the VA address. One modules may own more VfrBin address.\r
- //\r
- *(*Offset + Index) = (UINTN) EfiAddr + VirOffValue;\r
- Index++;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search the UniBin Base address.\r
-\r
- According the known GUID gUniStrArrayAttractGuid to get the base address from FFS.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param EfiAddr the Pointer to the EFI in FFS\r
- @param Length the length of Fv\r
- @param Offset the Pointer to the Addr (Offset)\r
-\r
- @retval Base address Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-SearchUniBinInFFS (\r
- IN VOID *Fv,\r
- IN VOID *EfiAddr,\r
- IN UINTN Length,\r
- OUT UINTN **Offset\r
- )\r
-{\r
- UINT8 NumOfMachingOffset;\r
- EFI_STATUS Status;\r
- UINTN VirOffValue;\r
-\r
- NumOfMachingOffset = 0;\r
- Status = EFI_SUCCESS;\r
- VirOffValue = 0;\r
-\r
- if ((Fv == NULL) || (Offset == NULL)) {\r
- return EFI_ABORTED;\r
- }\r
- Status = GetAddressByGuid (\r
- Fv,\r
- &gUniStrArrayAttractGuid,\r
- Length,\r
- Offset,\r
- &NumOfMachingOffset\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- //Transfer the offset to the VA address. There is only one UniArray in one modules.\r
- //\r
- if (NumOfMachingOffset == 1) {\r
- VirOffValue = *(UINTN *)((UINTN)Fv + **Offset);\r
- **Offset = (UINTN) EfiAddr + VirOffValue;\r
- } else {\r
- printf ("Error. Find more than 1 UniBin in FFS.\n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SearchNvStoreDatabaseInFd(\r
- IN VOID *Fv,\r
- IN UINTN length\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Offset;\r
- PCD_NV_STORE_DEFAULT_BUFFER_HEADER *NvStoreHeader;\r
- Status = EFI_SUCCESS;\r
- Offset = 0;\r
- if (Fv == NULL) {\r
- printf ("The FV is NULL.");\r
- return EFI_ABORTED;\r
- }\r
- while (Offset < (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER))){\r
- NvStoreHeader = (PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)((UINT8*)Fv + Offset);\r
- if (NvStoreHeader->Signature == PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE) {\r
- gEfiFdInfo.ExistNvStoreDatabase = TRUE;\r
- gEfiFdInfo.NvStoreDatabase = (UINT8 *) NvStoreHeader;\r
- break;\r
- }\r
- Offset++;\r
- }\r
- if (Offset == (length - sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) || gEfiFdInfo.ExistNvStoreDatabase != TRUE) {\r
- //printf ("Not found the PcdNvStoreDefaultValueBuffer\n");\r
- return Status;\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Get the address by Guid.\r
-\r
- Parse the FD image, and find the GUID address.There may be some Guids matching the\r
- searched Guid.\r
-\r
- @param Fv the Pointer to the image.\r
- @param Guid The Guid need to find.\r
- @param Offset The dual Pointer to the offset.\r
- @param NumOfMatchGuid The number of matching Guid offset.\r
-\r
- @retval EFI_SUCCESS The Search was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-GetVariableAddressByGuid (\r
- IN VOID *Fv,\r
- IN EFI_GUID *Guid,\r
- IN UINTN Len,\r
- OUT UINTN **Offset,\r
- OUT UINT8 *NumOfMatchGuid\r
- )\r
-{\r
- UINTN NextOffset;\r
- UINT8 Flag;\r
-\r
- if( (Fv == NULL) || (Fv == NULL) || (Guid == NULL) ){\r
- return EFI_ABORTED;\r
- }\r
-\r
- Flag = 0;\r
- NextOffset = 0;\r
-\r
- if (NumOfMatchGuid != NULL) {\r
- *NumOfMatchGuid = 0;\r
- }\r
- while (GetNextOffset(Fv, Guid, Len, &NextOffset)) {\r
- Flag = 1;\r
- if (NumOfMatchGuid != NULL && Offset != NULL) {\r
- if (*NumOfMatchGuid == 0) {\r
- *Offset = malloc (sizeof (UINTN) * MAX_MATCH_GUID_NUM);\r
- if (*Offset == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- memset (*Offset, 0, sizeof (UINTN) * MAX_MATCH_GUID_NUM);\r
- }\r
- *(*Offset + *NumOfMatchGuid) = NextOffset;\r
- (*NumOfMatchGuid)++;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- if( Flag == 0 ) {\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search the EFI Variable Base address.\r
-\r
- According the known GUID gEfiSystemNvDataFvGuid to get the base address from FFS.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param Length the length of Fv\r
- @param Offset the Pointer to the Addr (Offset)\r
- @param NumOfMachingOffset the number of IFR array in one FFS\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_ABORTED An error occured.\r
-**/\r
-EFI_STATUS\r
-SearchEfiVarInFFS (\r
- IN VOID *Fv,\r
- IN UINTN Length,\r
- OUT UINTN **Offset,\r
- OUT UINT8 *NumOfMachingOffset\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Index;\r
-\r
- Status = EFI_SUCCESS;\r
- Index = 0;\r
-\r
- if ((Fv == NULL) || (Offset == NULL)) {\r
- printf ("The FV or offset is NULL.");\r
- return EFI_ABORTED;\r
- }\r
- Status = GetVariableAddressByGuid (\r
- Fv,\r
- &gEfiSystemNvDataFvGuid,\r
- Length,\r
- Offset,\r
- NumOfMachingOffset\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- //Transfer the offset to the VA address.\r
- //\r
- while (Index < *NumOfMachingOffset) {\r
- *(*Offset + Index) = (UINTN) Fv + *(*Offset + Index);\r
- Index++;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Parse the Ffs header to get the size.\r
-\r
- @param InputFile The pointer to the input file\r
- @param FvSize The pointer to the file size\r
-\r
- @return EFI_SUCCESS Get the file size successfully\r
-**/\r
-EFI_STATUS\r
-ReadFfsHeader (\r
- IN FILE *InputFile,\r
- OUT UINT32 *FvSize\r
- )\r
-{\r
- EFI_FFS_FILE_HEADER FfsHeader;\r
- EFI_FV_FILETYPE Type;\r
-\r
- //\r
- // Check input parameters\r
- //\r
- if ((InputFile == NULL) || (FvSize == NULL)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Read the header\r
- //\r
- fread (\r
- &FfsHeader,\r
- sizeof (EFI_FFS_FILE_HEADER),\r
- 1,\r
- InputFile\r
- );\r
- Type = FfsHeader.Type;\r
-\r
- if (Type == EFI_FV_FILETYPE_DRIVER) {\r
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;\r
- } else if (Type == EFI_FV_FILETYPE_APPLICATION) {\r
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;\r
- } else if (Type == EFI_FV_FILETYPE_FREEFORM) {\r
- *FvSize = *(UINT32 *)FfsHeader.Size & 0xffffff;\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/*\r
- Read the length of the whole FD\r
-\r
- This function determines the size of the FV.\r
-\r
- @param InputFile The file that contains the FV image.\r
- @param FvSize The size of the FV.\r
-\r
- @retval EFI_SUCCESS The application exited normally.\r
- @retval EFI_ABORTED An error occurred.\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-ReadFdHeader (\r
- IN FILE *InputFile,\r
- OUT UINT32 *FvSize\r
- )\r
-{\r
- //\r
- // Check input parameters\r
- //\r
- if ((InputFile == NULL) || (FvSize == NULL)) {\r
- return EFI_ABORTED;\r
- }\r
- *FvSize = 0;\r
- //\r
- // Get the total size of FD file (Fixed the length)\r
- //\r
- fseek(InputFile,0,SEEK_END);\r
- *FvSize = ftell(InputFile);\r
- fseek(InputFile,0,SEEK_SET);\r
-\r
- if (*FvSize == 0) {\r
- return EFI_ABORTED;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read the file to memory.\r
-\r
- @param InputFile The file that contains the FV image.\r
- @param Size The size of the file.\r
-\r
- @retval The pointer to the begining position of memory.\r
-**/\r
-VOID *\r
-ReadFileToMemory (\r
- IN CHAR8 *FileName,\r
- OUT UINT32 *Size\r
- )\r
-{\r
- FILE *InFile;\r
- VOID *Address;\r
- UINT32 BytesRead;\r
- EFI_STATUS Status;\r
-\r
- InFile = NULL;\r
- Address = NULL;\r
- BytesRead = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- InFile = fopen (FileName,"rb");\r
- if (InFile == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Determine the size of FV\r
- //\r
- Status = ReadFdHeader (InFile, Size);\r
- if (Status != EFI_SUCCESS) {\r
- fclose (InFile);\r
- return NULL;\r
- }\r
- //\r
- // Allocate a buffer for the FV image\r
- //\r
- Address = malloc (*Size);\r
- if (Address == NULL) {\r
- fclose (InFile);\r
- return NULL;\r
- }\r
- memset (Address, 0, *Size);\r
- //\r
- // Seek to the start of the image, then read the entire FV to the buffer\r
- //\r
- fseek (InFile, 0, SEEK_SET);\r
- BytesRead = fread (Address, 1, *Size, InFile);\r
- fclose (InFile);\r
- if ((UINTN) BytesRead != *Size) {\r
- free (Address);\r
- return NULL;\r
- }\r
- return Address;\r
-}\r
-\r
-/**\r
- Search the EFI variables address in Fd.\r
-\r
- Open and read the *.fd to the memory, initialize the global structure.\r
- Update the EFI variables addr and the begining position of memory.\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-GetEfiVariablesAddr (\r
- BOOLEAN UqiIsSet\r
- )\r
-{\r
- VOID *FdImage;\r
- UINT32 FdSize;\r
- EFI_STATUS Status;\r
- UINTN *EfiVarAddr;\r
- UINT8 NumOfMachingVar;\r
- UINT32 Index;\r
- BOOLEAN GotFlag;\r
- EFI_FIRMWARE_VOLUME_HEADER *Variable;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
- BOOLEAN NormalOrNot;\r
-\r
- FdImage = NULL;\r
- FdSize = 0;\r
- Status = EFI_SUCCESS;\r
- EfiVarAddr = NULL;\r
- NumOfMachingVar = 0;\r
- Index = 0;\r
- GotFlag = TRUE;\r
- Variable = NULL;\r
-\r
- FdImage = ReadFileToMemory (mInputFdName, &FdSize);\r
- if (FdImage == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- if (!UqiIsSet) {\r
- Status = SearchNvStoreDatabaseInFd(FdImage, FdSize);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- Status = SearchEfiVarInFFS (\r
- FdImage,\r
- FdSize,\r
- &EfiVarAddr,\r
- &NumOfMachingVar\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Check the signature "_FVH"\r
- //\r
- Index = 0;\r
- GotFlag = FALSE;\r
-\r
- while (Index < NumOfMachingVar) {\r
- Variable = (EFI_FIRMWARE_VOLUME_HEADER *)(*(EfiVarAddr + Index) - 0x20);\r
- if (Variable->Signature == 0x4856465F) {\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore ((UINT8 *)Variable + Variable->HeaderLength);\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength);\r
- NormalOrNot = CheckNormalVarStoreOrNot ((UINT8 *)Variable + Variable->HeaderLength);\r
- if (AuthencitatedMonotonicOrNot || AuthencitatedBasedTimeOrNot || NormalOrNot) {\r
- GotFlag = TRUE;\r
- gEfiFdInfo.EfiVariableAddr = (UINTN)Variable;\r
- break;\r
- }\r
- }\r
- Index++;\r
- }\r
- free (EfiVarAddr);\r
- if (!GotFlag) {\r
- return EFI_ABORTED;\r
- }\r
- gEfiFdInfo.Fd = FdImage;\r
- gEfiFdInfo.FdSize = FdSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Pick up the FFS which includes IFR section.\r
-\r
- Parse all FFS extracted by BfmLib, and save all which includes IFR\r
- Binary to gEfiFdInfo structure.\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_BUFFER_TOO_SMALL Memory can't be allocated.\r
- @retval EFI_ABORTED Read FFS Failed.\r
-**/\r
-EFI_STATUS\r
-FindFileInFolder (\r
- IN CHAR8 *FolderName,\r
- OUT BOOLEAN *ExistStorageInBfv,\r
- OUT BOOLEAN *SizeOptimized\r
-)\r
-{\r
- CHAR8 *FileName;\r
- CHAR8 *CurFolderName;\r
- EFI_STATUS Status;\r
- UINTN MaxFileNameLen;\r
- UINTN Index;\r
- CHAR8 FileNameArry[MAX_FILENAME_LEN];\r
- FILE *FfsFile;\r
- UINTN FileSize;\r
- VOID *FfsImage;\r
- UINTN BytesRead;\r
-#ifndef __GNUC__\r
- HANDLE FindHandle;\r
- WIN32_FIND_DATA FindFileData;\r
-#else\r
- struct dirent *pDirent;\r
- DIR *pDir;\r
-#endif\r
-\r
- FileName = NULL;\r
- CurFolderName = NULL;\r
- Status = EFI_SUCCESS;\r
- MaxFileNameLen = 0;\r
- Index = 0;\r
- FileSize = 0;\r
- BytesRead = 0;\r
- FfsImage = NULL;\r
- FfsFile = NULL;\r
-\r
- MaxFileNameLen = strlen (FolderName) + MAX_FILENAME_LEN;\r
- CurFolderName = (CHAR8 *)calloc(\r
- strlen (FolderName) + strlen (OS_SEP_STR) + strlen ("*.*")+ 1,\r
- sizeof(CHAR8)\r
- );\r
- if (CurFolderName == NULL) {\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
- strcpy (CurFolderName, FolderName);\r
- strcat (CurFolderName, OS_SEP_STR);\r
- strcat (CurFolderName, "*.*");\r
- FileName = (CHAR8 *)calloc(\r
- MaxFileNameLen,\r
- sizeof(CHAR8)\r
- );\r
- if (FileName == NULL) {\r
- free (CurFolderName);\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
-#ifndef __GNUC__\r
- if((FindHandle = FindFirstFile(CurFolderName, &FindFileData)) != INVALID_HANDLE_VALUE){\r
- do {\r
- memset (FileName, 0, MaxFileNameLen);\r
- if ((strcmp (FindFileData.cFileName, ".") == 0)\r
- || (strcmp (FindFileData.cFileName, "..") == 0)\r
- ) {\r
- continue;\r
- }\r
- if (strlen(FolderName) + strlen ("\\") + strlen (FindFileData.cFileName) > MAX_FILENAME_LEN - 1) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- snprintf (FileNameArry, MAX_FILENAME_LEN, "%s%c%s", FolderName, OS_SEP, FindFileData.cFileName);\r
- FfsFile = fopen (FileNameArry, "rb");\r
- if (FfsFile == NULL) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize);\r
- if (EFI_ERROR (Status)) {\r
- fclose (FfsFile);\r
- Status = EFI_SUCCESS;\r
- continue;\r
- }\r
- //\r
- // Allocate a buffer for the FFS file\r
- //\r
- FfsImage = malloc (FileSize);\r
- if (FfsImage == NULL) {\r
- fclose (FfsFile);\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- goto Done;\r
- }\r
- //\r
- // Seek to the start of the image, then read the entire FV to the buffer\r
- //\r
- fseek (FfsFile, 0, SEEK_SET);\r
- BytesRead = fread (FfsImage, 1, FileSize, FfsFile);\r
- fclose (FfsFile);\r
-\r
- if ((UINTN) BytesRead != FileSize) {\r
- free (FfsImage);\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //\r
- // Check whether exists the storage ffs in BFV for multi-platform mode\r
- //\r
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) {\r
- *ExistStorageInBfv = TRUE;\r
- *SizeOptimized = FALSE;\r
- gEfiFdInfo.StorageFfsInBfv = FfsImage;\r
- continue;\r
- }\r
- //\r
- // Check whether exists the optimized storage ffs in BFV for multi-platform mode\r
- //\r
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) {\r
- *ExistStorageInBfv = TRUE;\r
- *SizeOptimized = TRUE;\r
- gEfiFdInfo.StorageFfsInBfv = FfsImage;\r
- continue;\r
- }\r
- //\r
- // Check whether current FFS includes IFR\r
- //\r
- Status = GetAddressByGuid (\r
- FfsImage,\r
- &gVfrArrayAttractGuid,\r
- FileSize,\r
- NULL,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- free (FfsImage);\r
- Status = EFI_SUCCESS;\r
- } else {\r
- //\r
- // Check whether existed same IFR binary. If existed, not insert the new one.\r
- //\r
- if (NotExistSameFfsIfr (FfsImage)) {\r
- gEfiFdInfo.FfsArray[Index] = FfsImage;\r
- gEfiFdInfo.Length[Index++] = FileSize;\r
- }\r
- }\r
-\r
- } while (FindNextFile (FindHandle, &FindFileData));\r
- FindClose(FindHandle);\r
- } else {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
-\r
-Done:\r
- free (CurFolderName);\r
- free (FileName);\r
-\r
-#else\r
- if((pDir = opendir(FolderName)) != NULL){\r
- while ((pDirent = readdir(pDir)) != NULL){\r
- memset (FileName, 0, MaxFileNameLen);\r
- if ((strcmp (pDirent->d_name, ".") == 0)\r
- || (strcmp (pDirent->d_name, "..") == 0)\r
- ) {\r
- continue;\r
- }\r
- sprintf (FileNameArry, "%s%c%s", FolderName, OS_SEP, pDirent->d_name);\r
- FfsFile = fopen (FileNameArry, "rb");\r
- Status = ReadFfsHeader (FfsFile, (UINT32 *)&FileSize);\r
- if (EFI_ERROR (Status)) {\r
- fclose (FfsFile);\r
- Status = EFI_SUCCESS;\r
- continue;\r
- }\r
- //\r
- // Allocate a buffer for the FFS file\r
- //\r
- FfsImage = malloc (FileSize);\r
- if (FfsImage == NULL) {\r
- fclose (FfsFile);\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- goto Done;\r
- }\r
- //\r
- // Seek to the start of the image, then read the entire FV to the buffer\r
- //\r
- fseek (FfsFile, 0, SEEK_SET);\r
- BytesRead = fread (FfsImage, 1, FileSize, FfsFile);\r
- fclose (FfsFile);\r
-\r
- if ((UINTN) BytesRead != FileSize) {\r
- free (FfsImage);\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //\r
- // Check whether exists the storage ffs in BFV for multi-platform mode\r
- //\r
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid,(EFI_GUID *) FfsImage) == 0) {\r
- *ExistStorageInBfv = TRUE;\r
- *SizeOptimized = FALSE;\r
- gEfiFdInfo.StorageFfsInBfv = FfsImage;\r
- continue;\r
- }\r
- //\r
- // Check whether exists the optimized storage ffs in BFV for multi-platform mode\r
- //\r
- if (CompareGuid(&gEfiFfsBfvForMultiPlatformGuid2,(EFI_GUID *) FfsImage) == 0) {\r
- *ExistStorageInBfv = TRUE;\r
- *SizeOptimized = TRUE;\r
- gEfiFdInfo.StorageFfsInBfv = FfsImage;\r
- continue;\r
- }\r
- //\r
- // Check whether current FFS includes IFR\r
- //\r
- Status = GetAddressByGuid (\r
- FfsImage,\r
- &gVfrArrayAttractGuid,\r
- FileSize,\r
- NULL,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- free (FfsImage);\r
- Status = EFI_SUCCESS;\r
- } else {\r
- //\r
- // Check whether existed same IFR binary. If existed, not insert the new one.\r
- //\r
- if (NotExistSameFfsIfr (FfsImage)) {\r
- gEfiFdInfo.FfsArray[Index] = FfsImage;\r
- gEfiFdInfo.Length[Index++] = FileSize;\r
- }\r
- }\r
-\r
- }\r
- closedir(pDir);\r
- } else {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
-\r
-Done:\r
- free (CurFolderName);\r
- free (FileName);\r
-#endif\r
- return Status;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The API to parse the binary.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#ifndef _BINARY_PARSE_H_\r
-#define _BINARY_PARSE_H_ 1\r
-\r
-#include <FvLib.h>\r
-#include "Compress.h"\r
-#include "Decompress.h"\r
-#include "CommonLib.h"\r
-#include "EfiUtilityMsgs.h"\r
-#include "FirmwareVolumeBufferLib.h"\r
-#include "OsPath.h"\r
-#include "ParseGuidedSectionTools.h"\r
-#include "StringFuncs.h"\r
-#include "ParseInf.h"\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Common/UefiInternalFormRepresentation.h>\r
-#include <Common/UefiCapsule.h>\r
-#include <Common/PiFirmwareFile.h>\r
-#include <Common/PiFirmwareVolume.h>\r
-#include <Guid/PiFirmwareFileSystem.h>\r
-#include <IndustryStandard/PeImage.h>\r
-#include <Protocol/GuidedSectionExtraction.h>\r
-\r
-#ifdef __GNUC__\r
-#define OS_SEP '/'\r
-#define OS_SEP_STR "/"\r
-#else\r
-#define OS_SEP '\\'\r
-#define OS_SEP_STR "\\"\r
-#endif\r
-\r
-#if defined(_MSC_VER) && _MSC_VER < 1900\r
-#define snprintf _snprintf\r
-#endif\r
-\r
-#define TEMP_DIR_NAME "Temp"\r
-#define MAX_FILENAME_LEN 200\r
-#define MAX_MATCH_GUID_NUM 100\r
-#define MAX_EFI_IN_FFS_NUM 100\r
-\r
-typedef struct {\r
- VOID *Fd;\r
- UINT32 FdSize;\r
- UINTN EfiVariableAddr;\r
- UINTN Length[MAX_EFI_IN_FFS_NUM];\r
- VOID *FfsArray[MAX_EFI_IN_FFS_NUM];\r
- VOID *StorageFfsInBfv;\r
- VOID *NvStoreDatabase;\r
- BOOLEAN ExistNvStoreDatabase;\r
-} G_EFI_FD_INFO;\r
-\r
-///\r
-///Define the structure for th sections\r
-///\r
-typedef struct {\r
- UINTN BufferBase;\r
- UINTN UncompressedBuffer[MAX_EFI_IN_FFS_NUM];\r
- UINTN Length;\r
- UINT8 UnCompressIndex;\r
-} EFI_SECTION_STRUCT;\r
-\r
-// {d0bc7cb4-6a47-495f-aa11-710746da06a2}\r
-#define EFI_VFR_ATTRACT_GUID \\r
-{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }\r
-\r
-// {8913C5E0-33F6-4d86-9BF1-43EF89FC0666}\r
-#define EFI_UNI_STR_ATTRACT_GUID \\r
-{ 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
-\r
-// {FFF12B8D-7696-4C8B-A985-2747075B4F50}\r
-#define EFI_SYSTEM_NVDATA_FV_GUID \\r
-{ 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}\r
-\r
-/**\r
- Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS.\r
-\r
- @param SectionBuffer The section base address\r
- @param BufferLength The length of FFS.\r
- @param EfiBufferHeader The structure dual pointer to the efi informations\r
-\r
- @retval EFI_SUCCESS The application exited normally.\r
- @retval EFI_ABORTED An error occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSection (\r
- IN BOOLEAN IsFfsOrEfi,\r
- IN OUT UINT8 *SectionBuffer,\r
- IN UINT32 BufferLength,\r
- IN OUT EFI_SECTION_STRUCT **EfiBufferHeader\r
- );\r
-\r
-/**\r
- Search the VfrBin Base address.\r
-\r
- According the known GUID gVfrArrayAttractGuid to get the base address from FFS.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param EfiAddr the Pointer to the EFI in FFS\r
- @param Length the length of Fv\r
- @param Offset the Pointer to the Addr (Offset)\r
- @param NumOfMachingOffset the number of Addr (Offset)\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-SearchVfrBinInFFS (\r
- IN VOID *Fv,\r
- IN VOID *EfiAddr,\r
- IN UINTN Length,\r
- OUT UINTN **Offset,\r
- OUT UINT8 *NumOfMachingOffset\r
- );\r
-\r
-/**\r
- Search the UniBin Base address.\r
-\r
- According the known GUID gUniStrArrayAttractGuid to get the base address from FFS.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param EfiAddr the Pointer to the EFI in FFS\r
- @param Length the length of Fv\r
- @param Offset the Pointer to the Addr (Offset)\r
-\r
- @retval Base address Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-SearchUniBinInFFS (\r
- IN VOID *Fv,\r
- IN VOID *EfiAddr,\r
- IN UINTN Length,\r
- OUT UINTN **Offset\r
- );\r
-\r
-/**\r
- Read the file to memory.\r
-\r
- @param InputFile The file that contains the FV image.\r
- @param Size The size of the file.\r
-\r
- @retval The pointer to the begining position of memory.\r
-**/\r
-VOID *\r
-ReadFileToMemory (\r
- IN CHAR8 *FileName,\r
- OUT UINT32 *Size\r
- );\r
-\r
-/**\r
- Search the EFI variables address in Fd.\r
-\r
- Open and read the *.fd to the memory, initialize the global structure.\r
- Update the EFI variables addr and the begining position of memory.\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-EFI_STATUS\r
-GetEfiVariablesAddr (\r
- BOOLEAN UqiIsSet\r
- );\r
-\r
-/**\r
- Pick up the FFS which includes IFR section.\r
-\r
- Parse all FFS extracted by BfmLib, and save all which includes IFR\r
- Binary to gEfiFdInfo structure.\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_BUFFER_TOO_SMALL Memory can't be allocated.\r
- @retval EFI_ABORTED Read FFS Failed.\r
-**/\r
-EFI_STATUS\r
-FindFileInFolder (\r
- IN CHAR8 *FolderName,\r
- OUT BOOLEAN *ExistStorageInBfv,\r
- OUT BOOLEAN *SizeOptimized\r
-);\r
-\r
-#endif\r
-\r
+++ /dev/null
-/** @file\r
-\r
- Common library.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#include "Common.h"\r
-\r
-#define WARNING_STATUS_NUMBER 4\r
-#define ERROR_STATUS_NUMBER 24\r
-\r
-CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
-\r
-CONST CHAR8 *mStatusString[] = {\r
- "Success", // RETURN_SUCCESS = 0\r
- "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1\r
- "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2\r
- "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3\r
- "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4\r
- "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT\r
- "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT\r
- "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT\r
- "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT\r
- "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT\r
- "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT\r
- "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT\r
- "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT\r
- "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT\r
- "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT\r
- "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT\r
- "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT\r
- "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT\r
- "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT\r
- "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT\r
- "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT\r
- "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT\r
- "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT\r
- "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT\r
- "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT\r
- "Aborted", // RETURN_ABORTED = 21 | MAX_BIT\r
- "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT\r
- "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT\r
- "Protocol Error" // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT\r
-};\r
-\r
-/**\r
- Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
- string and returns the new Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then return NULL.\r
- If Destination is not aligned on a 16-bit boundary, then return NULL.\r
-\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
- @param Source A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
-\r
-**/\r
-CHAR16 *\r
-StrCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- ReturnValue = NULL;\r
-\r
- if ((Destination == NULL) || ((UINTN) Destination % 2 != 0)) {\r
- return NULL;\r
- }\r
-\r
- ReturnValue = Destination;\r
- while (*Source != 0) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Returns the length of a Null-terminated Unicode string.\r
-\r
- This function returns the number of Unicode characters in the Null-terminated\r
- Unicode string specified by String.\r
-\r
- If String is NULL, then return 0.\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @return The length of String.\r
-\r
-**/\r
-UINTN\r
-FceStrLen (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- UINTN Length;\r
-\r
- if (String == NULL) {\r
- return 0;\r
- }\r
- for (Length = 0; *String != L'\0'; String++, Length++) {\r
- ;\r
- }\r
- return Length;\r
-}\r
-\r
-/**\r
- Returns the size of a Null-terminated Unicode string in bytes, including the\r
- Null terminator.\r
-\r
- This function returns the size, in bytes, of the Null-terminated Unicode string\r
- specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned on a 16-bit boundary, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @return The size of String.\r
-\r
-**/\r
-UINTN\r
-FceStrSize (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- return (FceStrLen (String) + 1) * sizeof (*String);\r
-}\r
-\r
-/**\r
- Compares two Null-terminated Unicode strings, and returns the difference\r
- between the first mismatched Unicode characters.\r
-\r
- This function compares the Null-terminated Unicode string FirstString to the\r
- Null-terminated Unicode string SecondString. If FirstString is identical to\r
- SecondString, then 0 is returned. Otherwise, the value returned is the first\r
- mismatched Unicode character in SecondString subtracted from the first\r
- mismatched Unicode character in FirstString.\r
-\r
- @param FirstString A pointer to a Null-terminated Unicode string.\r
- @param SecondString A pointer to a Null-terminated Unicode string.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @return others FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-FceStrCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString\r
- )\r
-{\r
- while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
- FirstString++;\r
- SecondString++;\r
- }\r
- return *FirstString - *SecondString;\r
-}\r
-\r
-/**\r
- Concatenates one Null-terminated Unicode string to another Null-terminated\r
- Unicode string, and returns the concatenated Unicode string.\r
-\r
- This function concatenates two Null-terminated Unicode strings. The contents\r
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination. The Null-terminated concatenated\r
- Unicode String is returned. If Source and Destination overlap, then the\r
- results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
- and Source results in a Unicode string with more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
- @param Source A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
-\r
-**/\r
-CHAR16 *\r
-StrCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- StrCpy (Destination + FceStrLen (Destination), Source);\r
-\r
- //\r
- // Size of the resulting string should never be zero.\r
- // PcdMaximumUnicodeStringLength is tested inside FceStrLen().\r
- //\r
- ASSERT (FceStrSize (Destination) != 0);\r
- return Destination;\r
-}\r
-\r
-/**\r
- Returns the first occurrence of a Null-terminated Unicode sub-string\r
- in a Null-terminated Unicode string.\r
-\r
- This function scans the contents of the Null-terminated Unicode string\r
- specified by String and returns the first occurrence of SearchString.\r
- If SearchString is not found in String, then NULL is returned. If\r
- the length of SearchString is zero, then String is\r
- returned.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned on a 16-bit boundary, then ASSERT().\r
- If SearchString is NULL, then ASSERT().\r
- If SearchString is not aligned on a 16-bit boundary, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and SearchString\r
- or String contains more than PcdMaximumUnicodeStringLength Unicode\r
- characters, not including the Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
- @param SearchString A pointer to a Null-terminated Unicode string to search for.\r
-\r
- @retval NULL If the SearchString does not appear in String.\r
- @return others If there is a match.\r
-\r
-**/\r
-CHAR16 *\r
-StrStr (\r
- IN CONST CHAR16 *String,\r
- IN CONST CHAR16 *SearchString\r
- )\r
-{\r
- CONST CHAR16 *FirstMatch;\r
- CONST CHAR16 *SearchStringTmp;\r
-\r
- //\r
- // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside FceStrLen().\r
- //\r
- ASSERT (FceStrSize (String) != 0);\r
- ASSERT (FceStrSize (SearchString) != 0);\r
-\r
- if (*SearchString == L'\0') {\r
- return (CHAR16 *) String;\r
- }\r
-\r
- while (*String != L'\0') {\r
- SearchStringTmp = SearchString;\r
- FirstMatch = String;\r
-\r
- while ((*String == *SearchStringTmp)\r
- && (*String != L'\0')) {\r
- String++;\r
- SearchStringTmp++;\r
- }\r
-\r
- if (*SearchStringTmp == L'\0') {\r
- return (CHAR16 *) FirstMatch;\r
- }\r
-\r
- if (*String == L'\0') {\r
- return NULL;\r
- }\r
-\r
- String = FirstMatch + 1;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-/**\r
- Convert one Null-terminated ASCII string to a Null-terminated\r
- Unicode string and returns the Unicode string.\r
-\r
- This function converts the contents of the ASCII string Source to the Unicode\r
- string Destination, and returns Destination. The function terminates the\r
- Unicode string Destination by appending a Null-terminator character at the end.\r
- The caller is responsible to make sure Destination points to a buffer with size\r
- equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
-\r
- @param Source A pointer to a Null-terminated ASCII string.\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
- @return NULL If Destination or Source is NULL, return NULL.\r
-\r
-**/\r
-CHAR16 *\r
-AsciiStrToUnicodeStr (\r
- IN CONST CHAR8 *Source,\r
- OUT CHAR16 *Destination\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- ReturnValue = NULL;\r
-\r
- if ((Destination == NULL) || (Source == NULL) || (strlen (Source) == 0)) {\r
- return NULL;\r
- }\r
- ReturnValue = Destination;\r
- while (*Source != '\0') {\r
- *(Destination++) = (CHAR16) *(Source++);\r
- }\r
- //\r
- // End the Destination with a NULL.\r
- //\r
- *Destination = '\0';\r
-\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Internal function that convert a number to a string in Buffer.\r
-\r
- Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.\r
-\r
- @param Buffer Location to place the ASCII string of Value.\r
- @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.\r
- @param Radix Radix of the value\r
-\r
- @return A pointer to the end of buffer filled with ASCII string.\r
-\r
-**/\r
-CHAR8 *\r
-BasePrintLibValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN INT64 Value,\r
- IN UINTN Radix\r
- )\r
-{\r
- UINT32 Remainder;\r
-\r
- //\r
- // Loop to convert one digit at a time in reverse order\r
- //\r
- *Buffer = 0;\r
- do {\r
- Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);\r
- *(++Buffer) = mHexStr[Remainder];\r
- } while (Value != 0);\r
-\r
- //\r
- // Return pointer of the end of filled buffer.\r
- //\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Reads a 16-bit value from memory that may be unaligned.\r
-\r
- This function returns the 16-bit value pointed to by Buffer. The function\r
- guarantees that the read operation does not produce an alignment fault.\r
-\r
- If the Buffer is NULL, then ASSERT().\r
-\r
- @param Buffer A pointer to a 16-bit value that may be unaligned.\r
-\r
- @return The 16-bit value read from Buffer.\r
-\r
-**/\r
-UINT16\r
-FceReadUnaligned16 (\r
- IN CONST UINT16 *Buffer\r
- )\r
-{\r
- ASSERT (Buffer != NULL);\r
-\r
- return *Buffer;\r
-}\r
-\r
-/**\r
- Reads a 32-bit value from memory that may be unaligned.\r
-\r
- This function returns the 32-bit value pointed to by Buffer. The function\r
- guarantees that the read operation does not produce an alignment fault.\r
-\r
- If the Buffer is NULL, then ASSERT().\r
-\r
- @param Buffer A pointer to a 32-bit value that may be unaligned.\r
-\r
- @return The 32-bit value read from Buffer.\r
-\r
-**/\r
-UINT32\r
-ReadUnaligned32 (\r
- IN CONST UINT32 *Buffer\r
- )\r
-{\r
- ASSERT (Buffer != NULL);\r
-\r
- return *Buffer;\r
-}\r
-\r
-/**\r
- Internal function that places the character into the Buffer.\r
-\r
- Internal function that places ASCII or Unicode character into the Buffer.\r
-\r
- @param Buffer The buffer to place the Unicode or ASCII string.\r
- @param EndBuffer The end of the input Buffer. No characters will be\r
- placed after that.\r
- @param Length The count of character to be placed into Buffer.\r
- (Negative value indicates no buffer fill.)\r
- @param Character The character to be placed into Buffer.\r
- @param Increment The character increment in Buffer.\r
-\r
- @return Buffer.\r
-\r
-**/\r
-CHAR8 *\r
-BasePrintLibFillBuffer (\r
- OUT CHAR8 *Buffer,\r
- IN CHAR8 *EndBuffer,\r
- IN INTN Length,\r
- IN UINTN Character,\r
- IN INTN Increment\r
- )\r
-{\r
- INTN Index;\r
-\r
- for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {\r
- *Buffer = (CHAR8) Character;\r
- if (Increment != 1) {\r
- *(Buffer + 1) = (CHAR8)(Character >> 8);\r
- }\r
- Buffer += Increment;\r
- }\r
-\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Worker function that produces a Null-terminated string in an output buffer\r
- based on a Null-terminated format string and a VA_LIST argument list.\r
-\r
- VSPrint function to process format and place the results in Buffer. Since a\r
- VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
- this is the main print working routine.\r
-\r
- If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.\r
-\r
- @param[out] Buffer The character buffer to print the results of the\r
- parsing of Format into.\r
- @param[in] BufferSize The maximum number of characters to put into\r
- buffer.\r
- @param[in] Flags Initial flags value.\r
- Can only have FORMAT_UNICODE, OUTPUT_UNICODE,\r
- and COUNT_ONLY_NO_PRINT set.\r
- @param[in] Format A Null-terminated format string.\r
- @param[in] VaListMarker VA_LIST style variable argument list consumed by\r
- processing Format.\r
- @param[in] BaseListMarker BASE_LIST style variable argument list consumed\r
- by processing Format.\r
-\r
- @return The number of characters printed not including the Null-terminator.\r
- If COUNT_ONLY_NO_PRINT was set returns the same, but without any\r
- modification to Buffer.\r
-\r
-**/\r
-UINTN\r
-BasePrintLibSPrintMarker (\r
- OUT CHAR8 *Buffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *Format,\r
- IN VA_LIST VaListMarker, OPTIONAL\r
- IN BASE_LIST BaseListMarker OPTIONAL\r
- )\r
-{\r
- CHAR8 *OriginalBuffer;\r
- CHAR8 *EndBuffer;\r
- CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
- UINT32 BytesPerOutputCharacter;\r
- UINTN BytesPerFormatCharacter;\r
- UINTN FormatMask;\r
- UINTN FormatCharacter;\r
- UINTN Width;\r
- UINTN Precision;\r
- INT64 Value;\r
- CONST CHAR8 *ArgumentString;\r
- UINTN Character;\r
- EFI_GUID *TmpGuid;\r
- TIME *TmpTime;\r
- UINTN Count;\r
- UINTN ArgumentMask;\r
- INTN BytesPerArgumentCharacter;\r
- UINTN ArgumentCharacter;\r
- BOOLEAN Done;\r
- UINTN Index;\r
- CHAR8 Prefix;\r
- BOOLEAN ZeroPad;\r
- BOOLEAN Comma;\r
- UINTN Digits;\r
- UINTN Radix;\r
- RETURN_STATUS Status;\r
- UINT32 GuidData1;\r
- UINT16 GuidData2;\r
- UINT16 GuidData3;\r
- UINTN LengthToReturn;\r
-\r
- //\r
- // If you change this code be sure to match the 2 versions of this function.\r
- // Nearly identical logic is found in the BasePrintLib and\r
- // DxePrintLibPrint2Protocol (both PrintLib instances).\r
- //\r
-\r
- if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {\r
- if (BufferSize == 0) {\r
- Buffer = NULL;\r
- }\r
- } else {\r
- //\r
- // We can run without a Buffer for counting only.\r
- //\r
- if (BufferSize == 0) {\r
- return 0;\r
- }\r
- ASSERT (Buffer != NULL);\r
- }\r
-\r
- if ((Flags & OUTPUT_UNICODE) != 0) {\r
- BytesPerOutputCharacter = 2;\r
- } else {\r
- BytesPerOutputCharacter = 1;\r
- }\r
-\r
- LengthToReturn = 0;\r
-\r
- //\r
- // Reserve space for the Null terminator.\r
- //\r
- BufferSize--;\r
- OriginalBuffer = Buffer;\r
-\r
- //\r
- // Set the tag for the end of the input Buffer.\r
- //\r
- EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;\r
-\r
- if ((Flags & FORMAT_UNICODE) != 0) {\r
- //\r
- // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength\r
- // Unicode characters if PcdMaximumUnicodeStringLength is not zero.\r
- //\r
- ASSERT (FceStrSize ((CHAR16 *) Format) != 0);\r
- BytesPerFormatCharacter = 2;\r
- FormatMask = 0xffff;\r
- } else {\r
- //\r
- // Make sure format string cannot contain more than PcdMaximumAsciiStringLength\r
- // Ascii characters if PcdMaximumAsciiStringLength is not zero.\r
- //\r
- ASSERT (strlen (Format) + 1 != 0);\r
- BytesPerFormatCharacter = 1;\r
- FormatMask = 0xff;\r
- }\r
-\r
- //\r
- // Get the first character from the format string\r
- //\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
-\r
- //\r
- // Loop until the end of the format string is reached or the output buffer is full\r
- //\r
- while (FormatCharacter != 0 && Buffer < EndBuffer) {\r
- //\r
- // Clear all the flag bits except those that may have been passed in\r
- //\r
- Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);\r
-\r
- //\r
- // Set the default width to zero, and the default precision to 1\r
- //\r
- Width = 0;\r
- Precision = 1;\r
- Prefix = 0;\r
- Comma = FALSE;\r
- ZeroPad = FALSE;\r
- Count = 0;\r
- Digits = 0;\r
-\r
- switch (FormatCharacter) {\r
- case '%':\r
- //\r
- // Parse Flags and Width\r
- //\r
- for (Done = FALSE; !Done; ) {\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- switch (FormatCharacter) {\r
- case '.':\r
- Flags |= PRECISION;\r
- break;\r
- case '-':\r
- Flags |= LEFT_JUSTIFY;\r
- break;\r
- case '+':\r
- Flags |= PREFIX_SIGN;\r
- break;\r
- case ' ':\r
- Flags |= PREFIX_BLANK;\r
- break;\r
- case ',':\r
- Flags |= COMMA_TYPE;\r
- break;\r
- case 'L':\r
- case 'l':\r
- Flags |= LONG_TYPE;\r
- break;\r
- case '*':\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PAD_TO_WIDTH;\r
- if (BaseListMarker == NULL) {\r
- Width = VA_ARG (VaListMarker, UINTN);\r
- } else {\r
- Width = BASE_ARG (BaseListMarker, UINTN);\r
- }\r
- } else {\r
- if (BaseListMarker == NULL) {\r
- Precision = VA_ARG (VaListMarker, UINTN);\r
- } else {\r
- Precision = BASE_ARG (BaseListMarker, UINTN);\r
- }\r
- }\r
- break;\r
- case '0':\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PREFIX_ZERO;\r
- }\r
- case '1':\r
- case '2':\r
- case '3':\r
- case '4':\r
- case '5':\r
- case '6':\r
- case '7':\r
- case '8':\r
- case '9':\r
- for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){\r
- Count = (Count * 10) + FormatCharacter - '0';\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- }\r
- Format -= BytesPerFormatCharacter;\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PAD_TO_WIDTH;\r
- Width = Count;\r
- } else {\r
- Precision = Count;\r
- }\r
- break;\r
-\r
- case '\0':\r
- //\r
- // Make no output if Format string terminates unexpectedly when\r
- // looking up for flag, width, precision and type.\r
- //\r
- Format -= BytesPerFormatCharacter;\r
- Precision = 0;\r
- //\r
- // break skipped on purpose.\r
- //\r
- default:\r
- Done = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Handle each argument type\r
- //\r
- switch (FormatCharacter) {\r
- case 'p':\r
- //\r
- // Flag space, +, 0, L & l are invalid for type p.\r
- //\r
- Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE);\r
- if (sizeof (VOID *) > 4) {\r
- Flags |= LONG_TYPE;\r
- }\r
- case 'X':\r
- Flags |= PREFIX_ZERO;\r
- //\r
- // break skipped on purpose\r
- //\r
- case 'x':\r
- Flags |= RADIX_HEX;\r
- //\r
- // break skipped on purpose\r
- //\r
- case 'd':\r
- if ((Flags & LONG_TYPE) == 0) {\r
- //\r
- // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
- // This assumption is made so the format string definition is compatible with the ANSI C\r
- // Specification for formatted strings. It is recommended that the Base Types be used\r
- // everywhere, but in this one case, compliance with ANSI C is more important, and\r
- // provides an implementation that is compatible with that largest possible set of CPU\r
- // architectures. This is why the type "int" is used in this one case.\r
- //\r
- if (BaseListMarker == NULL) {\r
- Value = VA_ARG (VaListMarker, int);\r
- } else {\r
- Value = BASE_ARG (BaseListMarker, int);\r
- }\r
- } else {\r
- if (BaseListMarker == NULL) {\r
- Value = VA_ARG (VaListMarker, INT64);\r
- } else {\r
- Value = BASE_ARG (BaseListMarker, INT64);\r
- }\r
- }\r
- if ((Flags & PREFIX_BLANK) != 0) {\r
- Prefix = ' ';\r
- }\r
- if ((Flags & PREFIX_SIGN) != 0) {\r
- Prefix = '+';\r
- }\r
- if ((Flags & COMMA_TYPE) != 0) {\r
- Comma = TRUE;\r
- }\r
- if ((Flags & RADIX_HEX) == 0) {\r
- Radix = 10;\r
- if (Comma) {\r
- Flags &= (~PREFIX_ZERO);\r
- Precision = 1;\r
- }\r
- if (Value < 0) {\r
- Flags |= PREFIX_SIGN;\r
- Prefix = '-';\r
- Value = -Value;\r
- }\r
- } else {\r
- Radix = 16;\r
- Comma = FALSE;\r
- if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
- //\r
- // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
- // This assumption is made so the format string definition is compatible with the ANSI C\r
- // Specification for formatted strings. It is recommended that the Base Types be used\r
- // everywhere, but in this one case, compliance with ANSI C is more important, and\r
- // provides an implementation that is compatible with that largest possible set of CPU\r
- // architectures. This is why the type "unsigned int" is used in this one case.\r
- //\r
- Value = (unsigned int)Value;\r
- }\r
- }\r
- //\r
- // Convert Value to a reversed string\r
- //\r
- Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;\r
- if (Value == 0 && Precision == 0) {\r
- Count = 0;\r
- }\r
- ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
-\r
- Digits = Count % 3;\r
- if (Digits != 0) {\r
- Digits = 3 - Digits;\r
- }\r
- if (Comma && Count != 0) {\r
- Count += ((Count - 1) / 3);\r
- }\r
- if (Prefix != 0) {\r
- Count++;\r
- Precision++;\r
- }\r
- Flags |= ARGUMENT_REVERSED;\r
- ZeroPad = TRUE;\r
- if ((Flags & PREFIX_ZERO) != 0) {\r
- if ((Flags & LEFT_JUSTIFY) == 0) {\r
- if ((Flags & PAD_TO_WIDTH) != 0) {\r
- if ((Flags & PRECISION) == 0) {\r
- Precision = Width;\r
- }\r
- }\r
- }\r
- }\r
- break;\r
-\r
- case 's':\r
- case 'S':\r
- Flags |= ARGUMENT_UNICODE;\r
- //\r
- // break skipped on purpose\r
- //\r
- case 'a':\r
- if (BaseListMarker == NULL) {\r
- ArgumentString = VA_ARG (VaListMarker, CHAR8 *);\r
- } else {\r
- ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);\r
- }\r
- if (ArgumentString == NULL) {\r
- Flags &= (~ARGUMENT_UNICODE);\r
- ArgumentString = "<null string>";\r
- }\r
- //\r
- // Set the default precision for string to be zero if not specified.\r
- //\r
- if ((Flags & PRECISION) == 0) {\r
- Precision = 0;\r
- }\r
- break;\r
-\r
- case 'c':\r
- if (BaseListMarker == NULL) {\r
- Character = VA_ARG (VaListMarker, UINTN) & 0xffff;\r
- } else {\r
- Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;\r
- }\r
- ArgumentString = (CHAR8 *)&Character;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
-\r
- case 'g':\r
- if (BaseListMarker == NULL) {\r
- TmpGuid = VA_ARG (VaListMarker, EFI_GUID *);\r
- } else {\r
- TmpGuid = BASE_ARG (BaseListMarker, EFI_GUID *);\r
- }\r
- if (TmpGuid == NULL) {\r
- ArgumentString = "<null guid>";\r
- } else {\r
- GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));\r
- GuidData2 = FceReadUnaligned16 (&(TmpGuid->Data2));\r
- GuidData3 = FceReadUnaligned16 (&(TmpGuid->Data3));\r
- BasePrintLibSPrint (\r
- ValueBuffer,\r
- MAXIMUM_VALUE_CHARACTERS,\r
- 0,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
- GuidData1,\r
- GuidData2,\r
- GuidData3,\r
- TmpGuid->Data4[0],\r
- TmpGuid->Data4[1],\r
- TmpGuid->Data4[2],\r
- TmpGuid->Data4[3],\r
- TmpGuid->Data4[4],\r
- TmpGuid->Data4[5],\r
- TmpGuid->Data4[6],\r
- TmpGuid->Data4[7]\r
- );\r
- ArgumentString = ValueBuffer;\r
- }\r
- break;\r
-\r
- case 't':\r
- if (BaseListMarker == NULL) {\r
- TmpTime = VA_ARG (VaListMarker, TIME *);\r
- } else {\r
- TmpTime = BASE_ARG (BaseListMarker, TIME *);\r
- }\r
- if (TmpTime == NULL) {\r
- ArgumentString = "<null time>";\r
- } else {\r
- BasePrintLibSPrint (\r
- ValueBuffer,\r
- MAXIMUM_VALUE_CHARACTERS,\r
- 0,\r
- "%02d/%02d/%04d %02d:%02d",\r
- TmpTime->Month,\r
- TmpTime->Day,\r
- TmpTime->Year,\r
- TmpTime->Hour,\r
- TmpTime->Minute\r
- );\r
- ArgumentString = ValueBuffer;\r
- }\r
- break;\r
-\r
- case 'r':\r
- if (BaseListMarker == NULL) {\r
- Status = VA_ARG (VaListMarker, RETURN_STATUS);\r
- } else {\r
- Status = BASE_ARG (BaseListMarker, RETURN_STATUS);\r
- }\r
- ArgumentString = ValueBuffer;\r
- if (RETURN_ERROR (Status)) {\r
- //\r
- // Clear error bit\r
- //\r
- Index = Status & ~MAX_BIT;\r
- if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {\r
- ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];\r
- }\r
- } else {\r
- Index = Status;\r
- if (Index <= WARNING_STATUS_NUMBER) {\r
- ArgumentString = mStatusString [Index];\r
- }\r
- }\r
- if (ArgumentString == ValueBuffer) {\r
- BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);\r
- }\r
- break;\r
-\r
- case '\r':\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- if (FormatCharacter == '\n') {\r
- //\r
- // Translate '\r\n' to '\r\n'\r
- //\r
- ArgumentString = "\r\n";\r
- } else {\r
- //\r
- // Translate '\r' to '\r'\r
- //\r
- ArgumentString = "\r";\r
- Format -= BytesPerFormatCharacter;\r
- }\r
- break;\r
-\r
- case '\n':\r
- //\r
- // Translate '\n' to '\r\n' and '\n\r' to '\r\n'\r
- //\r
- ArgumentString = "\r\n";\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- if (FormatCharacter != '\r') {\r
- Format -= BytesPerFormatCharacter;\r
- }\r
- break;\r
-\r
- case '%':\r
- default:\r
- //\r
- // if the type is '%' or unknown, then print it to the screen\r
- //\r
- ArgumentString = (CHAR8 *)&FormatCharacter;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
- }\r
- break;\r
-\r
- case '\r':\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- if (FormatCharacter == '\n') {\r
- //\r
- // Translate '\r\n' to '\r\n'\r
- //\r
- ArgumentString = "\r\n";\r
- } else {\r
- //\r
- // Translate '\r' to '\r'\r
- //\r
- ArgumentString = "\r";\r
- Format -= BytesPerFormatCharacter;\r
- }\r
- break;\r
-\r
- case '\n':\r
- //\r
- // Translate '\n' to '\r\n' and '\n\r' to '\r\n'\r
- //\r
- ArgumentString = "\r\n";\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- if (FormatCharacter != '\r') {\r
- Format -= BytesPerFormatCharacter;\r
- }\r
- break;\r
-\r
- default:\r
- ArgumentString = (CHAR8 *)&FormatCharacter;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
- }\r
-\r
- //\r
- // Retrieve the ArgumentString attriubutes\r
- //\r
- if ((Flags & ARGUMENT_UNICODE) != 0) {\r
- ArgumentMask = 0xffff;\r
- BytesPerArgumentCharacter = 2;\r
- } else {\r
- ArgumentMask = 0xff;\r
- BytesPerArgumentCharacter = 1;\r
- }\r
- if ((Flags & ARGUMENT_REVERSED) != 0) {\r
- BytesPerArgumentCharacter = -BytesPerArgumentCharacter;\r
- } else {\r
- //\r
- // Compute the number of characters in ArgumentString and store it in Count\r
- // ArgumentString is either null-terminated, or it contains Precision characters\r
- //\r
- for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
- ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
- if (ArgumentCharacter == 0) {\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (Precision < Count) {\r
- Precision = Count;\r
- }\r
-\r
- //\r
- // Pad before the string\r
- //\r
- if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {\r
- LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
- }\r
- }\r
-\r
- if (ZeroPad) {\r
- if (Prefix != 0) {\r
- LengthToReturn += (1 * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);\r
- }\r
- }\r
- LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);\r
- }\r
- } else {\r
- LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);\r
- }\r
- if (Prefix != 0) {\r
- LengthToReturn += (1 * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Output the Prefix character if it is present\r
- //\r
- Index = 0;\r
- if (Prefix != 0) {\r
- Index++;\r
- }\r
-\r
- //\r
- // Copy the string into the output buffer performing the required type conversions\r
- //\r
- while (Index < Count) {\r
- ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
-\r
- LengthToReturn += (1 * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);\r
- }\r
- ArgumentString += BytesPerArgumentCharacter;\r
- Index++;\r
- if (Comma) {\r
- Digits++;\r
- if (Digits == 3) {\r
- Digits = 0;\r
- Index++;\r
- if (Index < Count) {\r
- LengthToReturn += (1 * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Pad after the string\r
- //\r
- if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {\r
- LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);\r
- if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
- }\r
- }\r
-\r
- //\r
- // Get the next character from the format string\r
- //\r
- Format += BytesPerFormatCharacter;\r
-\r
- //\r
- // Get the next character from the format string\r
- //\r
- FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
- }\r
-\r
- if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {\r
- return (LengthToReturn / BytesPerOutputCharacter);\r
- }\r
-\r
- ASSERT (Buffer != NULL);\r
- //\r
- // Null terminate the Unicode or ASCII string\r
- //\r
- BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);\r
- //\r
- // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength\r
- // Unicode characters if PcdMaximumUnicodeStringLength is not zero.\r
- //\r
- ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (FceStrSize ((CHAR16 *) OriginalBuffer) != 0));\r
- //\r
- // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength\r
- // ASCII characters if PcdMaximumAsciiStringLength is not zero.\r
- //\r
- ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || ((strlen (OriginalBuffer) + 1) != 0));\r
-\r
- return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);\r
-}\r
-\r
-/**\r
- Worker function that produces a Null-terminated string in an output buffer\r
- based on a Null-terminated format string and variable argument list.\r
-\r
- VSPrint function to process format and place the results in Buffer. Since a\r
- VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
- this is the main print working routine\r
-\r
- @param StartOfBuffer The character buffer to print the results of the parsing\r
- of Format into.\r
- @param BufferSize The maximum number of characters to put into buffer.\r
- Zero means no limit.\r
- @param Flags Initial flags value.\r
- Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
- @param FormatString A Null-terminated format string.\r
- @param ... The variable argument list.\r
-\r
- @return The number of characters printed.\r
-\r
-**/\r
-UINTN\r
-BasePrintLibSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);\r
-}\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on\r
- a Null-terminated Unicode format string and a VA_LIST argument list\r
-\r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list specified by Marker based on the\r
- contents of the format string.\r
- The number of Unicode characters in the produced output buffer is returned not including\r
- the Null-terminator.\r
- If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
- If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
- If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
- ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated\r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString A Null-terminated Unicode format string.\r
- @param Marker VA_LIST marker for the variable argument list.\r
-\r
- @return The number of Unicode characters in the produced output buffer not including the\r
- Null-terminator.\r
-\r
-**/\r
-UINTN\r
-UnicodeVSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- ASSERT_UNICODE_BUFFER (StartOfBuffer);\r
- ASSERT_UNICODE_BUFFER (FormatString);\r
- return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker, NULL);\r
-}\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
- Unicode format string and variable argument list.\r
-\r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the format string.\r
- The number of Unicode characters in the produced output buffer is returned not including\r
- the Null-terminator.\r
- If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
- If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
- If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
- ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated\r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString A Null-terminated Unicode format string.\r
- @param ... Variable argument list whose contents are accessed based on the\r
- format string specified by FormatString.\r
-\r
- @return The number of Unicode characters in the produced output buffer not including the\r
- Null-terminator.\r
-\r
-**/\r
-UINTN\r
-UnicodeSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
-}\r
-\r
-/**\r
- Convert a Null-terminated Unicode string to a Null-terminated\r
- ASCII string and returns the ASCII string.\r
-\r
- This function converts the content of the Unicode string Source\r
- to the ASCII string Destination by copying the lower 8 bits of\r
- each Unicode character. It returns Destination. The function terminates\r
- the ASCII string Destination by appending a Null-terminator character\r
- at the end. The caller is responsible to make sure Destination points\r
- to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- If any Unicode characters in Source contain non-zero value in\r
- the upper 8 bits, then ASSERT().\r
-\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
-\r
- @reture Destination\r
-\r
-**/\r
-CHAR8 *\r
-UnicodeStrToAsciiStr (\r
- IN CONST CHAR16 *Source,\r
- OUT CHAR8 *Destination\r
- )\r
-{\r
- CHAR8 *ReturnValue;\r
-\r
- ReturnValue = Destination;\r
- assert (Destination != NULL);\r
- assert (Source != NULL);\r
- assert (((UINTN) Source & 0x01) == 0);\r
-\r
- while (*Source != L'\0') {\r
- //\r
- // If any Unicode characters in Source contain\r
- // non-zero value in the upper 8 bits, then ASSERT().\r
- //\r
- assert (*Source < 0x100);\r
- *(ReturnValue++) = (CHAR8) *(Source++);\r
- }\r
-\r
- *ReturnValue = '\0';\r
-\r
- return Destination;\r
-}\r
-\r
-/**\r
- Allocate new memory and then copy the Unicode string Source to Destination.\r
-\r
- @param Dest Location to copy string\r
- @param Src String to copy\r
-\r
-**/\r
-VOID\r
-NewStringCpy (\r
- IN OUT CHAR16 **Dest,\r
- IN CHAR16 *Src\r
- )\r
-{\r
- if (*Dest != NULL) {\r
- FreePool (*Dest);\r
- }\r
- *Dest = FceAllocateCopyPool (FceStrSize (Src), Src);\r
- ASSERT (*Dest != NULL);\r
-}\r
-\r
-/**\r
- Check if a Unicode character is a decimal character.\r
-\r
- This internal function checks if a Unicode character is a\r
- decimal character. The valid decimal character is from\r
- L'0' to L'9'.\r
-\r
- @param Char The character to check against.\r
-\r
- @retval TRUE If the Char is a decmial character.\r
- @retval FALSE If the Char is not a decmial character.\r
-\r
-**/\r
-BOOLEAN\r
-FceInternalIsDecimalDigitCharacter (\r
- IN CHAR16 Char\r
- )\r
-{\r
- return (BOOLEAN) ((Char >= L'0') && (Char <= L'9'));\r
-}\r
-\r
-/**\r
- Convert a Unicode character to upper case only if\r
- it maps to a valid small-case ASCII character.\r
-\r
- This internal function only deal with Unicode character\r
- which maps to a valid small-case ASCII character, i.e.\r
- L'a' to L'z'. For other Unicode character, the input character\r
- is returned directly.\r
-\r
- @param Char The character to convert.\r
-\r
- @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
- @retval Unchanged Otherwise.\r
-\r
-**/\r
-CHAR16\r
-FceInternalCharToUpper (\r
- IN CHAR16 Char\r
- )\r
-{\r
- if ((Char >= L'a') && (Char <= L'z')) {\r
- return (CHAR16) (Char - (L'a' - L'A'));\r
- }\r
-\r
- return Char;\r
-}\r
-\r
-/**\r
- Convert a Unicode character to numerical value.\r
-\r
- This internal function only deal with Unicode character\r
- which maps to a valid hexadecimal ASII character, i.e.\r
- L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
- Unicode character, the value returned does not make sense.\r
-\r
- @param Char The character to convert.\r
-\r
- @return The numerical value converted.\r
-\r
-**/\r
-UINTN\r
-FceInternalHexCharToUintn (\r
- IN CHAR16 Char\r
- )\r
-{\r
- if (FceInternalIsDecimalDigitCharacter (Char)) {\r
- return Char - L'0';\r
- }\r
-\r
- return (UINTN) (10 + FceInternalCharToUpper (Char) - L'A');\r
-}\r
-\r
-/**\r
- Check if a Unicode character is a hexadecimal character.\r
-\r
- This internal function checks if a Unicode character is a\r
- decimal character. The valid hexadecimal character is\r
- L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
-\r
-\r
- @param Char The character to check against.\r
-\r
- @retval TRUE If the Char is a hexadecmial character.\r
- @retval FALSE If the Char is not a hexadecmial character.\r
-\r
-**/\r
-BOOLEAN\r
-FceInternalIsHexaDecimalDigitCharacter (\r
- IN CHAR16 Char\r
- )\r
-{\r
-\r
- return (BOOLEAN) (FceInternalIsDecimalDigitCharacter (Char) ||\r
- ((Char >= L'A') && (Char <= L'F')) ||\r
- ((Char >= L'a') && (Char <= L'f')));\r
-}\r
-\r
-\r
-/**\r
- Convert a Null-terminated Unicode decimal string to a value of\r
- type UINT64.\r
-\r
- This function returns a value of type UINT64 by interpreting the contents\r
- of the Unicode string specified by String as a decimal number. The format\r
- of the input Unicode string String is:\r
-\r
- [spaces] [decimal digits].\r
-\r
- The valid decimal digit character is in the range [0-9]. The\r
- function will ignore the pad space, which includes spaces or\r
- tab characters, before [decimal digits]. The running zero in the\r
- beginning of [decimal digits] will be ignored. Then, the function\r
- stops at the first character that is a not a valid decimal character\r
- or a Null-terminator, whichever one comes first.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned in a 16-bit boundary, then ASSERT().\r
- If String has only pad spaces, then 0 is returned.\r
- If String has no pad spaces or valid decimal digits,\r
- then 0 is returned.\r
- If the number represented by String overflows according\r
- to the range defined by UINT64, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains\r
- more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
- the Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @retval Value translated from String.\r
-\r
-**/\r
-UINT64\r
-FceStrDecimalToUint64 (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- UINT64 Result;\r
-\r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside FceStrLen().\r
- //\r
- ASSERT (FceStrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- Result = 0;\r
-\r
- while (FceInternalIsDecimalDigitCharacter (*String)) {\r
- //\r
- // If the number represented by String overflows according\r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));\r
-\r
- Result = MultU64x32 (Result, 10) + (*String - L'0');\r
- String++;\r
- }\r
-\r
- return Result;\r
-}\r
-\r
-\r
-/**\r
- Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
-\r
- This function returns a value of type UINT64 by interpreting the contents\r
- of the Unicode string specified by String as a hexadecimal number.\r
- The format of the input Unicode string String is\r
-\r
- [spaces][zeros][x][hexadecimal digits].\r
-\r
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
- If "x" appears in the input string, it must be prefixed with at least one 0.\r
- The function will ignore the pad space, which includes spaces or tab characters,\r
- before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
- [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
- first valid hexadecimal digit. Then, the function stops at the first character that is\r
- a not a valid hexadecimal character or NULL, whichever one comes first.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned in a 16-bit boundary, then ASSERT().\r
- If String has only pad spaces, then zero is returned.\r
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
- then zero is returned.\r
- If the number represented by String overflows according to the range defined by\r
- UINT64, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
- then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @retval Value translated from String.\r
-\r
-**/\r
-UINT64\r
-FceStrHexToUint64 (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- UINT64 Result;\r
-\r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside FceStrLen().\r
- //\r
- ASSERT (FceStrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- if (FceInternalCharToUpper (*String) == L'X') {\r
- ASSERT (*(String - 1) == L'0');\r
- if (*(String - 1) != L'0') {\r
- return 0;\r
- }\r
- //\r
- // Skip the 'X'\r
- //\r
- String++;\r
- }\r
-\r
- Result = 0;\r
-\r
- while (FceInternalIsHexaDecimalDigitCharacter (*String)) {\r
- //\r
- // If the Hex Number represented by String overflows according\r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= RShiftU64 (((UINT64) ~0) - FceInternalHexCharToUintn (*String) , 4));\r
-\r
- Result = LShiftU64 (Result, 4);\r
- Result = Result + FceInternalHexCharToUintn (*String);\r
- String++;\r
- }\r
-\r
- return Result;\r
-}\r
-\r
-\r
-CHAR16\r
-ToUpper (\r
- CHAR16 a\r
- )\r
-{\r
- if (('a' <= a) && (a <= 'z')) {\r
- return (CHAR16) (a - 0x20);\r
- } else {\r
- return a;\r
- }\r
-}\r
-\r
-CHAR16\r
-ToLower (\r
- CHAR16 a\r
- )\r
-{\r
- if (('A' <= a) && (a <= 'Z')) {\r
- return (CHAR16) (a + 0x20);\r
- } else {\r
- return a;\r
- }\r
-}\r
-\r
-/**\r
- Performs a case-insensitive comparison between a Null-terminated\r
- Unicode pattern string and a Null-terminated Unicode string.\r
-\r
- @param String - A pointer to a Null-terminated Unicode string.\r
- @param Pattern - A pointer to a Null-terminated Unicode pattern string.\r
-\r
-\r
- @retval TRUE - Pattern was found in String.\r
- @retval FALSE - Pattern was not found in String.\r
-\r
-**/\r
-BOOLEAN\r
-MetaiMatch (\r
- IN CHAR16 *String,\r
- IN CHAR16 *Pattern\r
- )\r
-{\r
- CHAR16 c;\r
- CHAR16 p;\r
-\r
- assert (String != NULL);\r
- assert (Pattern != NULL);\r
-\r
- for (;;) {\r
- p = *Pattern;\r
- Pattern += 1;\r
-\r
- if (p == 0) {\r
- //\r
- // End of pattern. If end of string, TRUE match\r
- //\r
- if (*String) {\r
- return FALSE;\r
- } else {\r
- return TRUE;\r
- }\r
-\r
- } else {\r
-\r
- c = *String;\r
- if (ToUpper (c) != ToUpper (p)) {\r
- return FALSE;\r
- }\r
-\r
- String += 1;\r
-\r
- }\r
-\r
- }\r
-\r
-}\r
-/**\r
- Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and\r
- generates a 64-bit unsigned result.\r
-\r
- This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit\r
- unsigned value Multiplier and generates a 64-bit unsigned result. This 64-\r
- bit unsigned result is returned.\r
-\r
- @param Multiplicand A 64-bit unsigned value.\r
- @param Multiplier A 32-bit unsigned value.\r
-\r
- @return Multiplicand * Multiplier.\r
-\r
-**/\r
-UINT64\r
-MultU64x32 (\r
- IN UINT64 Multiplicand,\r
- IN UINT32 Multiplier\r
- )\r
-{\r
- return Multiplicand * Multiplier;\r
-}\r
-\r
-/**\r
- Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates\r
- a 64-bit unsigned result.\r
-\r
- This function divides the 64-bit unsigned value Dividend by the 32-bit\r
- unsigned value Divisor and generates a 64-bit unsigned quotient. This\r
- function returns the 64-bit unsigned quotient.\r
-\r
- If Divisor is 0, then ASSERT().\r
-\r
- @param Dividend A 64-bit unsigned value.\r
- @param Divisor A 32-bit unsigned value.\r
-\r
- @return Dividend / Divisor\r
-\r
-**/\r
-UINT64\r
-DivU64x32 (\r
- IN UINT64 Dividend,\r
- IN UINT32 Divisor\r
- )\r
-{\r
- ASSERT (Divisor != 0);\r
- return Dividend / Divisor;\r
-}\r
-\r
-/**\r
- Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled\r
- with zeros. The shifted value is returned.\r
-\r
- This function shifts the 64-bit value Operand to the left by Count bits. The\r
- low Count bits are set to zero. The shifted value is returned.\r
-\r
- If Count is greater than 63, then ASSERT().\r
-\r
- @param Operand The 64-bit operand to shift left.\r
- @param Count The number of bits to shift left.\r
-\r
- @return Operand << Count.\r
-\r
-**/\r
-UINT64\r
-LShiftU64 (\r
- IN UINT64 Operand,\r
- IN UINTN Count\r
- )\r
-{\r
- ASSERT (Count < 64);\r
- return Operand << Count;\r
-}\r
-\r
-/**\r
- Shifts a 64-bit integer right between 0 and 63 bits. This high bits are\r
- filled with zeros. The shifted value is returned.\r
-\r
- This function shifts the 64-bit value Operand to the right by Count bits. The\r
- high Count bits are set to zero. The shifted value is returned.\r
-\r
- If Count is greater than 63, then ASSERT().\r
-\r
- @param Operand The 64-bit operand to shift right.\r
- @param Count The number of bits to shift right.\r
-\r
- @return Operand >> Count.\r
-\r
-**/\r
-UINT64\r
-RShiftU64 (\r
- IN UINT64 Operand,\r
- IN UINTN Count\r
- )\r
-\r
-{\r
- ASSERT (Count < 64);\r
- return Operand >> Count;\r
-}\r
-\r
-\r
-/**\r
- Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates\r
- a 64-bit unsigned result and an optional 32-bit unsigned remainder.\r
-\r
- This function divides the 64-bit unsigned value Dividend by the 32-bit\r
- unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder\r
- is not NULL, then the 32-bit unsigned remainder is returned in Remainder.\r
- This function returns the 64-bit unsigned quotient.\r
-\r
- If Divisor is 0, then ASSERT().\r
-\r
- @param Dividend A 64-bit unsigned value.\r
- @param Divisor A 32-bit unsigned value.\r
- @param Remainder A pointer to a 32-bit unsigned value. This parameter is\r
- optional and may be NULL.\r
-\r
- @return Dividend / Divisor\r
-\r
-**/\r
-UINT64\r
-DivU64x32Remainder (\r
- IN UINT64 Dividend,\r
- IN UINT32 Divisor,\r
- OUT UINT32 *Remainder\r
- )\r
-{\r
- ASSERT (Divisor != 0);\r
-\r
- if (Remainder != NULL) {\r
- *Remainder = (UINT32)(Dividend % Divisor);\r
- }\r
- return Dividend / Divisor;\r
-}\r
-\r
-/**\r
- Copies a buffer to an allocated buffer.\r
-\r
- Allocates the number bytes specified by AllocationSize, copies allocationSize bytes\r
- from Buffer to the newly allocated buffer, and returns a pointer to the allocated\r
- buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
- is not enough memory remaining to satisfy the request, then NULL is returned.\r
-\r
- If Buffer is NULL, then ASSERT().\r
-\r
- @param AllocationSize The number of bytes to allocate and zero.\r
- @param Buffer The buffer to copy to the allocated buffer.\r
-\r
- @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-FceAllocateCopyPool (\r
- IN UINTN AllocationSize,\r
- IN CONST VOID *Buffer\r
- )\r
-{\r
- VOID *Memory;\r
-\r
- Memory = NULL;\r
-\r
- if ((Buffer == NULL) || (AllocationSize == 0)) {\r
- return Memory;\r
- }\r
-\r
- Memory = calloc (AllocationSize, sizeof (CHAR8));\r
- if (Memory != NULL) {\r
- Memory = memcpy (Memory, Buffer, AllocationSize);\r
- }\r
- return Memory;\r
-}\r
-\r
-/**\r
- Initializes the head node of a doubly-linked list, and returns the pointer to\r
- the head node of the doubly-linked list.\r
-\r
- Initializes the forward and backward links of a new linked list. After\r
- initializing a linked list with this function, the other linked list\r
- functions may be used to add and remove nodes from the linked list. It is up\r
- to the caller of this function to allocate the memory for ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a new doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InitializeListHead (\r
- IN OUT LIST_ENTRY *ListHead\r
- )\r
-\r
-{\r
- assert (ListHead != NULL);\r
-\r
- ListHead->ForwardLink = ListHead;\r
- ListHead->BackLink = ListHead;\r
- return ListHead;\r
-}\r
-\r
-/**\r
- Adds a node to the beginning of a doubly-linked list, and returns the pointer\r
- to the head node of the doubly-linked list.\r
-\r
- Adds the node Entry at the beginning of the doubly-linked list denoted by\r
- ListHead, and returns ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If Entry is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r
- of nodes in ListHead, including the ListHead node, is greater than or\r
- equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
- @param Entry A pointer to a node that is to be inserted at the beginning\r
- of a doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InsertHeadList (\r
- IN OUT LIST_ENTRY *ListHead,\r
- IN OUT LIST_ENTRY *Entry\r
- )\r
-{\r
- assert ((ListHead != NULL) && (Entry != NULL));\r
-\r
- Entry->ForwardLink = ListHead->ForwardLink;\r
- Entry->BackLink = ListHead;\r
- Entry->ForwardLink->BackLink = Entry;\r
- ListHead->ForwardLink = Entry;\r
- return ListHead;\r
-}\r
-\r
-/**\r
- Adds a node to the end of a doubly-linked list, and returns the pointer to\r
- the head node of the doubly-linked list.\r
-\r
- Adds the node Entry to the end of the doubly-linked list denoted by ListHead,\r
- and returns ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If Entry is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r
- of nodes in ListHead, including the ListHead node, is greater than or\r
- equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
- @param Entry A pointer to a node that is to be added at the end of the\r
- doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InsertTailList (\r
- IN OUT LIST_ENTRY *ListHead,\r
- IN OUT LIST_ENTRY *Entry\r
- )\r
-{\r
- assert ((ListHead != NULL) && (Entry != NULL));\r
-\r
- Entry->ForwardLink = ListHead;\r
- Entry->BackLink = ListHead->BackLink;\r
- Entry->BackLink->ForwardLink = Entry;\r
- ListHead->BackLink = Entry;\r
- return ListHead;\r
-}\r
-\r
-/**\r
- Retrieves the first node of a doubly-linked list.\r
-\r
- Returns the first node of a doubly-linked list. List must have been\r
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
- If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
-\r
- @return The first node of a doubly-linked list.\r
- @retval NULL The list is empty.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetFirstNode (\r
- IN CONST LIST_ENTRY *List\r
- )\r
-{\r
- assert (List != NULL);\r
-\r
- return List->ForwardLink;\r
-}\r
-\r
-/**\r
- Retrieves the next node of a doubly-linked list.\r
-\r
- Returns the node of a doubly-linked list that follows Node.\r
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
- or InitializeListHead(). If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
- PcdMaximumLinkedListLenth nodes, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @return A pointer to the next node if one exists. Otherwise List is returned.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetNextNode (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- )\r
-{\r
- assert ((List != NULL) && (Node != NULL));\r
-\r
- return Node->ForwardLink;\r
-}\r
-\r
-/**\r
- Retrieves the previous node of a doubly-linked list.\r
-\r
- Returns the node of a doubly-linked list that precedes Node.\r
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
- or InitializeListHead(). If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
- PcdMaximumLinkedListLenth nodes, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @return A pointer to the previous node if one exists. Otherwise List is returned.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetPreviousNode (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- )\r
-{\r
- assert ((List != NULL) && (Node != NULL));\r
-\r
- return Node->BackLink;\r
-}\r
-\r
-/**\r
- Checks to see if a doubly-linked list is empty or not.\r
-\r
- Checks to see if the doubly-linked list is empty. If the linked list contains\r
- zero nodes, this function returns TRUE. Otherwise, it returns FALSE.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
-\r
- @retval TRUE The linked list is empty.\r
- @retval FALSE The linked list is not empty.\r
-\r
-**/\r
-BOOLEAN\r
-IsListEmpty (\r
- IN CONST LIST_ENTRY *ListHead\r
- )\r
-{\r
- assert (ListHead != NULL);\r
-\r
- return (BOOLEAN)(ListHead->ForwardLink == ListHead);\r
-}\r
-\r
-/**\r
- Determines if a node in a doubly-linked list is the head node of a the same\r
- doubly-linked list. This function is typically used to terminate a loop that\r
- traverses all the nodes in a doubly-linked list starting with the head node.\r
-\r
- Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the\r
- nodes in the doubly-linked list specified by List. List must have been\r
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),\r
- then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not\r
- equal to List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @retval TRUE Node is the head of the doubly-linked list pointed by List.\r
- @retval FALSE Node is not the head of the doubly-linked list pointed by List.\r
-\r
-**/\r
-BOOLEAN\r
-IsNull (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- )\r
-{\r
- assert ((List != NULL) && (Node != NULL));\r
-\r
- return (BOOLEAN)(Node == List);\r
-}\r
-\r
-/**\r
- Determines if a node the last node in a doubly-linked list.\r
-\r
- Returns TRUE if Node is the last node in the doubly-linked list specified by\r
- List. Otherwise, FALSE is returned. List must have been initialized with\r
- INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @retval TRUE Node is the last node in the linked list.\r
- @retval FALSE Node is not the last node in the linked list.\r
-\r
-**/\r
-BOOLEAN\r
-IsNodeAtEnd (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- )\r
-{\r
- assert ((List != NULL) && (Node != NULL));\r
-\r
- return (BOOLEAN)(!IsNull (List, Node) && (List->BackLink == Node));\r
-}\r
-\r
-/**\r
- Removes a node from a doubly-linked list, and returns the node that follows\r
- the removed node.\r
-\r
- Removes the node Entry from a doubly-linked list. It is up to the caller of\r
- this function to release the memory used by this node if that is required. On\r
- exit, the node following Entry in the doubly-linked list is returned. If\r
- Entry is the only node in the linked list, then the head node of the linked\r
- list is returned.\r
-\r
- If Entry is NULL, then ASSERT().\r
- If Entry is the head node of an empty list, then ASSERT().\r
- If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
- linked list containing Entry, including the Entry node, is greater than\r
- or equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param Entry A pointer to a node in a linked list.\r
-\r
- @return Entry.\r
-\r
-**/\r
-LIST_ENTRY *\r
-RemoveEntryList (\r
- IN CONST LIST_ENTRY *Entry\r
- )\r
-{\r
- assert (!IsListEmpty (Entry));\r
-\r
- Entry->ForwardLink->BackLink = Entry->BackLink;\r
- Entry->BackLink->ForwardLink = Entry->ForwardLink;\r
- return Entry->ForwardLink;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- Common library.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#ifndef _COMMON_LIB_H_\r
-#define _COMMON_LIB_H_\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#ifdef __GNUC__\r
-#include <unistd.h>\r
-#else\r
-#include <io.h>\r
-#include <direct.h>\r
-#endif\r
-#include <ctype.h>\r
-#include <assert.h>\r
-#include <math.h>\r
-#include "CommonLib.h"\r
-#include <Common/UefiBaseTypes.h>\r
-\r
-#define MAX_QUI_PARAM_LEN 2000\r
-#define ERROR_INFO_LENGTH 400\r
-#define MAX_STR_LEN_FOR_PICK_UQI 200\r
-#define MAX_PLATFORM_DEFAULT_ID_NUM 1000\r
-#define _MAX_BUILD_VERSION 100\r
-#define _MAXIMUM_SECTION_FILE_NUM 1000\r
-\r
-#ifndef _MAX_PATH\r
-#define _MAX_PATH 500\r
-#endif\r
-\r
-///\r
-/// Variable attributes.\r
-///\r
-#define EFI_VARIABLE_NON_VOLATILE 0x00000001\r
-#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002\r
-#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004\r
-\r
-///\r
-/// This attribute is identified by the mnemonic 'HR'\r
-/// elsewhere in this specification.\r
-///\r
-#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010\r
-\r
-#define VARSTORE_LIST_TYPE 0x0000000000000001ULL\r
-#define EFI_VARSTORE_LIST_TYPE 0x0000000000000002ULL\r
-#define PLATFORM_DEFAULT_ID_TYPE 0x0000000000000004ULL\r
-#define UQI_LIST_TYPE 0x0000000000000008ULL\r
-#define HII_OBJ_LIST_TYPE 0x0000000000000010ULL\r
-\r
-///\r
-/// LIST_ENTRY structure definition.\r
-///\r
-typedef struct _LIST_ENTRY {\r
- struct _LIST_ENTRY *ForwardLink;\r
- struct _LIST_ENTRY *BackLink;\r
-} LIST_ENTRY;\r
-\r
-#define CR(Record, TYPE, Field, TestSignature) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))\r
-#define AllocateZeroPool(a) calloc(a, sizeof (CHAR8))\r
-#define FreePool(a) free(a)\r
-#define CopyMem(a, b, c) memcpy(a, b, c)\r
-#define ZeroMem(a, b) memset(a, 0, b)\r
-#define CompareMem(a, b, c) memcmp(a, b, c)\r
-#define AllocatePool(a) malloc(a)\r
-\r
-/**\r
- Returns a 16-bit signature built from 2 ASCII characters.\r
-\r
- This macro returns a 16-bit value built from the two ASCII characters specified\r
- by A and B.\r
-\r
- @param A The first ASCII character.\r
- @param B The second ASCII character.\r
-\r
- @return A 16-bit value built from the two ASCII characters specified by A and B.\r
-\r
-**/\r
-#define SIGNATURE_16(A, B) ((A) | (B << 8))\r
-\r
-/**\r
- Returns a 32-bit signature built from 4 ASCII characters.\r
-\r
- This macro returns a 32-bit value built from the four ASCII characters specified\r
- by A, B, C, and D.\r
-\r
- @param A The first ASCII character.\r
- @param B The second ASCII character.\r
- @param C The third ASCII character.\r
- @param D The fourth ASCII character.\r
-\r
- @return A 32-bit value built from the two ASCII characters specified by A, B,\r
- C and D.\r
-\r
-**/\r
-#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))\r
-\r
-#define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)\r
-\r
-/**\r
- Returns an argument of a specified type from a variable argument list and updates\r
- the pointer to the variable argument list to point to the next argument.\r
-\r
- This function returns an argument of the type specified by TYPE from the beginning\r
- of the variable argument list specified by Marker. Marker is then updated to point\r
- to the next argument in the variable argument list. The method for computing the\r
- pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.\r
-\r
- @param Marker The pointer to the beginning of a variable argument list.\r
- @param TYPE The type of argument to retrieve from the beginning\r
- of the variable argument list.\r
-\r
- @return An argument of the type specified by TYPE.\r
-\r
-**/\r
-#define BASE_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))\r
-\r
-///\r
-/// Define the maximum number of characters that are required to\r
-/// encode with a NULL terminator a decimal, hexadecimal, GUID,\r
-/// or TIME value.\r
-///\r
-/// Maximum Length Decimal String = 28\r
-/// "-9,223,372,036,854,775,808"\r
-/// Maximum Length Hexadecimal String = 17\r
-/// "FFFFFFFFFFFFFFFF"\r
-/// Maximum Length GUID = 37\r
-/// "00000000-0000-0000-0000-000000000000"\r
-/// Maximum Length TIME = 18\r
-/// "12/12/2006 12:12"\r
-///\r
-#define MAXIMUM_VALUE_CHARACTERS 38\r
-\r
-///\r
-/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.\r
-///\r
-typedef UINTN *BASE_LIST;\r
-\r
-/**\r
- Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary.\r
-\r
- @param TYPE The date type to determine the size of.\r
-\r
- @return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary.\r
-**/\r
-#define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN))\r
-\r
-//\r
-// Print primitives\r
-//\r
-#define PREFIX_SIGN BIT1\r
-#define PREFIX_BLANK BIT2\r
-#define LONG_TYPE BIT4\r
-#define OUTPUT_UNICODE BIT6\r
-#define FORMAT_UNICODE BIT8\r
-#define PAD_TO_WIDTH BIT9\r
-#define ARGUMENT_UNICODE BIT10\r
-#define PRECISION BIT11\r
-#define ARGUMENT_REVERSED BIT12\r
-#define COUNT_ONLY_NO_PRINT BIT13\r
-\r
-///\r
-/// Flags bitmask values use in UnicodeValueToString() and\r
-/// AsciiValueToString()\r
-///\r
-#define LEFT_JUSTIFY 0x01\r
-#define COMMA_TYPE 0x08\r
-#define PREFIX_ZERO 0x20\r
-#define RADIX_HEX 0x80\r
-\r
-//\r
-// Record date and time information\r
-//\r
-typedef struct {\r
- UINT16 Year;\r
- UINT8 Month;\r
- UINT8 Day;\r
- UINT8 Hour;\r
- UINT8 Minute;\r
- UINT8 Second;\r
- UINT8 Pad1;\r
- UINT32 Nanosecond;\r
- INT16 TimeZone;\r
- UINT8 Daylight;\r
- UINT8 Pad2;\r
-} TIME;\r
-\r
-\r
-/**\r
- Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
- string and returns the new Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then return NULL.\r
- If Destination is not aligned on a 16-bit boundary, then return NULL.\r
-\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
- @param Source A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
-\r
-**/\r
-CHAR16 *\r
-StrCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- );\r
-\r
-/**\r
- Returns the length of a Null-terminated Unicode string.\r
-\r
- This function returns the number of Unicode characters in the Null-terminated\r
- Unicode string specified by String.\r
-\r
- If String is NULL, then return 0.\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @return The length of String.\r
-\r
-**/\r
-UINTN\r
-FceStrLen (\r
- IN CONST CHAR16 *String\r
- );\r
-\r
-/**\r
- Returns the size of a Null-terminated Unicode string in bytes, including the\r
- Null terminator.\r
-\r
- This function returns the size, in bytes, of the Null-terminated Unicode string\r
- specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned on a 16-bit boundary, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @return The size of String.\r
-\r
-**/\r
-UINTN\r
-FceStrSize (\r
- IN CONST CHAR16 *String\r
- );\r
-\r
-/**\r
- Compares two Null-terminated Unicode strings, and returns the difference\r
- between the first mismatched Unicode characters.\r
-\r
- This function compares the Null-terminated Unicode string FirstString to the\r
- Null-terminated Unicode string SecondString. If FirstString is identical to\r
- SecondString, then 0 is returned. Otherwise, the value returned is the first\r
- mismatched Unicode character in SecondString subtracted from the first\r
- mismatched Unicode character in FirstString.\r
-\r
- @param FirstString A pointer to a Null-terminated Unicode string.\r
- @param SecondString A pointer to a Null-terminated Unicode string.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @return others FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-FceStrCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString\r
- );\r
-\r
-/**\r
- Concatenates one Null-terminated Unicode string to another Null-terminated\r
- Unicode string, and returns the concatenated Unicode string.\r
-\r
- This function concatenates two Null-terminated Unicode strings. The contents\r
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination. The Null-terminated concatenated\r
- Unicode String is returned. If Source and Destination overlap, then the\r
- results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
- and Source results in a Unicode string with more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
- @param Source A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
-\r
-**/\r
-CHAR16 *\r
-StrCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- );\r
-\r
-/**\r
- Returns the first occurrence of a Null-terminated Unicode sub-string\r
- in a Null-terminated Unicode string.\r
-\r
- This function scans the contents of the Null-terminated Unicode string\r
- specified by String and returns the first occurrence of SearchString.\r
- If SearchString is not found in String, then NULL is returned. If\r
- the length of SearchString is zero, then String is\r
- returned.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned on a 16-bit boundary, then ASSERT().\r
- If SearchString is NULL, then ASSERT().\r
- If SearchString is not aligned on a 16-bit boundary, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and SearchString\r
- or String contains more than PcdMaximumUnicodeStringLength Unicode\r
- characters, not including the Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
- @param SearchString A pointer to a Null-terminated Unicode string to search for.\r
-\r
- @retval NULL If the SearchString does not appear in String.\r
- @return others If there is a match.\r
-\r
-**/\r
-CHAR16 *\r
-StrStr (\r
- IN CONST CHAR16 *String,\r
- IN CONST CHAR16 *SearchString\r
- );\r
-\r
-/**\r
- Convert a Null-terminated Unicode decimal string to a value of\r
- type UINT64.\r
-\r
- This function returns a value of type UINT64 by interpreting the contents\r
- of the Unicode string specified by String as a decimal number. The format\r
- of the input Unicode string String is:\r
-\r
- [spaces] [decimal digits].\r
-\r
- The valid decimal digit character is in the range [0-9]. The\r
- function will ignore the pad space, which includes spaces or\r
- tab characters, before [decimal digits]. The running zero in the\r
- beginning of [decimal digits] will be ignored. Then, the function\r
- stops at the first character that is a not a valid decimal character\r
- or a Null-terminator, whichever one comes first.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned in a 16-bit boundary, then ASSERT().\r
- If String has only pad spaces, then 0 is returned.\r
- If String has no pad spaces or valid decimal digits,\r
- then 0 is returned.\r
- If the number represented by String overflows according\r
- to the range defined by UINT64, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains\r
- more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
- the Null-terminator, then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @retval Value translated from String.\r
-\r
-**/\r
-UINT64\r
-FceStrDecimalToUint64 (\r
- IN CONST CHAR16 *String\r
- );\r
-\r
-\r
-/**\r
- Convert one Null-terminated ASCII string to a Null-terminated\r
- Unicode string and returns the Unicode string.\r
-\r
- This function converts the contents of the ASCII string Source to the Unicode\r
- string Destination, and returns Destination. The function terminates the\r
- Unicode string Destination by appending a Null-terminator character at the end.\r
- The caller is responsible to make sure Destination points to a buffer with size\r
- equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
-\r
- @param Source A pointer to a Null-terminated ASCII string.\r
- @param Destination A pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination.\r
- @return NULL If Destination or Source is NULL, return NULL.\r
-\r
-**/\r
-CHAR16 *\r
-AsciiStrToUnicodeStr (\r
- IN CONST CHAR8 *Source,\r
- OUT CHAR16 *Destination\r
- );\r
-\r
-/**\r
- Worker function that produces a Null-terminated string in an output buffer\r
- based on a Null-terminated format string and variable argument list.\r
-\r
- VSPrint function to process format and place the results in Buffer. Since a\r
- VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
- this is the main print working routine\r
-\r
- @param StartOfBuffer The character buffer to print the results of the parsing\r
- of Format into.\r
- @param BufferSize The maximum number of characters to put into buffer.\r
- Zero means no limit.\r
- @param Flags Initial flags value.\r
- Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
- @param FormatString A Null-terminated format string.\r
- @param ... The variable argument list.\r
-\r
- @return The number of characters printed.\r
-\r
-**/\r
-UINTN\r
-BasePrintLibSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
- Unicode format string and variable argument list.\r
-\r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the format string.\r
- The number of Unicode characters in the produced output buffer is returned not including\r
- the Null-terminator.\r
- If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
- If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
- If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
- ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
-\r
- @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated\r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString A Null-terminated Unicode format string.\r
- @param ... Variable argument list whose contents are accessed based on the\r
- format string specified by FormatString.\r
-\r
- @return The number of Unicode characters in the produced output buffer not including the\r
- Null-terminator.\r
-\r
-**/\r
-UINTN\r
-UnicodeSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Convert a Null-terminated Unicode string to a Null-terminated\r
- ASCII string and returns the ASCII string.\r
-\r
- This function converts the content of the Unicode string Source\r
- to the ASCII string Destination by copying the lower 8 bits of\r
- each Unicode character. It returns Destination. The function terminates\r
- the ASCII string Destination by appending a Null-terminator character\r
- at the end. The caller is responsible to make sure Destination points\r
- to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source is not aligned on a 16-bit boundary, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- If any Unicode characters in Source contain non-zero value in\r
- the upper 8 bits, then ASSERT().\r
-\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
-\r
- @reture Destination\r
-\r
-**/\r
-CHAR8 *\r
-UnicodeStrToAsciiStr (\r
- IN CONST CHAR16 *Source,\r
- OUT CHAR8 *Destination\r
- );\r
-\r
-/**\r
- Allocate new memory and then copy the Unicode string Source to Destination.\r
-\r
- @param Dest Location to copy string\r
- @param Src String to copy\r
-\r
-**/\r
-VOID\r
-NewStringCpy (\r
- IN OUT CHAR16 **Dest,\r
- IN CHAR16 *Src\r
- );\r
-\r
-/**\r
- Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
-\r
- This function returns a value of type UINT64 by interpreting the contents\r
- of the Unicode string specified by String as a hexadecimal number.\r
- The format of the input Unicode string String is\r
-\r
- [spaces][zeros][x][hexadecimal digits].\r
-\r
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
- If "x" appears in the input string, it must be prefixed with at least one 0.\r
- The function will ignore the pad space, which includes spaces or tab characters,\r
- before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
- [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
- first valid hexadecimal digit. Then, the function stops at the first character that is\r
- a not a valid hexadecimal character or NULL, whichever one comes first.\r
-\r
- If String is NULL, then ASSERT().\r
- If String is not aligned in a 16-bit boundary, then ASSERT().\r
- If String has only pad spaces, then zero is returned.\r
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
- then zero is returned.\r
- If the number represented by String overflows according to the range defined by\r
- UINT64, then ASSERT().\r
-\r
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
- then ASSERT().\r
-\r
- @param String A pointer to a Null-terminated Unicode string.\r
-\r
- @retval Value translated from String.\r
-\r
-**/\r
-UINT64\r
-FceStrHexToUint64 (\r
- IN CONST CHAR16 *String\r
- );\r
-\r
-\r
-CHAR16\r
-ToUpper (\r
- CHAR16 a\r
- );\r
-\r
-CHAR16\r
-ToLower (\r
- CHAR16 a\r
- );\r
-\r
-/**\r
- Performs a case-insensitive comparison between a Null-terminated\r
- Unicode pattern string and a Null-terminated Unicode string.\r
-\r
- @param String - A pointer to a Null-terminated Unicode string.\r
- @param Pattern - A pointer to a Null-terminated Unicode pattern string.\r
-\r
-\r
- @retval TRUE - Pattern was found in String.\r
- @retval FALSE - Pattern was not found in String.\r
-\r
-**/\r
-BOOLEAN\r
-MetaiMatch (\r
- IN CHAR16 *String,\r
- IN CHAR16 *Pattern\r
- );\r
-\r
-/**\r
- Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and\r
- generates a 64-bit unsigned result.\r
-\r
- This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit\r
- unsigned value Multiplier and generates a 64-bit unsigned result. This 64-\r
- bit unsigned result is returned.\r
-\r
- @param Multiplicand A 64-bit unsigned value.\r
- @param Multiplier A 32-bit unsigned value.\r
-\r
- @return Multiplicand * Multiplier.\r
-\r
-**/\r
-UINT64\r
-MultU64x32 (\r
- IN UINT64 Multiplicand,\r
- IN UINT32 Multiplier\r
- );\r
-\r
-/**\r
- Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates\r
- a 64-bit unsigned result.\r
-\r
- This function divides the 64-bit unsigned value Dividend by the 32-bit\r
- unsigned value Divisor and generates a 64-bit unsigned quotient. This\r
- function returns the 64-bit unsigned quotient.\r
-\r
- If Divisor is 0, then ASSERT().\r
-\r
- @param Dividend A 64-bit unsigned value.\r
- @param Divisor A 32-bit unsigned value.\r
-\r
- @return Dividend / Divisor\r
-\r
-**/\r
-UINT64\r
-DivU64x32 (\r
- IN UINT64 Dividend,\r
- IN UINT32 Divisor\r
- );\r
-\r
-/**\r
- Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled\r
- with zeros. The shifted value is returned.\r
-\r
- This function shifts the 64-bit value Operand to the left by Count bits. The\r
- low Count bits are set to zero. The shifted value is returned.\r
-\r
- If Count is greater than 63, then ASSERT().\r
-\r
- @param Operand The 64-bit operand to shift left.\r
- @param Count The number of bits to shift left.\r
-\r
- @return Operand << Count.\r
-\r
-**/\r
-UINT64\r
-LShiftU64 (\r
- IN UINT64 Operand,\r
- IN UINTN Count\r
- );\r
-\r
-/**\r
- Shifts a 64-bit integer right between 0 and 63 bits. This high bits are\r
- filled with zeros. The shifted value is returned.\r
-\r
- This function shifts the 64-bit value Operand to the right by Count bits. The\r
- high Count bits are set to zero. The shifted value is returned.\r
-\r
- If Count is greater than 63, then ASSERT().\r
-\r
- @param Operand The 64-bit operand to shift right.\r
- @param Count The number of bits to shift right.\r
-\r
- @return Operand >> Count.\r
-\r
-**/\r
-UINT64\r
-RShiftU64 (\r
- IN UINT64 Operand,\r
- IN UINTN Count\r
- );\r
-\r
-\r
-/**\r
- Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates\r
- a 64-bit unsigned result and an optional 32-bit unsigned remainder.\r
-\r
- This function divides the 64-bit unsigned value Dividend by the 32-bit\r
- unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder\r
- is not NULL, then the 32-bit unsigned remainder is returned in Remainder.\r
- This function returns the 64-bit unsigned quotient.\r
-\r
- If Divisor is 0, then ASSERT().\r
-\r
- @param Dividend A 64-bit unsigned value.\r
- @param Divisor A 32-bit unsigned value.\r
- @param Remainder A pointer to a 32-bit unsigned value. This parameter is\r
- optional and may be NULL.\r
-\r
- @return Dividend / Divisor\r
-\r
-**/\r
-UINT64\r
-DivU64x32Remainder (\r
- IN UINT64 Dividend,\r
- IN UINT32 Divisor,\r
- OUT UINT32 *Remainder\r
- );\r
-\r
-/**\r
- Copies a buffer to an allocated buffer.\r
-\r
- Allocates the number bytes specified by AllocationSize, copies allocationSize bytes\r
- from Buffer to the newly allocated buffer, and returns a pointer to the allocated\r
- buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
- is not enough memory remaining to satisfy the request, then NULL is returned.\r
-\r
- If Buffer is NULL, then ASSERT().\r
-\r
- @param AllocationSize The number of bytes to allocate and zero.\r
- @param Buffer The buffer to copy to the allocated buffer.\r
-\r
- @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-FceAllocateCopyPool (\r
- IN UINTN AllocationSize,\r
- IN CONST VOID *Buffer\r
- );\r
-\r
-/**\r
- Initializes the head node of a doubly-linked list, and returns the pointer to\r
- the head node of the doubly-linked list.\r
-\r
- Initializes the forward and backward links of a new linked list. After\r
- initializing a linked list with this function, the other linked list\r
- functions may be used to add and remove nodes from the linked list. It is up\r
- to the caller of this function to allocate the memory for ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a new doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InitializeListHead (\r
- IN OUT LIST_ENTRY *ListHead\r
- );\r
-\r
-/**\r
- Adds a node to the beginning of a doubly-linked list, and returns the pointer\r
- to the head node of the doubly-linked list.\r
-\r
- Adds the node Entry at the beginning of the doubly-linked list denoted by\r
- ListHead, and returns ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If Entry is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r
- of nodes in ListHead, including the ListHead node, is greater than or\r
- equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
- @param Entry A pointer to a node that is to be inserted at the beginning\r
- of a doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InsertHeadList (\r
- IN OUT LIST_ENTRY *ListHead,\r
- IN OUT LIST_ENTRY *Entry\r
- );\r
-\r
-/**\r
- Adds a node to the end of a doubly-linked list, and returns the pointer to\r
- the head node of the doubly-linked list.\r
-\r
- Adds the node Entry to the end of the doubly-linked list denoted by ListHead,\r
- and returns ListHead.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If Entry is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r
- of nodes in ListHead, including the ListHead node, is greater than or\r
- equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
- @param Entry A pointer to a node that is to be added at the end of the\r
- doubly-linked list.\r
-\r
- @return ListHead\r
-\r
-**/\r
-LIST_ENTRY *\r
-InsertTailList (\r
- IN OUT LIST_ENTRY *ListHead,\r
- IN OUT LIST_ENTRY *Entry\r
- );\r
-\r
-/**\r
- Retrieves the first node of a doubly-linked list.\r
-\r
- Returns the first node of a doubly-linked list. List must have been\r
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
- If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
-\r
- @return The first node of a doubly-linked list.\r
- @retval NULL The list is empty.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetFirstNode (\r
- IN CONST LIST_ENTRY *List\r
- );\r
-\r
-/**\r
- Retrieves the next node of a doubly-linked list.\r
-\r
- Returns the node of a doubly-linked list that follows Node.\r
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
- or InitializeListHead(). If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
- PcdMaximumLinkedListLenth nodes, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @return A pointer to the next node if one exists. Otherwise List is returned.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetNextNode (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- );\r
-\r
-/**\r
- Retrieves the previous node of a doubly-linked list.\r
-\r
- Returns the node of a doubly-linked list that precedes Node.\r
- List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
- or InitializeListHead(). If List is empty, then List is returned.\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
- PcdMaximumLinkedListLenth nodes, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @return A pointer to the previous node if one exists. Otherwise List is returned.\r
-\r
-**/\r
-LIST_ENTRY *\r
-GetPreviousNode (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- );\r
-\r
-/**\r
- Checks to see if a doubly-linked list is empty or not.\r
-\r
- Checks to see if the doubly-linked list is empty. If the linked list contains\r
- zero nodes, this function returns TRUE. Otherwise, it returns FALSE.\r
-\r
- If ListHead is NULL, then ASSERT().\r
- If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param ListHead A pointer to the head node of a doubly-linked list.\r
-\r
- @retval TRUE The linked list is empty.\r
- @retval FALSE The linked list is not empty.\r
-\r
-**/\r
-BOOLEAN\r
-IsListEmpty (\r
- IN CONST LIST_ENTRY *ListHead\r
- );\r
-\r
-/**\r
- Determines if a node in a doubly-linked list is the head node of a the same\r
- doubly-linked list. This function is typically used to terminate a loop that\r
- traverses all the nodes in a doubly-linked list starting with the head node.\r
-\r
- Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the\r
- nodes in the doubly-linked list specified by List. List must have been\r
- initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),\r
- then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not\r
- equal to List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @retval TRUE Node is the head of the doubly-linked list pointed by List.\r
- @retval FALSE Node is not the head of the doubly-linked list pointed by List.\r
-\r
-**/\r
-BOOLEAN\r
-IsNull (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- );\r
-\r
-/**\r
- Determines if a node the last node in a doubly-linked list.\r
-\r
- Returns TRUE if Node is the last node in the doubly-linked list specified by\r
- List. Otherwise, FALSE is returned. List must have been initialized with\r
- INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
-\r
- If List is NULL, then ASSERT().\r
- If Node is NULL, then ASSERT().\r
- If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
- InitializeListHead(), then ASSERT().\r
- If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
- in List, including the List node, is greater than or equal to\r
- PcdMaximumLinkedListLength, then ASSERT().\r
- If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
-\r
- @param List A pointer to the head node of a doubly-linked list.\r
- @param Node A pointer to a node in the doubly-linked list.\r
-\r
- @retval TRUE Node is the last node in the linked list.\r
- @retval FALSE Node is not the last node in the linked list.\r
-\r
-**/\r
-BOOLEAN\r
-IsNodeAtEnd (\r
- IN CONST LIST_ENTRY *List,\r
- IN CONST LIST_ENTRY *Node\r
- );\r
-\r
-/**\r
- Removes a node from a doubly-linked list, and returns the node that follows\r
- the removed node.\r
-\r
- Removes the node Entry from a doubly-linked list. It is up to the caller of\r
- this function to release the memory used by this node if that is required. On\r
- exit, the node following Entry in the doubly-linked list is returned. If\r
- Entry is the only node in the linked list, then the head node of the linked\r
- list is returned.\r
-\r
- If Entry is NULL, then ASSERT().\r
- If Entry is the head node of an empty list, then ASSERT().\r
- If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
- linked list containing Entry, including the Entry node, is greater than\r
- or equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param Entry A pointer to a node in a linked list.\r
-\r
- @return Entry.\r
-\r
-**/\r
-LIST_ENTRY *\r
-RemoveEntryList (\r
- IN CONST LIST_ENTRY *Entry\r
- );\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
-\r
- Utility functions for expression evaluation.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "IfrParse.h"\r
-\r
-#define gEmptyString L""\r
-//\r
-// Global stack used to evaluate boolean expresions\r
-//\r
-EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
-EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
-EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
-\r
-EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
-EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
-EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
-UINTN mExpressionEvaluationStackOffset = 0;\r
-\r
-EFI_HII_VALUE *mCurrentExpressionStack = NULL;\r
-EFI_HII_VALUE *mCurrentExpressionEnd = NULL;\r
-EFI_HII_VALUE *mCurrentExpressionPointer = NULL;\r
-\r
-EFI_HII_VALUE *mMapExpressionListStack = NULL;\r
-EFI_HII_VALUE *mMapExpressionListEnd = NULL;\r
-EFI_HII_VALUE *mMapExpressionListPointer = NULL;\r
-\r
-/**\r
- Get Value for given Name from a NameValue Storage.\r
-\r
- @param Storage The NameValue Storage.\r
- @param Name The Name.\r
- @param Value The retured Value.\r
-\r
- @retval EFI_SUCCESS Value found for given Name.\r
- @retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
-\r
-**/\r
-EFI_STATUS\r
-GetValueByName (\r
- IN FORMSET_STORAGE *Storage,\r
- IN CHAR16 *Name,\r
- IN OUT CHAR16 **Value\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- NAME_VALUE_NODE *Node;\r
-\r
- *Value = NULL;\r
-\r
- Link = GetFirstNode (&Storage->NameValueListHead);\r
- while (!IsNull (&Storage->NameValueListHead, Link)) {\r
- Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-\r
- if (FceStrCmp (Name, Node->Name) == 0) {\r
- NewStringCpy (Value, Node->EditValue);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Link = GetNextNode (&Storage->NameValueListHead, Link);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Grow size of the stack.\r
-\r
- This is an internal function.\r
-\r
- @param Stack On input: old stack; On output: new stack\r
- @param StackPtr On input: old stack pointer; On output: new stack\r
- pointer\r
- @param StackEnd On input: old stack end; On output: new stack end\r
-\r
- @retval EFI_SUCCESS Grow stack success.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
-\r
-**/\r
-EFI_STATUS\r
-GrowStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd\r
- )\r
-{\r
- UINTN Size;\r
- EFI_HII_VALUE *NewStack;\r
-\r
- Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
- if (*StackPtr != NULL) {\r
- Size = Size + (*StackEnd - *Stack);\r
- }\r
-\r
- NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\r
- if (NewStack == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (*StackPtr != NULL) {\r
- //\r
- // Copy from Old Stack to the New Stack\r
- //\r
- CopyMem (\r
- NewStack,\r
- *Stack,\r
- (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)\r
- );\r
-\r
- //\r
- // Free The Old Stack\r
- //\r
- FreePool (*Stack);\r
- }\r
-\r
- //\r
- // Make the Stack pointer point to the old data in the new stack\r
- //\r
- *StackPtr = NewStack + (*StackPtr - *Stack);\r
- *Stack = NewStack;\r
- *StackEnd = NewStack + Size;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Push an element onto the Boolean Stack.\r
-\r
- @param Stack On input: old stack; On output: new stack\r
- @param StackPtr On input: old stack pointer; On output: new stack\r
- pointer\r
- @param StackEnd On input: old stack end; On output: new stack end\r
- @param Data Data to push.\r
-\r
- @retval EFI_SUCCESS Push stack success.\r
-\r
-**/\r
-EFI_STATUS\r
-PushStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd,\r
- IN EFI_HII_VALUE *Data\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check for a stack overflow condition\r
- //\r
- if (*StackPtr >= *StackEnd) {\r
- //\r
- // Grow the stack\r
- //\r
- Status = GrowStack (Stack, StackPtr, StackEnd);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Push the item onto the stack\r
- //\r
- CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
- *StackPtr = *StackPtr + 1;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Pop an element from the stack.\r
-\r
- @param Stack On input: old stack\r
- @param StackPtr On input: old stack pointer; On output: new stack pointer\r
- @param Data Data to pop.\r
-\r
- @retval EFI_SUCCESS The value was popped onto the stack.\r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
-\r
-**/\r
-EFI_STATUS\r
-PopStack (\r
- IN EFI_HII_VALUE *Stack,\r
- IN OUT EFI_HII_VALUE **StackPtr,\r
- OUT EFI_HII_VALUE *Data\r
- )\r
-{\r
- //\r
- // Check for a stack underflow condition\r
- //\r
- if (*StackPtr == Stack) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Pop the item off the stack\r
- //\r
- *StackPtr = *StackPtr - 1;\r
- CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetCurrentExpressionStack (\r
- VOID\r
- )\r
-{\r
- mCurrentExpressionPointer = mCurrentExpressionStack;\r
-}\r
-\r
-\r
-/**\r
- Push current expression onto the Stack\r
-\r
- @param Pointer Pointer to current expression.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushCurrentExpression (\r
- IN VOID *Pointer\r
- )\r
-{\r
- EFI_HII_VALUE Data;\r
-\r
- Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
-\r
- return PushStack (\r
- &mCurrentExpressionStack,\r
- &mCurrentExpressionPointer,\r
- &mCurrentExpressionEnd,\r
- &Data\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop current expression from the Stack\r
-\r
- @param Pointer Pointer to current expression to be pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopCurrentExpression (\r
- OUT VOID **Pointer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Data;\r
-\r
- Status = PopStack (\r
- mCurrentExpressionStack,\r
- &mCurrentExpressionPointer,\r
- &Data\r
- );\r
-\r
- *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetMapExpressionListStack (\r
- VOID\r
- )\r
-{\r
- mMapExpressionListPointer = mMapExpressionListStack;\r
-}\r
-\r
-\r
-/**\r
- Push the list of map expression onto the Stack\r
-\r
- @param Pointer Pointer to the list of map expression to be pushed.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushMapExpressionList (\r
- IN VOID *Pointer\r
- )\r
-{\r
- EFI_HII_VALUE Data;\r
-\r
- Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
-\r
- return PushStack (\r
- &mMapExpressionListStack,\r
- &mMapExpressionListPointer,\r
- &mMapExpressionListEnd,\r
- &Data\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop the list of map expression from the Stack\r
-\r
- @param Pointer Pointer to the list of map expression to be pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopMapExpressionList (\r
- OUT VOID **Pointer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Data;\r
-\r
- Status = PopStack (\r
- mMapExpressionListStack,\r
- &mMapExpressionListPointer,\r
- &Data\r
- );\r
-\r
- *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetScopeStack (\r
- VOID\r
- )\r
-{\r
- mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
-}\r
-\r
-\r
-/**\r
- Push an Operand onto the Stack\r
-\r
- @param Operand Operand to push.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushScope (\r
- IN UINT8 Operand\r
- )\r
-{\r
- EFI_HII_VALUE Data;\r
-\r
- Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Data.Value.u8 = Operand;\r
-\r
- return PushStack (\r
- &mOpCodeScopeStack,\r
- &mOpCodeScopeStackPointer,\r
- &mOpCodeScopeStackEnd,\r
- &Data\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop an Operand from the Stack\r
-\r
- @param Operand Operand to pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopScope (\r
- OUT UINT8 *Operand\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Data;\r
-\r
- Status = PopStack (\r
- mOpCodeScopeStack,\r
- &mOpCodeScopeStackPointer,\r
- &Data\r
- );\r
-\r
- *Operand = Data.Value.u8;\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Push an Expression value onto the Stack\r
-\r
- @param Value Expression value to push.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushExpression (\r
- IN EFI_HII_VALUE *Value\r
- )\r
-{\r
- return PushStack (\r
- &mExpressionEvaluationStack,\r
- &mExpressionEvaluationStackPointer,\r
- &mExpressionEvaluationStackEnd,\r
- Value\r
- );\r
-}\r
-\r
-\r
-/**\r
- Pop an Expression value from the stack.\r
-\r
- @param Value Expression value to pop.\r
-\r
- @retval EFI_SUCCESS The value was popped onto the stack.\r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
-\r
-**/\r
-EFI_STATUS\r
-PopExpression (\r
- OUT EFI_HII_VALUE *Value\r
- )\r
-{\r
- return PopStack (\r
- mExpressionEvaluationStack + mExpressionEvaluationStackOffset,\r
- &mExpressionEvaluationStackPointer,\r
- Value\r
- );\r
-}\r
-\r
-/**\r
- Get current stack offset from stack start.\r
-\r
- @return Stack offset to stack start.\r
-**/\r
-UINTN\r
-SaveExpressionEvaluationStackOffset (\r
- )\r
-{\r
- UINTN TempStackOffset;\r
- TempStackOffset = mExpressionEvaluationStackOffset;\r
- mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack;\r
- return TempStackOffset;\r
-}\r
-\r
-/**\r
- Restore stack offset based on input stack offset\r
-\r
- @param StackOffset Offset to stack start.\r
-\r
-**/\r
-VOID\r
-RestoreExpressionEvaluationStackOffset (\r
- UINTN StackOffset\r
- )\r
-{\r
- mExpressionEvaluationStackOffset = StackOffset;\r
-}\r
-\r
-\r
-/**\r
- Search a Question in Form scope using its QuestionId.\r
-\r
- @param Form The form which contains this Question.\r
- @param QuestionId Id of this Question.\r
-\r
- @retval Pointer The Question.\r
- @retval NULL Specified Question not found in the form.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-IdToQuestion2 (\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 QuestionId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Question;\r
-\r
- if (QuestionId == 0) {\r
- //\r
- // The value of zero is reserved\r
- //\r
- return NULL;\r
- }\r
-\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- while (!IsNull (&Form->StatementListHead, Link)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-\r
- if (Question->QuestionId == QuestionId) {\r
- return Question;\r
- }\r
-\r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Search a Question in Formset scope using its QuestionId.\r
-\r
- @param FormSet The formset which contains this form.\r
- @param Form The form which contains this Question.\r
- @param QuestionId Id of this Question.\r
-\r
- @retval Pointer The Question.\r
- @retval NULL Specified Question not found in the form.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-IdToQuestion (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 QuestionId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Question;\r
-\r
- //\r
- // Search in the form scope first\r
- //\r
- Question = IdToQuestion2 (Form, QuestionId);\r
- if (Question != NULL) {\r
- return Question;\r
- }\r
-\r
- //\r
- // Search in the formset scope\r
- //\r
- Link = GetFirstNode (&FormSet->FormListHead);\r
- while (!IsNull (&FormSet->FormListHead, Link)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
- Question = IdToQuestion2 (Form, QuestionId);\r
- if (Question != NULL) {\r
- return Question;\r
- }\r
-\r
- Link = GetNextNode (&FormSet->FormListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Get Expression given its RuleId.\r
-\r
- @param Form The form which contains this Expression.\r
- @param RuleId Id of this Expression.\r
-\r
- @retval Pointer The Expression.\r
- @retval NULL Specified Expression not found in the form.\r
-\r
-**/\r
-FORM_EXPRESSION *\r
-RuleIdToExpression (\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT8 RuleId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
-\r
- Link = GetFirstNode (&Form->ExpressionListHead);\r
- while (!IsNull (&Form->ExpressionListHead, Link)) {\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
-\r
- if ((Expression->Type == EFI_HII_EXPRESSION_RULE) && (Expression->RuleId == RuleId)) {\r
- return Expression;\r
- }\r
-\r
- Link = GetNextNode (&Form->ExpressionListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-/**\r
- Convert the input Unicode character to upper.\r
-\r
- @param String Th Unicode character to be converted.\r
-\r
-**/\r
-VOID\r
-IfrStrToUpper (\r
- IN CHAR16 *String\r
- )\r
-{\r
- while (*String != 0) {\r
- if ((*String >= 'a') && (*String <= 'z')) {\r
- *String = (UINT16) ((*String) & ((UINT16) ~0x20));\r
- }\r
- String++;\r
- }\r
-}\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TO_STRING.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Format String format in EFI_IFR_TO_STRING.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToString (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Format,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *PrintFormat;\r
- CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
- UINTN BufferSize;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- switch (Value.Type) {\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);\r
- switch (Format) {\r
- case EFI_IFR_STRING_UNSIGNED_DEC:\r
- case EFI_IFR_STRING_SIGNED_DEC:\r
- PrintFormat = L"%ld";\r
- break;\r
-\r
- case EFI_IFR_STRING_LOWERCASE_HEX:\r
- PrintFormat = L"%lx";\r
- break;\r
-\r
- case EFI_IFR_STRING_UPPERCASE_HEX:\r
- PrintFormat = L"%lX";\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
- UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_TYPE_STRING:\r
- CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
- return EFI_SUCCESS;\r
-\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- //Result->Value.string = NewString (String, FormSet->HiiHandle);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TO_UINT.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToUint (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String;\r
- CHAR16 *StringPtr;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- if (Value.Type == EFI_IFR_TYPE_STRING) {\r
- String = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- IfrStrToUpper (String);\r
- StringPtr = StrStr (String, L"0X");\r
- if (StringPtr != NULL) {\r
- //\r
- // Hex string\r
- //\r
- Result->Value.u64 = FceStrHexToUint64 (String);\r
- } else {\r
- //\r
- // decimal string\r
- //\r
- Result->Value.u64 = FceStrDecimalToUint64 (String);\r
- }\r
- FreePool (String);\r
- } else {\r
- CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- return Status;\r
-}\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_CATENATE.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrCatenate (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Index;\r
- CHAR16 *StringPtr;\r
- UINTN Size;\r
-\r
- //\r
- // String[0] - The second string\r
- // String[1] - The first string\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- StringPtr = NULL;\r
- Status = EFI_SUCCESS;\r
-\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Size = FceStrSize (String[0]);\r
- StringPtr= AllocatePool (FceStrSize (String[1]) + Size);\r
- ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- //Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- }\r
- if (StringPtr != NULL) {\r
- FreePool (StringPtr);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_MATCH.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrMatch (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Index;\r
-\r
- //\r
- // String[0] - The string to search\r
- // String[1] - pattern\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- Status = EFI_SUCCESS;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String [Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Result->Value.b = MetaiMatch (String[0], String[1]);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_FIND.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Format Case sensitive or insensitive.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrFind (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Format,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Base;\r
- CHAR16 *StringPtr;\r
- UINTN Index;\r
-\r
- if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - sub-string\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {\r
- //\r
- // Case insensitive, convert both string to upper case\r
- //\r
- IfrStrToUpper (String[Index]);\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- if (Base >= FceStrLen (String[1])) {\r
- Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;\r
- } else {\r
- StringPtr = StrStr (String[1] + Base, String[0]);\r
- Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);\r
- }\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_MID.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrMid (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String;\r
- UINTN Base;\r
- UINTN Length;\r
- CHAR16 *SubString;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Length = (UINTN) Value.Value.u64;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- String = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if ((Length == 0) || (Base >= FceStrLen (String))) {\r
- SubString = gEmptyString;\r
- } else {\r
- SubString = String + Base;\r
- if ((Base + Length) < FceStrLen (String)) {\r
- SubString[Length] = L'\0';\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- //Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
-\r
- FreePool (String);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TOKEN.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToken (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Count;\r
- CHAR16 *Delimiter;\r
- CHAR16 *SubString;\r
- CHAR16 *StringPtr;\r
- UINTN Index;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Count = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - Delimiter\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Delimiter = String[0];\r
- SubString = String[1];\r
- while (Count > 0) {\r
- SubString = StrStr (SubString, Delimiter);\r
- if (SubString != NULL) {\r
- //\r
- // Skip over the delimiter\r
- //\r
- SubString = SubString + FceStrLen (Delimiter);\r
- } else {\r
- break;\r
- }\r
- Count--;\r
- }\r
-\r
- if (SubString == NULL) {\r
- //\r
- // nth delimited sub-string not found, push an empty string\r
- //\r
- SubString = gEmptyString;\r
- } else {\r
- //\r
- // Put a NULL terminator for nth delimited sub-string\r
- //\r
- StringPtr = StrStr (SubString, Delimiter);\r
- if (StringPtr != NULL) {\r
- *StringPtr = L'\0';\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- //Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_SPAN.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Flags FIRST_MATCHING or FIRST_NON_MATCHING.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrSpan (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Flags,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- CHAR16 *Charset;\r
- UINTN Base;\r
- UINTN Index;\r
- CHAR16 *StringPtr;\r
- BOOLEAN Found;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - Charset\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->UnicodeBinary);\r
- if (String [Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- if (Base >= FceStrLen (String[1])) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- Found = FALSE;\r
- StringPtr = String[1] + Base;\r
- Charset = String[0];\r
- while (*StringPtr != 0 && !Found) {\r
- Index = 0;\r
- while (Charset[Index] != 0) {\r
- if ((*StringPtr >= Charset[Index]) && (*StringPtr <= Charset[Index + 1])) {\r
- if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {\r
- Found = TRUE;\r
- break;\r
- }\r
- } else {\r
- if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- //\r
- // Skip characters pair representing low-end of a range and high-end of a range\r
- //\r
- Index += 2;\r
- }\r
-\r
- if (!Found) {\r
- StringPtr++;\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Result->Value.u64 = StringPtr - String[1];\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Zero extend integer/boolean/date/time to UINT64 for comparing.\r
-\r
- @param Value HII Value to be converted.\r
-\r
-**/\r
-VOID\r
-ExtendValueToU64 (\r
- IN EFI_HII_VALUE *Value\r
- )\r
-{\r
- UINT64 Temp;\r
-\r
- Temp = 0;\r
- switch (Value->Type) {\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- Temp = Value->Value.u8;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- Temp = Value->Value.u16;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- Temp = Value->Value.u32;\r
- break;\r
-\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- Temp = Value->Value.b;\r
- break;\r
-\r
- case EFI_IFR_TYPE_TIME:\r
- Temp = Value->Value.u32 & 0xffffff;\r
- break;\r
-\r
- case EFI_IFR_TYPE_DATE:\r
- Temp = Value->Value.u32;\r
- break;\r
-\r
- default:\r
- return;\r
- }\r
-\r
- Value->Value.u64 = Temp;\r
-}\r
-\r
-\r
-/**\r
- Compare two Hii value.\r
-\r
- @param Value1 Expression value to compare on left-hand.\r
- @param Value2 Expression value to compare on right-hand.\r
- @param FormSet The pointer to the Formset.\r
-\r
- @retval EFI_INVALID_PARAMETER Could not perform compare on two values.\r
- @retval 0 Two operators equal.\r
- @return Positive value if Value1 is greater than Value2.\r
- @retval Negative value if Value1 is less than Value2.\r
-\r
-**/\r
-INTN\r
-CompareHiiValue (\r
- IN EFI_HII_VALUE *Value1,\r
- IN EFI_HII_VALUE *Value2,\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- INTN Result;\r
- INT64 Temp64;\r
- CHAR16 *Str1;\r
- CHAR16 *Str2;\r
-\r
- if ((Value1->Type >= EFI_IFR_TYPE_OTHER) || (Value2->Type >= EFI_IFR_TYPE_OTHER) ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Value1->Type == EFI_IFR_TYPE_STRING) || (Value2->Type == EFI_IFR_TYPE_STRING) ) {\r
- if (Value1->Type != Value2->Type) {\r
- //\r
- // Both Operator should be type of String\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Value1->Value.string == 0) || (Value2->Value.string == 0)) {\r
- //\r
- // StringId 0 is reserved\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Value1->Value.string == Value2->Value.string) {\r
- return 0;\r
- }\r
-\r
- Str1 = GetToken (Value1->Value.string, FormSet->UnicodeBinary);\r
- if (Str1 == NULL) {\r
- //\r
- // String not found\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Str2 = GetToken (Value2->Value.string, FormSet->UnicodeBinary);\r
- if (Str2 == NULL) {\r
- FreePool (Str1);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Result = FceStrCmp (Str1, Str2);\r
-\r
- FreePool (Str1);\r
- FreePool (Str2);\r
-\r
- return Result;\r
- }\r
-\r
- //\r
- // Take remain types(integer, boolean, date/time) as integer\r
- //\r
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
- if (Temp64 > 0) {\r
- Result = 1;\r
- } else if (Temp64 < 0) {\r
- Result = -1;\r
- } else {\r
- Result = 0;\r
- }\r
-\r
- return Result;\r
-}\r
-\r
-/**\r
- Tell whether this Operand is an constant Expression or not\r
-\r
- @param Operand Operand of an IFR OpCode.\r
-\r
- @retval TRUE This is an Expression OpCode.\r
- @retval FALSE Not an Expression OpCode.\r
-\r
-**/\r
-BOOLEAN\r
-IsConstantExpressionOpCode (\r
- IN UINT8 Operand\r
- )\r
-{\r
- if ((Operand == EFI_IFR_EQ_ID_VAL_OP) ||\r
- (Operand == EFI_IFR_EQ_ID_ID_OP) ||\r
- (Operand == EFI_IFR_EQ_ID_VAL_LIST_OP )||\r
- (Operand == EFI_IFR_QUESTION_REF1_OP) ||\r
- (Operand == EFI_IFR_QUESTION_REF2_OP) ||\r
- (Operand == EFI_IFR_QUESTION_REF3_OP) ||\r
- (Operand == EFI_IFR_THIS_OP ) ||\r
- (Operand == EFI_IFR_SECURITY_OP) ||\r
- (Operand == EFI_IFR_GET_OP) ||\r
- (Operand == EFI_IFR_SET_OP)\r
- ) {\r
- return FALSE;\r
- } else {\r
- return TRUE;\r
- }\r
-}\r
-\r
-/**\r
- Update the HiiValue of question from its variable.\r
-\r
- @param FormSet FormSet associated with this expression.\r
- @param Question The pointer to the Question\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_NOT_FOUND\r
-**/\r
-EFI_STATUS\r
-UpdateHiiValue (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 *VarBuffer;\r
- EFI_HII_VALUE *HiiValue;\r
-\r
- Status = EFI_SUCCESS;\r
- HiiValue = &Question->HiiValue;\r
-\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- if (Question->QuestionReferToBitField) {\r
- GetBitsQuestionValue (Question, VarBuffer, &HiiValue->Value.u32);\r
- } else {\r
- CopyMem (&HiiValue->Value.u64, VarBuffer, Question->StorageWidth);\r
- }\r
- return Status;\r
-}\r
-/**\r
- Evaluate the result of a HII expression.\r
-\r
- If Expression is NULL, then ASSERT.\r
-\r
- @param FormSet FormSet associated with this expression.\r
- @param Form Form associated with this expression.\r
- @param Expression Expression to be evaluated.\r
- @param ConstantExpression The pointer to the flag of constant expression. If constant, will return TRUE.\r
-\r
- @retval EFI_SUCCESS The expression evaluated successfuly\r
- @retval EFI_NOT_FOUND The Question which referenced by a QuestionId\r
- could not be found.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
- @retval EFI_INVALID_PARAMETER Syntax error with the Expression\r
-\r
-**/\r
-EFI_STATUS\r
-EvaluateExpression (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN OUT FORM_EXPRESSION *Expression,\r
- IN OUT BOOLEAN *ConstantExpression\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- EXPRESSION_OPCODE *OpCode;\r
- FORM_BROWSER_STATEMENT *Question;\r
- FORM_BROWSER_STATEMENT *Question2;\r
- UINT16 Index;\r
- EFI_HII_VALUE Data1;\r
- EFI_HII_VALUE Data2;\r
- EFI_HII_VALUE Data3;\r
- FORM_EXPRESSION *RuleExpression;\r
- EFI_HII_VALUE *Value;\r
- INTN Result;\r
- CHAR16 *StrPtr;\r
- UINT32 TempValue;\r
- LIST_ENTRY *SubExpressionLink;\r
- FORM_EXPRESSION *SubExpression;\r
- UINTN StackOffset;\r
- UINTN TempLength;\r
- CHAR16 TempStr[5];\r
- UINT8 DigitUint8;\r
- UINT8 *TempBuffer;\r
-\r
- //\r
- // Save current stack offset.\r
- //\r
- StackOffset = SaveExpressionEvaluationStackOffset ();\r
-\r
- ASSERT (Expression != NULL);\r
- Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
-\r
- Link = GetFirstNode (&Expression->OpCodeListHead);\r
- while (!IsNull (&Expression->OpCodeListHead, Link)) {\r
- OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
-\r
- Link = GetNextNode (&Expression->OpCodeListHead, Link);\r
-\r
- ZeroMem (&Data1, sizeof (EFI_HII_VALUE));\r
- ZeroMem (&Data2, sizeof (EFI_HII_VALUE));\r
- ZeroMem (&Data3, sizeof (EFI_HII_VALUE));\r
-\r
- Value = &Data3;\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Check whether it is a constant expression or not\r
- //\r
- if (*ConstantExpression) {\r
- *ConstantExpression = IsConstantExpressionOpCode (OpCode->Operand);\r
- }\r
-\r
- switch (OpCode->Operand) {\r
- //\r
- // Built-in functions\r
- //\r
- case EFI_IFR_EQ_ID_VAL_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- UpdateHiiValue (FormSet, Question);\r
- Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, FormSet);\r
- if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_ID_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
- if (Question2 == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- UpdateHiiValue (FormSet, Question);\r
- UpdateHiiValue (FormSet, Question2);\r
- Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet);\r
- if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
-\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- UpdateHiiValue (FormSet, Question);\r
- Value->Value.b = FALSE;\r
- for (Index =0; Index < OpCode->ListLength; Index++) {\r
- if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {\r
- Value->Value.b = TRUE;\r
- break;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_DUP_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Status = PushExpression (Value);\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF1_OP:\r
- case EFI_IFR_THIS_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- UpdateHiiValue (FormSet, Question);\r
- Value = &Question->HiiValue;\r
- break;\r
-\r
- case EFI_IFR_SECURITY_OP:\r
- //\r
- // Do nothing, as no need for static scaning\r
- //\r
- break;\r
-\r
- case EFI_IFR_GET_OP:\r
- //\r
- // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore.\r
- //\r
- Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
- Value->Value.u8 = 0;\r
- if (OpCode->VarStorage != NULL) {\r
- switch (OpCode->VarStorage->Type) {\r
- case EFI_IFR_VARSTORE_OP:\r
- //\r
- // Get value from Buffer\r
- //\r
- Value->Type = OpCode->ValueType;\r
- CopyMem (&Value->Value, OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth);\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_EFI_OP:\r
- //\r
- // Get value from Buffer\r
- //\r
- if (OpCode->VarStorage->NewEfiVarstore) {\r
- Value->Type = OpCode->ValueType;\r
- CopyMem (&Value->Value, OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth);\r
- } else {\r
- CopyMem (&Value->Value, OpCode->VarStorage->Buffer, OpCode->ValueWidth);\r
- }\r
-\r
-\r
- break;\r
- case EFI_HII_VARSTORE_NAME_VALUE:\r
- if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
- //\r
- // Get value from string except for STRING value.\r
- //\r
- Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr);\r
- if (!EFI_ERROR (Status)) {\r
- ASSERT (StrPtr != NULL);\r
- TempLength = FceStrLen (StrPtr);\r
- if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) {\r
- Value->Type = OpCode->ValueType;\r
- TempBuffer = (UINT8 *) &Value->Value;\r
- ZeroMem (TempStr, sizeof (TempStr));\r
- for (Index = 0; Index < TempLength; Index ++) {\r
- TempStr[0] = StrPtr[TempLength - Index - 1];\r
- DigitUint8 = (UINT8) FceStrHexToUint64 (TempStr);\r
- if ((Index & 1) == 0) {\r
- TempBuffer [Index/2] = DigitUint8;\r
- } else {\r
- TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);\r
- }\r
- }\r
- }\r
- free (StrPtr);\r
- StrPtr = NULL;\r
- }\r
- }\r
- break;\r
- default:\r
- //\r
- // Not recognize storage.\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCode->DevicePath == 0) {\r
- //\r
- // EFI_IFR_QUESTION_REF3\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- //\r
- // push the questions' value on to the expression stack\r
- //\r
- Value = &Question->HiiValue;\r
- } else {\r
- //\r
- // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,\r
- // since it is impractical to evaluate the value of a Question in another\r
- // Hii Package list.\r
- //\r
- ZeroMem (Value, sizeof (EFI_HII_VALUE));\r
- }\r
- break;\r
-\r
- case EFI_IFR_RULE_REF_OP:\r
- //\r
- // Find expression for this rule\r
- //\r
- RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);\r
- if (RuleExpression == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Evaluate this rule expression\r
- //\r
- Status = EvaluateExpression (FormSet, Form, RuleExpression, ConstantExpression);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Value = &RuleExpression->Result;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF1_OP:\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- Value->Value.string = OpCode->Value.Value.string;\r
- break;\r
-\r
- //\r
- // Constant\r
- //\r
- case EFI_IFR_TRUE_OP:\r
- case EFI_IFR_FALSE_OP:\r
- case EFI_IFR_ONE_OP:\r
- case EFI_IFR_ONES_OP:\r
- case EFI_IFR_UINT8_OP:\r
- case EFI_IFR_UINT16_OP:\r
- case EFI_IFR_UINT32_OP:\r
- case EFI_IFR_UINT64_OP:\r
- case EFI_IFR_UNDEFINED_OP:\r
- case EFI_IFR_VERSION_OP:\r
- case EFI_IFR_ZERO_OP:\r
- Value = &OpCode->Value;\r
- break;\r
-\r
- //\r
- // unary-op\r
- //\r
- case EFI_IFR_LENGTH_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary);\r
- if (StrPtr == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = FceStrLen (StrPtr);\r
- FreePool (StrPtr);\r
- break;\r
-\r
- case EFI_IFR_NOT_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- Value->Value.b = (BOOLEAN) (!Value->Value.b);\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF2_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
- if (Question == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- Value = &Question->HiiValue;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF2_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- StrPtr = GetToken (Value->Value.u16, FormSet->UnicodeBinary);\r
- if (StrPtr == NULL) {\r
- //\r
- // If String not exit, push an empty string\r
- //\r
- //Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);\r
- } else {\r
- Index = (UINT16) Value->Value.u64;\r
- Value->Value.string = Index;\r
- FreePool (StrPtr);\r
- }\r
- break;\r
-\r
- case EFI_IFR_TO_BOOLEAN_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Convert an expression to a Boolean\r
- //\r
- if (Value->Type <= EFI_IFR_TYPE_DATE) {\r
- //\r
- // When converting from an unsigned integer, zero will be converted to\r
- // FALSE and any other value will be converted to TRUE.\r
- //\r
- Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0);\r
-\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- } else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
- //\r
- // When converting from a string, if case-insensitive compare\r
- // with "true" is True, then push True. If a case-insensitive compare\r
- // with "false" is True, then push False. Otherwise, push Undefined.\r
- //\r
- StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary);\r
- if (StrPtr == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- IfrStrToUpper (StrPtr);\r
- if (FceStrCmp (StrPtr, L"TRUE") == 0){\r
- Value->Value.b = TRUE;\r
- } else if (FceStrCmp (StrPtr, L"FALSE") == 0) {\r
- Value->Value.b = FALSE;\r
- } else {\r
- Status = EFI_INVALID_PARAMETER;\r
- FreePool (StrPtr);\r
- goto Done;\r
- }\r
- FreePool (StrPtr);\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- }\r
- break;\r
-\r
- case EFI_IFR_TO_STRING_OP:\r
- //Status = IfrToString (FormSet, OpCode->Format, Value);\r
- break;\r
-\r
- case EFI_IFR_TO_UINT_OP:\r
- Status = IfrToUint (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_TO_LOWER_OP:\r
- case EFI_IFR_TO_UPPER_OP:\r
-\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- StrPtr = GetToken (Value->Value.string, FormSet->UnicodeBinary);\r
- if (StrPtr == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- //\r
- // Do nothing here, as these two Opcode are to change or update the String Package\r
- //\r
- FreePool (StrPtr);\r
- break;\r
-\r
- case EFI_IFR_BITWISE_NOT_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Value->Type > EFI_IFR_TYPE_DATE) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = ~Value->Value.u64;\r
- break;\r
-\r
- case EFI_IFR_SET_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Data1.Type = EFI_IFR_TYPE_BOOLEAN;\r
- Data1.Value.b = FALSE;\r
- //\r
- // Not support SetOpcode for static scaning\r
- //\r
- if (OpCode->VarStorage != NULL) {\r
- switch (OpCode->VarStorage->Type) {\r
-\r
- case EFI_IFR_VARSTORE_OP:\r
- CopyMem (OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);\r
- Data1.Value.b = TRUE;\r
- break;\r
- case EFI_IFR_VARSTORE_EFI_OP:\r
- if (OpCode->VarStorage->NewEfiVarstore) {\r
- CopyMem (OpCode->VarStorage->Buffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);\r
- Data1.Value.b = TRUE;\r
- } else {\r
- CopyMem (OpCode->VarStorage->Buffer, &Value->Value, OpCode->ValueWidth);\r
- Data1.Value.b = TRUE;\r
- }\r
- break;\r
- case EFI_HII_VARSTORE_NAME_VALUE:\r
-\r
- break;\r
- break;\r
- default:\r
- //\r
- // Not recognize storage.\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- break;\r
- }\r
- Value = &Data1;\r
- }\r
- break;\r
-\r
- //\r
- // binary-op\r
- //\r
- case EFI_IFR_ADD_OP:\r
- case EFI_IFR_SUBTRACT_OP:\r
- case EFI_IFR_MULTIPLY_OP:\r
- case EFI_IFR_DIVIDE_OP:\r
- case EFI_IFR_MODULO_OP:\r
- case EFI_IFR_BITWISE_AND_OP:\r
- case EFI_IFR_BITWISE_OR_OP:\r
- case EFI_IFR_SHIFT_LEFT_OP:\r
- case EFI_IFR_SHIFT_RIGHT_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
-\r
- switch (OpCode->Operand) {\r
- case EFI_IFR_ADD_OP:\r
- Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_SUBTRACT_OP:\r
- Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_MULTIPLY_OP:\r
- Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_DIVIDE_OP:\r
- Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_MODULO_OP:\r
- DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
- Value->Value.u64 = TempValue;\r
- break;\r
-\r
- case EFI_IFR_BITWISE_AND_OP:\r
- Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_BITWISE_OR_OP:\r
- Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_SHIFT_LEFT_OP:\r
- Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_SHIFT_RIGHT_OP:\r
- Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- break;\r
-\r
- case EFI_IFR_AND_OP:\r
- case EFI_IFR_OR_OP:\r
- //\r
- // Two Boolean operator\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (OpCode->Operand == EFI_IFR_AND_OP) {\r
- Value->Value.b = (BOOLEAN) (Data1.Value.b && Data2.Value.b);\r
- } else {\r
- Value->Value.b = (BOOLEAN) (Data1.Value.b || Data2.Value.b);\r
- }\r
- break;\r
-\r
- case EFI_IFR_EQUAL_OP:\r
- case EFI_IFR_NOT_EQUAL_OP:\r
- case EFI_IFR_GREATER_EQUAL_OP:\r
- case EFI_IFR_GREATER_THAN_OP:\r
- case EFI_IFR_LESS_EQUAL_OP:\r
- case EFI_IFR_LESS_THAN_OP:\r
- //\r
- // Compare two integer, string, boolean or date/time\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if ((Data2.Type > EFI_IFR_TYPE_BOOLEAN) && (Data2.Type != EFI_IFR_TYPE_STRING)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Result = CompareHiiValue (&Data1, &Data2, FormSet);\r
- if ((EFI_STATUS)Result == EFI_INVALID_PARAMETER) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- switch (OpCode->Operand) {\r
- case EFI_IFR_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_NOT_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result != 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_GREATER_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result >= 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_GREATER_THAN_OP:\r
- Value->Value.b = (BOOLEAN) ((Result > 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_LESS_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result <= 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_LESS_THAN_OP:\r
- Value->Value.b = (BOOLEAN) ((Result < 0) ? TRUE : FALSE);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- break;\r
-\r
- case EFI_IFR_MATCH_OP:\r
- Status = IfrMatch (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_CATENATE_OP:\r
- Status = IfrCatenate (FormSet, Value);\r
- break;\r
-\r
- //\r
- // ternary-op\r
- //\r
- case EFI_IFR_CONDITIONAL_OP:\r
- //\r
- // Pop third expression from the expression stack\r
- //\r
- Status = PopExpression (&Data3);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Pop second expression from the expression stack\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Pop first expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (Data1.Value.b) {\r
- Value = &Data3;\r
- } else {\r
- Value = &Data2;\r
- }\r
- break;\r
-\r
- case EFI_IFR_FIND_OP:\r
- Status = IfrFind (FormSet, OpCode->Format, Value);\r
- break;\r
-\r
- case EFI_IFR_MID_OP:\r
- Status = IfrMid (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_TOKEN_OP:\r
- Status = IfrToken (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_SPAN_OP:\r
- Status = IfrSpan (FormSet, OpCode->Flags, Value);\r
- break;\r
-\r
- case EFI_IFR_MAP_OP:\r
- //\r
- // Pop the check value\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- //\r
- // Check MapExpression list is valid.\r
- //\r
- if (OpCode->MapExpressionList.ForwardLink == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- //\r
- // Go through map expression list.\r
- //\r
- SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
- while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
- SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
- //\r
- // Evaluate the first expression in this pair.\r
- //\r
- Status = EvaluateExpression (FormSet, Form, SubExpression, ConstantExpression);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- //\r
- // Compare the expression value with current value\r
- //\r
- if (CompareHiiValue (&Data1, &SubExpression->Result, FormSet) == 0) {\r
- //\r
- // Try get the map value.\r
- //\r
- SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
- if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
- Status = EvaluateExpression (FormSet, Form, SubExpression, ConstantExpression);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Value = &SubExpression->Result;\r
- break;\r
- }\r
- //\r
- // Skip the second expression on this pair.\r
- //\r
- SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
- if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- //\r
- // Goto the first expression on next pair.\r
- //\r
- SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
- }\r
-\r
- //\r
- // No map value is found.\r
- //\r
- if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
- Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
- Value->Value.u8 = 0;\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Status = PushExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // Pop the final result from expression stack\r
- //\r
- Value = &Data1;\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // After evaluating an expression, there should be only one value left on the expression stack\r
- //\r
- if (PopExpression (Value) != EFI_ACCESS_DENIED) {\r
- Status = EFI_INVALID_PARAMETER;\r
- }\r
-\r
-Done:\r
- RestoreExpressionEvaluationStackOffset (StackOffset);\r
- if (!EFI_ERROR (Status)) {\r
- CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
- }\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- FCE is a tool which enables developers to retrieve and change HII configuration ("Setup")\r
- data in Firmware Device files (".fd" files).\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Fce.h"\r
-\r
-#ifndef __GNUC__\r
-#define COPY_STR "copy \"%s\" \"%s\" > NUL"\r
-#define RMDIR_STR "rmdir /S /Q \"%s\" > NUL"\r
-#define DEL_STR "del \"%s\" > NUL"\r
-#else\r
-#define COPY_STR "cp \"%s\" \"%s\" > /dev/null"\r
-#define RMDIR_STR "rm -r \"%s\" > /dev/null"\r
-#define DEL_STR "rm \"%s\" > /dev/null"\r
-#endif\r
-\r
-//\r
-// Utility global variables\r
-//\r
-OPERATION_TYPE Operations;\r
-\r
-CHAR8 mInputFdName[MAX_FILENAME_LEN];\r
-CHAR8 mOutputFdName[MAX_FILENAME_LEN];\r
-CHAR8 mOutTxtName[MAX_FILENAME_LEN];\r
-CHAR8 mSetupTxtName[MAX_FILENAME_LEN];\r
-\r
-CHAR8* mUtilityFilename = NULL;\r
-UINT32 mEfiVariableAddr = 0;\r
-\r
-UQI_PARAM_LIST *mUqiList = NULL;\r
-UQI_PARAM_LIST *mLastUqiList = NULL;\r
-LIST_ENTRY mVarListEntry;\r
-LIST_ENTRY mBfvVarListEntry;\r
-LIST_ENTRY mAllVarListEntry;\r
-LIST_ENTRY mFormSetListEntry;\r
-\r
-//\r
-// Store GUIDed Section guid->tool mapping\r
-//\r
-EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
-\r
-CHAR8* mGuidToolDefinition = "GuidToolDefinitionConf.ini";\r
-\r
-//\r
-//gFfsArray is used to store all the FFS informations of Fd\r
-//\r
-G_EFI_FD_INFO gEfiFdInfo;\r
-//\r
-//mMultiPlatformParam is used to store the structures about multi-platform support\r
-//\r
-MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
-\r
-UINT32 mFormSetOrderRead;\r
-UINT32 mFormSetOrderParse;\r
-\r
-CHAR8 mFullGuidToolDefinitionDir[_MAX_PATH];\r
-\r
-CHAR8 *mFvNameGuidString = NULL;\r
-\r
-/**\r
- Check the revision of BfmLib. If not matched, return an error.\r
-\r
- @retval EFI_SUCCESS If revision matched, return EFI_SUCCESS.\r
- @retval EFI_UNSUPPORTED Other cases.\r
-**/\r
-static\r
-EFI_STATUS\r
-CheckBfmLibRevision (\r
- VOID\r
- )\r
-{\r
- CHAR8 *SystemCommandFormatString;\r
- CHAR8 *SystemCommand;\r
- CHAR8 *TempSystemCommand;\r
- CHAR8 *Revision;\r
- FILE *FileHandle;\r
- CHAR8 RevisionStr[_MAX_BUILD_VERSION];\r
- UINT32 Len;\r
-\r
- SystemCommandFormatString = NULL;\r
- SystemCommand = NULL;\r
- TempSystemCommand = NULL;\r
- Revision = "Revision.txt";\r
-\r
- memset (RevisionStr, 0, _MAX_BUILD_VERSION);\r
-\r
- //\r
- // Construction 'system' command string\r
- //\r
- SystemCommandFormatString = "BfmLib -v > %s";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (Revision) + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -v > %s",\r
- Revision\r
- );\r
-\r
- if (mFullGuidToolDefinitionDir[0] != 0) {\r
- TempSystemCommand = SystemCommand;\r
- SystemCommand = malloc (\r
- strlen (mFullGuidToolDefinitionDir) + strlen (OS_SEP_STR) + strlen (SystemCommandFormatString) + strlen (Revision) + 1\r
- );\r
-\r
- if (SystemCommand == NULL) {\r
- free (TempSystemCommand);\r
- return EFI_UNSUPPORTED;\r
- }\r
- strcpy (SystemCommand, mFullGuidToolDefinitionDir);\r
- strcat (SystemCommand, OS_SEP_STR);\r
- strcat (SystemCommand, TempSystemCommand);\r
- free (TempSystemCommand);\r
- }\r
-\r
- system (SystemCommand);\r
- free (SystemCommand);\r
- FileHandle = fopen (Revision, "r");\r
- if (FileHandle == NULL) {\r
- printf ("Error. Read the revision file of BfmLib failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- fgets(RevisionStr, _MAX_BUILD_VERSION, FileHandle);\r
- Len = strlen(RevisionStr);\r
- if (RevisionStr[Len - 1] == '\n') {\r
- RevisionStr[Len - 1] = 0;\r
- }\r
- fclose (FileHandle);\r
- remove (Revision);\r
-\r
- if (strlen (RevisionStr) > _MAX_BUILD_VERSION - 1) {\r
- printf ("The revision string is too long");\r
- return EFI_UNSUPPORTED;\r
- }\r
- if (strcmp (RevisionStr, __BUILD_VERSION) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Transfer the Ascii string to the Dec Number\r
-\r
- @param InStr The Ascii string.\r
-\r
- @retval DecNum Return the Dec number.\r
-**/\r
-static\r
-UINT64\r
-StrToDec (\r
- IN CHAR8 *InStr\r
- )\r
-{\r
- UINT8 Index;\r
- UINTN DecNum;\r
- UINTN Temp;\r
-\r
- Index = 0;\r
- DecNum = 0;\r
- Temp = 0;\r
-\r
- if (InStr == NULL) {\r
- return (UINT64)-1;\r
- }\r
- while (Index < strlen (InStr)) {\r
-\r
- if ((*(InStr + Index) >= '0') && (*(InStr + Index) <= '9')) {\r
- Temp = *(InStr + Index) - '0';\r
- } else if ((*(InStr + Index) >= 'a') && (*(InStr + Index) <= 'f')) {\r
- Temp = *(InStr + Index) - 'a' + 10;\r
- } else if ((*(InStr + Index) >= 'A') && (*(InStr + Index) <= 'F')) {\r
- Temp = *(InStr + Index) - 'A' + 10;\r
- }\r
- DecNum = DecNum + Temp * (UINTN) pow (16, strlen (InStr) - Index - 1);\r
- Index++;\r
- }\r
- return DecNum;\r
-}\r
-/**\r
- Check whether there are some errors in uqi parameters of One_of\r
-\r
- @param Question The pointer to the question Node.\r
- @param UqiValue The value of One_of.\r
-\r
- @retval TRUE If existed error, return TRUE;\r
- @return FALSE Otherwise, return FALSE;\r
-**/\r
-static\r
-BOOLEAN\r
-CheckOneOfParamError (\r
- IN CONST FORM_BROWSER_STATEMENT *Question,\r
- IN UINT64 UqiValue\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- QUESTION_OPTION *Option;\r
- UINT64 Value;\r
-\r
- Link = NULL;\r
- Option = NULL;\r
- Value = 0;\r
-\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
- Value = 0;\r
- CopyMem (&Value, &Option->Value.Value.u64, Question->StorageWidth);\r
- if (Value == UqiValue) {\r
- return FALSE;\r
- }\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Check whether there are some errors in uqi parameters of Orderlist\r
-\r
- @param HiiObjList The pointer to the Hii Object Node.\r
- @param UqiValue The pointer to the Uqi parameter.\r
-\r
- @retval TRUE If existed error, return TRUE;\r
- @return FALSE Otherwise, return FALSE;\r
-**/\r
-static\r
-BOOLEAN\r
-CheckOrderParamError (\r
- IN CONST FORM_BROWSER_STATEMENT *Question,\r
- IN CHAR8 *UqiValue\r
- )\r
-{\r
- UINT8 MaxNum;\r
- MaxNum = UqiValue[0];\r
-\r
- if (MaxNum != (UINT8)(Question->MaxContainers)) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Writes a Unicode string\r
-\r
- @param Package A pointer to the Unicode string.\r
-\r
- @return NULL\r
-**/\r
-static\r
-VOID\r
-WriteUnicodeStr (\r
- IN CHAR16 *pcString\r
- )\r
-{\r
- UINTN Index;\r
-\r
- if (pcString == NULL) {\r
- return;\r
- }\r
-\r
- for (Index = 0; pcString[Index] != 0; Index++) {\r
- printf("%c", pcString[Index] & 0x00FF);\r
- }\r
-}\r
-\r
-/**\r
- Parse and set the quick configure information by the command line.\r
-\r
- Read the UQI Config information from command line directly, and then compare it with the value in VarList.\r
- Update the Update flag in Varlist.\r
-\r
- @param CurUqiList The pointer to the current uqi\r
- @param DefaultId The default Id.\r
- @param PlatformId The platform Id.\r
- @param CurQuestion The pointer to the matched question\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @retval EFI_UNSUPPORTED Update a read-only value\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-SetUqiParametersWithQuestion (\r
- IN UQI_PARAM_LIST *CurUqiList,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId,\r
- IN FORM_BROWSER_STATEMENT *CurQuestion\r
- )\r
-{\r
- FORMSET_STORAGE *VarList;\r
- BOOLEAN IsFound;\r
- UINT8 *ValueAddrOfVar;\r
- UINT16 Index;\r
- UINT64 QuestionValue;\r
- UINT64 UqiValue;\r
- EFI_STATUS Status;\r
- CHAR8 *ErrorStr;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormSetLink;\r
- UINT64 CurValue;\r
-\r
- VarList = NULL;\r
- Index = 0;\r
- ValueAddrOfVar = NULL;\r
- QuestionValue = 0;\r
- UqiValue = 0;\r
- ErrorStr = NULL;\r
- Status = EFI_SUCCESS;\r
- FormSet = NULL;\r
- FormSetLink = NULL;\r
- CurValue = 0;\r
-\r
- //\r
- // Search the Variable List by VarStoreId and Offset\r
- //\r
- IsFound = FALSE;\r
- FormSetLink = GetFirstNode (&mFormSetListEntry);\r
- while (!IsNull (&mFormSetListEntry, FormSetLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r
- Status = SearchVarStorage (\r
- CurQuestion,\r
- NULL,\r
- CurQuestion->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **) &ValueAddrOfVar,\r
- &VarList\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- FormSetLink = GetNextNode (&mFormSetListEntry, FormSetLink);\r
- }\r
-\r
- if (!IsFound) {\r
- if (CurUqiList->Header.ScriptsLine == 0) {\r
- printf ("Error. The question in the command line doesn't store value by EFI_VARSTORE_IFR or EFI_VARSTORE_IFR_EFI.\n");\r
- } else {\r
- 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);\r
- }\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Check the length of variable value\r
- //\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)&QuestionValue);\r
- } else {\r
- switch (CurQuestion->StorageWidth) {\r
-\r
- case sizeof (UINT8):\r
- QuestionValue = *(UINT8 *)ValueAddrOfVar;\r
- break;\r
-\r
- case sizeof (UINT16):\r
- QuestionValue = *(UINT16 *)ValueAddrOfVar;\r
- break;\r
-\r
- case sizeof (UINT32):\r
- QuestionValue = *(UINT32 *)ValueAddrOfVar;\r
- break;\r
-\r
- case sizeof (UINT64):\r
- QuestionValue = *(UINT64 *)ValueAddrOfVar;\r
- break;\r
-\r
- default:\r
- //\r
- // The storage width of ORDERED_LIST may not be any type above.\r
- //\r
- ;\r
- break;\r
- }\r
- }\r
- UqiValue = *(UINT64 *)CurUqiList->Header.Value;\r
- CurUqiList->SameOrNot = TRUE;\r
-\r
- //\r
- // Check and set the checkbox value\r
- //\r
- if (CurQuestion->Operand == EFI_IFR_CHECKBOX_OP) {\r
- if ((UqiValue != 0) && (UqiValue != 1)) {\r
- CurUqiList->ErrorOrNot = TRUE;\r
- CurUqiList->SameOrNot = FALSE;\r
- CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8));\r
- if (CurUqiList->Error == NULL) {\r
- printf ("Fail to allocate memory!\n");\r
- return EFI_ABORTED;\r
- }\r
- memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH);\r
- sprintf (CurUqiList->Error, "Error. The updated value of CHECKBOX 0x%llx is invalid.\n", (unsigned long long) UqiValue);\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- } else {\r
- if (QuestionValue != UqiValue) {\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- memcpy (\r
- ValueAddrOfVar,\r
- CurUqiList->Header.Value,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- CurUqiList->SameOrNot = FALSE;\r
- }\r
- }\r
- }\r
- if (CurQuestion->Operand == EFI_IFR_STRING_OP) {\r
- if ((FceStrLen((wchar_t *)CurUqiList->Header.Value) + 1) * 2 > CurQuestion->StorageWidth) {\r
- CurUqiList->ErrorOrNot = TRUE;\r
- CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8));\r
- if (CurUqiList->Error == NULL) {\r
- printf ("Fail to allocate memory!\n");\r
- return EFI_ABORTED;\r
- }\r
- memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH);\r
- sprintf (CurUqiList->Error, "Error. The updated value of STRING exceed its Size.\n");\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- } else {\r
- if (memcmp((CHAR8 *)CurUqiList->Header.Value, ValueAddrOfVar, CurQuestion->StorageWidth) != 0) {\r
- memcpy(\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- memcpy(\r
- ValueAddrOfVar,\r
- CurUqiList->Header.Value,\r
- CurQuestion->StorageWidth\r
- );\r
- CurUqiList->SameOrNot = FALSE;\r
- }\r
- }\r
- }\r
- //\r
- // Check and set the NUMERIC value\r
- //\r
- if (CurQuestion->Operand == EFI_IFR_NUMERIC_OP) {\r
- if ((UqiValue < CurQuestion->Minimum) || (UqiValue > CurQuestion->Maximum)) {\r
- CurUqiList->ErrorOrNot = TRUE;\r
- CurUqiList->SameOrNot = FALSE;\r
- CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8));\r
- if (CurUqiList->Error == NULL) {\r
- printf ("Fail to allocate memory!\n");\r
- return EFI_ABORTED;\r
- }\r
- memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH);\r
- sprintf (CurUqiList->Error, "Error. The updated value of NUMERIC 0x%llx is invalid.\n", (unsigned long long) UqiValue);\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- } else {\r
- if (QuestionValue != UqiValue) {\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- memcpy (\r
- ValueAddrOfVar,\r
- CurUqiList->Header.Value,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- CurUqiList->SameOrNot = FALSE;\r
- }\r
- }\r
- }\r
- //\r
- // Check and set the ONE_OF value\r
- //\r
- if (CurQuestion->Operand == EFI_IFR_ONE_OF_OP) {\r
- if (CheckOneOfParamError (CurQuestion, UqiValue)) {\r
- CurUqiList->ErrorOrNot = TRUE;\r
- CurUqiList->SameOrNot = FALSE;\r
- CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8));\r
- if (CurUqiList->Error == NULL) {\r
- printf ("Fail to allocate memory!\n");\r
- return EFI_ABORTED;\r
- }\r
- memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH);\r
- sprintf (CurUqiList->Error, "Error. The updated ONE_OF value 0x%llx is invalid.\n", (unsigned long long) UqiValue);\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- } else {\r
- if (QuestionValue != UqiValue) {\r
- if (CurQuestion->QuestionReferToBitField) {\r
- GetBitsQuestionValue (CurQuestion, ValueAddrOfVar, (UINT32*)CurUqiList->Header.DiffValue);\r
- SetBitsQuestionValue (CurQuestion, ValueAddrOfVar, *(UINT32*)CurUqiList->Header.Value);\r
- } else {\r
- memcpy (\r
- CurUqiList->Header.DiffValue,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- memcpy (\r
- ValueAddrOfVar,\r
- CurUqiList->Header.Value,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- CurUqiList->SameOrNot = FALSE;\r
- }\r
- }\r
- }\r
- //\r
- // Check and set the ORDER_LIST value\r
- //\r
- if (CurQuestion->Operand == EFI_IFR_ORDERED_LIST_OP) {\r
- //\r
- // Synchronize the MaxContainers value\r
- //\r
- *CurUqiList->Header.DiffValue = (UINT8)CurQuestion->MaxContainers;\r
-\r
- if (CheckOrderParamError (CurQuestion, (CHAR8 *)CurUqiList->Header.Value)) {\r
-\r
- CurUqiList->ErrorOrNot = TRUE;\r
- CurUqiList->SameOrNot = FALSE;\r
- CurUqiList->Error = malloc (ERROR_INFO_LENGTH * sizeof (CHAR8));\r
- if (CurUqiList->Error == NULL) {\r
- printf ("Fail to allocate memory!\n");\r
- return EFI_ABORTED;\r
- }\r
- memset (CurUqiList->Error, 0, ERROR_INFO_LENGTH);\r
-\r
- ErrorStr = CurUqiList->Error;\r
- sprintf (ErrorStr, "Error. The updated NORDERED_LIST value ");\r
- ErrorStr = ErrorStr + strlen ("Error. The updated NORDERED_LIST value ");\r
-\r
- for (Index = 0; Index < CurQuestion->StorageWidth; Index++) {\r
- sprintf (ErrorStr, "%02x ", *(CurUqiList->Header.Value + Index + 1));\r
- ErrorStr +=3;\r
- }\r
- sprintf (ErrorStr, "is invalid.\n");\r
- memcpy (\r
- CurUqiList->Header.DiffValue + 1,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- } else {\r
- for (Index = 0; Index < CurQuestion->StorageWidth/CurQuestion->MaxContainers; Index++) {\r
- CurValue = 0;\r
- memcpy (\r
- &CurValue,\r
- (ValueAddrOfVar + Index * CurQuestion->StorageWidth/CurQuestion->MaxContainers),\r
- CurQuestion->StorageWidth/CurQuestion->MaxContainers\r
- );\r
- if (CurValue != *((UINT64 *)CurUqiList->Header.Value + Index + 1)) {\r
- CurUqiList->SameOrNot = FALSE;\r
- break;\r
- }\r
- }\r
- if (!CurUqiList->SameOrNot) {\r
- memcpy (\r
- CurUqiList->Header.DiffValue + 1,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- for (Index = 0; Index < CurQuestion->MaxContainers; Index++) {\r
- switch (CurQuestion->StorageWidth/CurQuestion->MaxContainers) {\r
-\r
- case sizeof (UINT8):\r
- *((UINT8 *)ValueAddrOfVar + Index) = *(UINT8 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index);\r
- break;\r
-\r
- case sizeof (UINT16):\r
- *((UINT16 *)ValueAddrOfVar + Index) = *(UINT16 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index);\r
- break;\r
-\r
- case sizeof (UINT32):\r
- *((UINT32 *)ValueAddrOfVar + Index) = *(UINT32 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index);\r
- break;\r
-\r
- case sizeof (UINT64):\r
- *((UINT64 *)ValueAddrOfVar + Index) = *((UINT64 *)CurUqiList->Header.Value + 1 + Index);\r
- break;\r
-\r
- default:\r
- *((UINT8 *)ValueAddrOfVar + Index) = *(UINT8 *)((UINT64 *)CurUqiList->Header.Value + 1 + Index);\r
- break;\r
- }\r
- }\r
- //\r
- // Update the vaule of ORDERED_LIST according to its size\r
- //\r
- CurUqiList->Header.Value = (UINT8 *)((UINT64 *)CurUqiList->Header.Value);\r
- memcpy (\r
- CurUqiList->Header.Value + 1,\r
- ValueAddrOfVar,\r
- CurQuestion->StorageWidth\r
- );\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Parse and set the quick configure information by the command line.\r
-\r
- Read the UQI Config information from command line directly, and then compare it with the value in VarList.\r
- Update the Update flag in Varlist.\r
-\r
- @param UqiList The pointer to the uqi list\r
- @param DefaultId The default Id.\r
- @param PlatformId The platform Id.\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @retval EFI_UNSUPPORTED Update a read-only value\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-SetUqiParameters (\r
- IN UQI_PARAM_LIST *UqiList,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
- )\r
-{\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormSetLink;\r
- FORM_BROWSER_FORM *Form;\r
- LIST_ENTRY *FormLink;\r
- FORM_BROWSER_STATEMENT *Question;\r
- LIST_ENTRY *QuestionLink;\r
- LIST_ENTRY *FormSetEntryListHead;\r
- UQI_PARAM_LIST *CurUqiList;\r
-\r
- FormSet = NULL;\r
- FormSetLink = NULL;\r
- Form = NULL;\r
- FormLink = NULL;\r
- Question = NULL;\r
- QuestionLink = NULL;\r
- FormSetEntryListHead = &mFormSetListEntry;\r
-\r
- FormSetLink = GetFirstNode (FormSetEntryListHead);\r
- while (!IsNull (FormSetEntryListHead, FormSetLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r
- //\r
- // Parse all forms in formset\r
- //\r
- FormLink = GetFirstNode (&FormSet->FormListHead);\r
-\r
- while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r
- //\r
- if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r
- continue;\r
- }\r
- if ((Question->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- && Question->NewEfiVarstore\r
- && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r
- continue;\r
- }\r
- }\r
-\r
- CurUqiList = UqiList;\r
- while (CurUqiList != NULL) {\r
- if ((PlatformId == CurUqiList->Header.PlatformId[0])\r
- && (DefaultId == CurUqiList->Header.DefaultId[0])\r
- && CompareUqiHeader (&(Question->Uqi), &(CurUqiList->Header))\r
- ) {\r
- //\r
- // Add further check to avoid a case that there are many options with a\r
- // same UQI (en-Us), but always returns the first one.\r
- //\r
- if (!CurUqiList->ParseOrNot) {\r
- CurUqiList->ParseOrNot = TRUE;\r
- break;\r
- }\r
- }\r
- CurUqiList = CurUqiList->Next;\r
- }\r
- if (CurUqiList != NULL) {\r
- SetUqiParametersWithQuestion (CurUqiList, DefaultId, PlatformId, Question);\r
- }\r
- }\r
- }\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- }\r
- FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Set question value per UqiList.\r
-\r
- @param UqiList The pointer to the uqi list\r
- @param DefaultId The default Id.\r
- @param PlatformId The platform Id.\r
-**/\r
-VOID\r
-SetUqiParametersMultiMode (\r
- IN UQI_PARAM_LIST *UqiList,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
- )\r
-{\r
- UQI_PARAM_LIST *CurUqiList;\r
-\r
- CurUqiList = UqiList;\r
- while (CurUqiList != NULL) {\r
- if ((CurUqiList->ParseOrNot == FALSE)\r
- && (PlatformId == CurUqiList->Header.PlatformId[0])\r
- && (DefaultId == CurUqiList->Header.DefaultId[0])\r
- ) {\r
- CurUqiList->ParseOrNot = TRUE;\r
- if (CurUqiList->Header.Question != NULL) {\r
- SetUqiParametersWithQuestion (CurUqiList, DefaultId, PlatformId, CurUqiList->Header.Question);\r
- }\r
- }\r
- CurUqiList = CurUqiList->Next;\r
- }\r
-}\r
-\r
-/**\r
- Find the matched question for each UQI string in UqiList\r
-\r
-**/\r
-EFI_STATUS\r
-ScanUqiFullList (\r
- IN UQI_PARAM_LIST *UqiList\r
- )\r
-{\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormSetLink;\r
- FORM_BROWSER_FORM *Form;\r
- LIST_ENTRY *FormLink;\r
- FORM_BROWSER_STATEMENT *Question;\r
- LIST_ENTRY *QuestionLink;\r
- LIST_ENTRY *FormSetEntryListHead;\r
- UQI_PARAM_LIST *CurUqiList;\r
- UINT64 PlatformId;\r
- UINT16 DefaultId;\r
-\r
- if (UqiList == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
- FormSet = NULL;\r
- FormSetLink = NULL;\r
- Form = NULL;\r
- FormLink = NULL;\r
- Question = NULL;\r
- QuestionLink = NULL;\r
- FormSetEntryListHead = &mFormSetListEntry;\r
-\r
- FormSetLink = FormSetEntryListHead->ForwardLink;\r
- while (FormSetEntryListHead != FormSetLink) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r
- //\r
- // Parse all forms in formset\r
- //\r
- FormLink = FormSet->FormListHead.ForwardLink;\r
-\r
- while (&FormSet->FormListHead != FormLink) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = Form->StatementListHead.ForwardLink;\r
-\r
- while (&Form->StatementListHead != QuestionLink) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- QuestionLink = QuestionLink->ForwardLink;\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- //\r
- // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r
- //\r
- if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r
- continue;\r
- } else if (Question->NewEfiVarstore\r
- && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r
- continue;\r
- }\r
-\r
- CurUqiList = UqiList;\r
- PlatformId = 0xFFFFFFFF;\r
- DefaultId = 0xFFFF;\r
- while (CurUqiList != NULL) {\r
- if ((CurUqiList->Header.Question == NULL)\r
- && CompareUqiHeader (&(Question->Uqi), &(CurUqiList->Header))\r
- && ((PlatformId != CurUqiList->Header.PlatformId[0]) || (DefaultId != CurUqiList->Header.DefaultId[0]))\r
- ) {\r
- CurUqiList->Header.Question = Question;\r
- PlatformId = CurUqiList->Header.PlatformId[0];\r
- DefaultId = CurUqiList->Header.DefaultId[0];\r
- }\r
- CurUqiList = CurUqiList->Next;\r
- }\r
- }\r
- }\r
- FormLink = FormLink->ForwardLink;\r
- }\r
- FormSetLink = FormSetLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Create and insert the UQI Node to the UQI parameter list.\r
-\r
- @retval Node address If successed, return the node address.\r
- @retval NULL An error occurred.\r
-\r
-**/\r
-static\r
-UQI_PARAM_LIST *\r
-CreateInsertUqiNode (\r
- )\r
-{\r
- UQI_PARAM_LIST *Node;\r
-\r
- Node = (UQI_PARAM_LIST *) malloc (sizeof (UQI_PARAM_LIST));\r
- if (Node == NULL) {\r
- return NULL;\r
- }\r
- memset (Node, 0, sizeof (UQI_PARAM_LIST));\r
-\r
- if (mUqiList == NULL) {\r
- mUqiList = Node;\r
- } else {\r
- mLastUqiList->Next = Node;\r
- }\r
-\r
- mLastUqiList = Node;\r
- return Node;\r
-}\r
-/**\r
- Parse the first part of QUI string\r
-\r
- @param **argv[] The dual array pointer to the parameters.\r
- @param Number The pointer to the number of the first character of UQI.\r
- @param Buffer The buffer to store the first part of UQI.\r
-\r
- @retval EFI_SUCCESS Parse the QUI parameters successfully.\r
- @retval EFI_INVALID_PARAMETER An error occurred.\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-ParseFirstpartOfUqi (\r
- IN CHAR8 **argv[],\r
- OUT UINT32 *Number,\r
- OUT UINT16 **Buffer\r
- )\r
-{\r
- UINT32 Index;\r
-\r
- Index = 0;\r
-\r
- *Number = (UINT32)StrToDec ((*argv)[0]);\r
-\r
- if ((*Number <= 0) || (*Number > MAX_QUI_PARAM_LEN)) {\r
- printf ("Error. Invalid UQI.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Buffer = malloc ((*Number + 1) * sizeof (CHAR16));\r
- assert (*Buffer != NULL);\r
- memset (*Buffer, 0, (*Number + 1) * sizeof (CHAR16));\r
-\r
- for (Index = 0; Index < *Number; Index++) {\r
- if (StrToDec ((*argv)[Index]) > 0xff) {\r
- printf ("Error. Invalid UQI.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- *(*Buffer + Index) = (UINT16)StrToDec ((*argv)[Index + 1]);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Parse the QUI input parameters from the command line\r
-\r
- @param argc The pointer to the number of input parameters.\r
- @param **argv[] The dual array pointer to the parameters.\r
-\r
- @retval EFI_SUCCESS Parse the QUI parameters successfully.\r
- @retval EFI_INVALID_PARAMETER An error occurred.\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-ParseUqiParam (\r
- IN UINT32 *argc,\r
- IN CHAR8 **argv[]\r
- )\r
-{\r
- UINT32 Index;\r
- UQI_PARAM_LIST *UqiNode;\r
- EFI_STATUS Status;\r
-\r
- Index = 0;\r
- UqiNode = NULL;\r
-\r
- if (*argc < 4) {\r
- printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- UqiNode = CreateInsertUqiNode ();\r
- assert (UqiNode != NULL);\r
-\r
- UqiNode->Header.DefaultId = (UINT16 *) calloc (1, sizeof (UINT16));\r
- UqiNode->Header.PlatformId = (UINT64 *) calloc (1, sizeof (UINT64));\r
-\r
- Status = ParseFirstpartOfUqi (argv, &(UqiNode->Header.HexNum), &(UqiNode->Header.Data));\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- *argc -= (UqiNode->Header.HexNum + 1);\r
- *argv += UqiNode->Header.HexNum + 1;\r
- //\r
- // Parse the TYPE and value\r
- //\r
- if (strcmp ("ONE_OF", (*argv)[0]) == 0) {\r
- UqiNode->Header.Type = ONE_OF;\r
- } else if (strcmp ("NUMERIC", (*argv)[0]) == 0) {\r
- UqiNode->Header.Type = NUMERIC;\r
- } else if (strcmp ("CHECKBOX", (*argv)[0]) == 0) {\r
- UqiNode->Header.Type = CHECKBOX;\r
- } else if (strcmp ("STRING", (*argv)[0]) == 0) {\r
- UqiNode->Header.Type = STRING;\r
- } else if (strcmp ("ORDERED_LIST", (*argv)[0]) == 0) {\r
- UqiNode->Header.Type = ORDERED_LIST;\r
- } else {\r
- printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- *argc -= 1;\r
- *argv += 1;\r
- //\r
- // Get the value according to the type of questions.\r
- //\r
- switch (UqiNode->Header.Type) {\r
-\r
- case ONE_OF:\r
- case NUMERIC:\r
- case CHECKBOX:\r
- UqiNode->Header.Value = malloc (sizeof (UINT64));\r
- if (UqiNode->Header.Value == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (UqiNode->Header.Value, 0, sizeof (UINT64));\r
-\r
- UqiNode->Header.DiffValue = malloc (sizeof (UINT64));\r
- if (UqiNode->Header.DiffValue == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (\r
- UqiNode->Header.DiffValue,\r
- 0,\r
- sizeof (UINT64)\r
- );\r
- *(UINT64 *)(UqiNode->Header.Value) = (UINT64)StrToDec ((*argv)[0]);\r
- break;\r
-\r
- case ORDERED_LIST:\r
- UqiNode->Header.Value = malloc (((UINTN)StrToDec ((*argv)[0]) + 1) * sizeof (UINT64));\r
- if (UqiNode->Header.Value == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (\r
- UqiNode->Header.Value,\r
- 0,\r
- (UINTN)StrToDec(((*argv)[0]) + 1) * sizeof (UINT64)\r
- );\r
-\r
- UqiNode->Header.DiffValue = malloc (((UINTN)StrToDec ((*argv)[0]) + 1) * sizeof (UINT64));\r
- if (UqiNode->Header.DiffValue == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (\r
- UqiNode->Header.DiffValue,\r
- 0,\r
- (UINTN)(StrToDec ((*argv)[0]) + 1) * sizeof (UINT64)\r
- );\r
-\r
- *UqiNode->Header.Value = (UINT8)StrToDec ((*argv)[0]);\r
- for (Index = 1; Index <= StrToDec ((*argv)[0]); Index++) {\r
- *((UINT64 *)UqiNode->Header.Value + Index) = StrToDec ((*argv)[Index]);\r
- }\r
- *argc -= (UINTN)StrToDec ((*argv)[0]);\r
- *argv += (UINTN)StrToDec ((*argv)[0]);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- *argc -= 1;\r
- *argv += 1;\r
-\r
- if (*argc > 0) {\r
- printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-/**\r
- Parse the input Fd file, and get the file name according to the FILETYPE.\r
-\r
- @param FdName The Name of Fd file\r
- @param FILETYPE The type of Fd file\r
-\r
- @return EFI_SUCCESS Get the file name successfully\r
- @return EFI_ABORTED An error occurred.\r
-**/\r
-static\r
-EFI_STATUS\r
-ParseInFile (\r
- IN CHAR8 *FdName,\r
- IN FILETYPE Type\r
-)\r
-{\r
- FILE *Fptr;\r
-\r
- Fptr = NULL;\r
-\r
- if ((Type == INFD) && ((FdName == NULL) || (Fptr = fopen (FdName, "r")) == NULL)) {\r
- if (FdName != NULL) {\r
- printf ("Error: The <infd> file doesn't exist '%s'\n", FdName);\r
- }\r
- return EFI_ABORTED;\r
- }\r
- if ((Type == OUTFD) && (FdName == NULL) ) {\r
- printf ("Error: The <Outfd> name is NULL.\n");\r
- return EFI_ABORTED;\r
- }\r
- if ((Type == SETUPTXT) && (FdName == NULL) ) {\r
- printf ("Error: The <script> name is NULL.\n");\r
- return EFI_ABORTED;\r
- }\r
- if (strlen (FdName) > MAX_FILENAME_LEN - 1) {\r
- printf ("Error: The <fd> name is too long.\n");\r
- if (Fptr != NULL) {\r
- fclose (Fptr);\r
- }\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Get and copy the file name\r
- //\r
- if (Type == INFD) {\r
- strncpy (mInputFdName, FdName, MAX_FILENAME_LEN - 1);\r
- mInputFdName[MAX_FILENAME_LEN - 1] = 0;\r
- }\r
- if (Type == OUTFD) {\r
- strncpy (mOutputFdName, FdName, MAX_FILENAME_LEN - 1);\r
- mOutputFdName[MAX_FILENAME_LEN - 1] = 0;\r
- }\r
- if (Type == OUTTXT) {\r
- strncpy (mOutTxtName, FdName, MAX_FILENAME_LEN - 1);\r
- mOutTxtName[MAX_FILENAME_LEN - 1] = 0;\r
- }\r
- if (Type == SETUPTXT) {\r
- strncpy (mSetupTxtName, FdName, MAX_FILENAME_LEN - 1);\r
- mSetupTxtName[MAX_FILENAME_LEN - 1] = 0;\r
- }\r
- if (Fptr != NULL) {\r
- fclose (Fptr);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-/**\r
- Print the usage of this tools.\r
-\r
- @return NULL\r
-**/\r
-static\r
-VOID\r
-Usage (\r
- VOID\r
- )\r
-{\r
- //\r
- // Print utility header\r
- //\r
- printf ("\nIntel(R) Firmware Configuration Editor. (Intel(R) %s) Version %d.%d. %s.\n\n",\r
- UTILITY_NAME,\r
- UTILITY_MAJOR_VERSION,\r
- UTILITY_MINOR_VERSION,\r
- __BUILD_VERSION\r
- );\r
- //\r
- // Copyright declaration\r
- //\r
- fprintf (stdout, "Copyright (c) 2010-2018, Intel Corporation. All rights reserved.\n\n");\r
- //\r
- // Summary usage\r
- //\r
- fprintf (stdout, "The tool enables you to retrieve and change HII configuration (Setup) data in \n");\r
- fprintf (stdout, "Firmware Device files.\n");\r
- fprintf (stdout, "\nUsage: \n");\r
- fprintf (stdout, " FCE [read -i <infd> [<PlatformId UQI>] ['>' <script>]] \n");\r
- fprintf (stdout, " FCE [update -i <infd> [<PlatformId UQI>|-s <script>] -o <outfd>\n");\r
- fprintf (stdout, " [--remove|--ignore] [-g <FvNameGuid>]] [-a]\n");\r
- fprintf (stdout, " FCE [verify -i <infd> -s <script>] \n");\r
- fprintf (stdout, " FCE [updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>] \n");\r
- fprintf (stdout, " FCE [[help] | [-?]] \n");\r
- fprintf (stdout, "\n");\r
-\r
- fprintf (stdout, "Options:\n");\r
- fprintf (stdout, " read Extract the HII data from the <infd> file. \n");\r
- fprintf (stdout, " update Update the HII data to the <outfd> file. \n");\r
- fprintf (stdout, " verify Verify the current platform configuration. \n");\r
- fprintf (stdout, " updateq Update the current platform configuration by command line.\n");\r
- fprintf (stdout, " updateq only supports common mode.\n");\r
- fprintf (stdout, " help Display the help information.\n");\r
-\r
- fprintf (stdout, " <infd> The name of a existing Firmware Device binary file input. \n");\r
- fprintf (stdout, " <PlatformId UQI> The UQI is required in multi-platform mode to represent a \n");\r
- fprintf (stdout, " PlatformId question from the VFR files used during binary \n");\r
- fprintf (stdout, " image creation. It must not be used for common mode. \n");\r
- fprintf (stdout, " <outfd> The name of a Firmware Device binary file output. \n");\r
- fprintf (stdout, " <script> The name of a configure scripts.\n");\r
- fprintf (stdout, " <UQI> A hex number followed by an array of hex numbers. \n");\r
- fprintf (stdout, " <Question Type> One of ORDERED_LIST, ONE_OF, NUMERIC, STRING or CHECKBOX. \n");\r
- fprintf (stdout, " <Value> A single hex number, if the <Question Type> is ONE_OF,\n");\r
- fprintf (stdout, " NUMERIC, or CHECKBOX. Or a single hex number containing \n");\r
- fprintf (stdout, " the array size followed by an array of that length of hex\n");\r
- fprintf (stdout, " numbers, if the <Question Type> is ORDERED_LIST. \n");\r
- fprintf (stdout, " <FvNameGuid> GuidValue is one specific FvName guid value.\n");\r
- fprintf (stdout, " Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.\n");\r
- fprintf (stdout, " -i Import an existing FD file <infd>. \n");\r
- fprintf (stdout, " -o Create the new FD with the changes made. \n");\r
- fprintf (stdout, " -s Import config scripts. \n");\r
- fprintf (stdout, " > Redirect the output to a scripts. \n");\r
- fprintf (stdout, " -? Display the help information. \n");\r
- fprintf (stdout, " --remove If one or more of the settings that are updated also \n");\r
- fprintf (stdout, " exists in NV RAM, remove them only in multi-platform mode.\n");\r
- fprintf (stdout, " --ignore If one or more of the settings that are updated also \n");\r
- fprintf (stdout, " existsin NV RAM, ignore them only in multi-platform mode.\n");\r
- fprintf (stdout, " -g Specify the FV image to store the multi-platform default \n");\r
- fprintf (stdout, " setting. If it is missing, the multi-platform default \n");\r
- fprintf (stdout, " will be inserted into BFV image.\n");\r
- fprintf (stdout, " -a Specify this tool to choose the smaller size between two \n");\r
- fprintf (stdout, " different storage formats in NV RAM. It's only vaild in \n");\r
- fprintf (stdout, " multi-platform mode. \n");\r
- fprintf (stdout, "\n");\r
-\r
- fprintf (stdout, "Mode:\n");\r
- fprintf (stdout, " Common Extract the HII data from IFR binary and update it to the \n");\r
- fprintf (stdout, " EFI variable. \n");\r
- fprintf (stdout, " Multi-platform The default value depends on the PlatformId and DefaultId \n");\r
- fprintf (stdout, " described in the VFR files. This tool will create the \n");\r
- fprintf (stdout, " binary file to store default settings at build time for \n");\r
- fprintf (stdout, " different platforms and modes adding all default settings \n");\r
- fprintf (stdout, " into BFV as one FFS.\n");\r
-\r
- fprintf (stdout, "\n");\r
-}\r
-\r
-/**\r
- Parse the command line parameters\r
-\r
- @param argc The pointer to number of input parameters.\r
- @param *argv[] The pointer to the parameters.\r
-\r
- @retval EFI_SUCCESS Parse the parameters successfully.\r
- @retval EFI_INVALID_PARAMETER An error occurred.\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-ParseCommmadLine (\r
- IN UINTN argc,\r
- IN CHAR8 *argv[]\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Index;\r
- UINT8 IndexParamI;\r
- UINT8 IndexParamS;\r
- UINT8 IndexParamO;\r
- UINT8 IndexParamRemove;\r
- UINT8 IndexParamIgnore;\r
- UINT8 IndexParamOptimize;\r
- EFI_GUID FvNameGuid;\r
-\r
- Status = EFI_SUCCESS;\r
- Index = 0;\r
- IndexParamI = 0;\r
- IndexParamO = 0;\r
- IndexParamS = 0;\r
- IndexParamRemove = 0;\r
- IndexParamIgnore = 0;\r
- IndexParamOptimize = 0;\r
- mMultiPlatformParam.SizeOptimizedParam = FALSE;\r
- //\r
- // Check for only own one operations\r
- //\r
- if (argc == 0) {\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- if (\r
- argc == 1 \\r
- && ((stricmp(argv[0], "read") == 0) \\r
- || (stricmp(argv[0], "update") == 0) \\r
- || (stricmp(argv[0], "updateq") == 0) \\r
- || (stricmp(argv[0], "verify") == 0) )\r
- ) {\r
- printf ("Error: Some parameters have been lost. Please correct. \n");\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- while (argc > 0) {\r
- if (stricmp(argv[0], "read") == 0) {\r
- Operations = READ;\r
- argc--;\r
- argv++;\r
-\r
- if (argc < 2) {\r
- printf ("Error. The correct command is 'FCE read -i <infd>'. \n");\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- //\r
- // Get input FD file name.\r
- //\r
- if (stricmp (argv[0], "-i") == 0) {\r
- Status = ParseInFile (argv[1], INFD);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- }\r
- //\r
- // Parse the QUI parameters\r
- //\r
- if (argc > 2) {\r
- Status = ParseFirstpartOfUqi (&argv, &(mMultiPlatformParam.Uqi.HexNum), &(mMultiPlatformParam.Uqi.Data));\r
- mMultiPlatformParam.MultiPlatformOrNot = TRUE;\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
- break;\r
-\r
- } else if (stricmp(argv[0], "update") == 0) {\r
- //\r
- // Update the config file to Fd\r
- //\r
- Operations = UPDATE;\r
- argc--;\r
- argv++;\r
-\r
- if (argc < 4) {\r
- printf ("Error. The correct command is 'FCE update -i <infd> [<PlatformId UQI>|-s <script>] -o <outfd>' \n");\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- continue;\r
- } else if (stricmp(argv[0], "verify") == 0) {\r
- //\r
- // 3. Parse the command line "FCE verify -i <infd> -s <script>"\r
- //\r
- Operations = VERIFY;\r
- argc--;\r
- argv++;\r
-\r
- if (argc < 4) {\r
- printf ("Error. The correct command is 'FCE verify -i <infd> -s <script>'\n");\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- continue;\r
- } else if (stricmp(argv[0], "updateq") == 0) {\r
- //\r
- // Parse the command line "FCE updateq -i <infd> -o<outfd> <UQI> <Question Type> <Value>"\r
- //\r
- argc--;\r
- argv++;\r
-\r
- //\r
- // Get input/output FD file name.\r
- //\r
- Index = 2;\r
- while ((Index > 0) && (argc > 1)) {\r
- if (stricmp (argv[0], "-i") == 0) {\r
- Status = ParseInFile (argv[1], INFD);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- Index--;\r
- IndexParamI++;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "-o") == 0) {\r
- Status = ParseInFile (argv[1], OUTFD);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- Index--;\r
- IndexParamO++;\r
- continue;\r
- }\r
- if (\r
- (argc >= 1) \\r
- && (stricmp(argv[0], "-o") != 0) \\r
- && (stricmp(argv[0], "-i") != 0)\r
- ) {\r
- printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>' \n");\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- }\r
-\r
- if (Index != 0) {\r
- printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>' \n");\r
- Usage ();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Parse the QUI parameters\r
- //\r
- Status = ParseUqiParam ((UINT32 *)&argc,&argv);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Operations = UPDATEQ;\r
- break;\r
- }\r
-\r
- if (stricmp (argv[0], "-i") == 0) {\r
- Status = ParseInFile (argv[1], INFD);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- IndexParamI++;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "-o") == 0) {\r
- Status = ParseInFile (argv[1], OUTFD);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- IndexParamO++;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "-s") == 0) {\r
- Status = ParseInFile (argv[1], SETUPTXT);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- argc -= 2;\r
- argv += 2;\r
- IndexParamS++;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "-g") == 0) {\r
- Status = StringToGuid (argv[1], &FvNameGuid);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error: Invalid parameters for -g option in command line. \n");\r
- Usage();\r
- goto Done;\r
- }\r
- mFvNameGuidString = argv[1];\r
- argc -= 2;\r
- argv += 2;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "-a") == 0) {\r
- argc -= 1;\r
- argv += 1;\r
- IndexParamOptimize++;\r
- mMultiPlatformParam.SizeOptimizedParam = TRUE;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "--remove") == 0) {\r
- argc -= 1;\r
- argv += 1;\r
- IndexParamRemove++;\r
- Operations = UPDATE_REMOVE;\r
- continue;\r
- }\r
-\r
- if (stricmp (argv[0], "--ignore") == 0) {\r
- argc -= 1;\r
- argv += 1;\r
- IndexParamIgnore++;\r
- Operations = UPDATE_IGNORE;\r
- continue;\r
- }\r
-\r
- if ((stricmp(argv[0], "help") == 0) || (stricmp(argv[0], "-?") == 0)) {\r
-\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- //\r
- // Operations should not be none\r
- //\r
- if ( Operations == NONE ) {\r
- printf ("Error. Only support read/update/verify/updateq mode. \n");\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (Operations == UPDATE) {\r
- Status = ParseFirstpartOfUqi (&argv, &(mMultiPlatformParam.Uqi.HexNum), &(mMultiPlatformParam.Uqi.Data));\r
- if (!EFI_ERROR (Status)) {\r
- mMultiPlatformParam.MultiPlatformOrNot = TRUE;\r
- argc = argc - mMultiPlatformParam.Uqi.HexNum - 1;\r
- argv = argv + mMultiPlatformParam.Uqi.HexNum + 1;\r
- continue;\r
- }\r
- }\r
-\r
- if (\r
- (argc >= 1) \\r
- && (stricmp(argv[0], "-?") != 0)\r
- && (stricmp(argv[0], "help") != 0)\r
- && (stricmp(argv[0], "verify") != 0)\r
- && (stricmp(argv[0], "read") != 0)\r
- && (stricmp(argv[0], "update") != 0)\r
- && (stricmp(argv[0], "updateq") != 0)\r
- && (stricmp(argv[0], "-o") != 0)\r
- && (stricmp(argv[0], "-i") != 0)\r
- && (stricmp(argv[0], "-s") != 0)\r
- && (stricmp(argv[0], "-a") != 0)\r
- && (stricmp(argv[0], "-g") != 0)\r
- && (stricmp(argv[0], "--remove") != 0)\r
- && (stricmp(argv[0], "--ignore") != 0)\r
- ) {\r
- printf ("Error: Invalid parameters exist in command line. \n");\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- }\r
- //\r
- // Check the repeated parameters in command line, such as "-i -i"\r
- //\r
- if (\r
- (IndexParamI > 1)\r
- || (IndexParamO > 1)\r
- || (IndexParamS > 1)\r
- || (IndexParamOptimize > 1)\r
- || (IndexParamRemove > 1)\r
- || (IndexParamIgnore > 1)\r
- ) {\r
- printf ("Error: Redundant parameters exist in command line.\n");\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- //\r
- // Check improper parameters in command line, such as "FCE read -i -s"\r
- //\r
- if (\r
- ((Operations == READ) && ((IndexParamO >= 1) || (IndexParamS >= 1) || (IndexParamRemove >= 1) || (IndexParamIgnore >= 1))) \\r
- || ((Operations == VERIFY) && ((IndexParamO >= 1) || (IndexParamRemove >= 1) || (IndexParamIgnore >= 1))) \\r
- || ((Operations == UPDATEQ) && ((IndexParamS >= 1) || (IndexParamRemove >= 1) || (IndexParamIgnore >= 1))) \\r
- || ((Operations == UPDATE) && ((IndexParamRemove >= 1) && (IndexParamIgnore >= 1)))\r
- || ((Operations != UPDATE && Operations != UPDATE_REMOVE && Operations != UPDATE_IGNORE) && ((IndexParamOptimize >= 1) || (mFvNameGuidString != NULL)))\r
- ) {\r
- printf ("Error: Improper parameters exist in command line. \n");\r
- Usage();\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-Done:\r
- return Status;\r
-}\r
-\r
-/**\r
- Check whether exists the valid variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-static\r
-BOOLEAN\r
-ExistEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- BOOLEAN Existed;\r
- VOID *VariableStoreHeader;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
-\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VOID *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- AuthencitatedMonotonicOrNot = FALSE;\r
- AuthencitatedBasedTimeOrNot = FALSE;\r
- Existed = TRUE;\r
- //\r
- // Judge the layout of NV by gEfiVariableGuid\r
- //\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore (VariableStoreHeader);\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot (VariableStoreHeader);\r
-\r
- if (AuthencitatedMonotonicOrNot) {\r
- //\r
- // Check the Monotonic based authenticate variable\r
- //\r
- Existed = ExistMonotonicBasedEfiVarOrNot (StorageListHead);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- //\r
- // Check the Time Sample authenticate variable\r
- //\r
- Existed = ExistTimeBasedEfiVarOrNot (StorageListHead);\r
- } else {\r
- //\r
- // Check the normal variable\r
- //\r
- Existed = ExistNormalEfiVarOrNot (StorageListHead);\r
- }\r
-\r
- return Existed;\r
-}\r
-\r
-/**\r
- Exchange the data between Efi variable and the data of VarList\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-static\r
-EFI_STATUS\r
-EfiVarAndListExchange (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- EFI_STATUS Status;\r
- VOID *VariableStoreHeader;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
-\r
- Status = EFI_ABORTED;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VOID *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- AuthencitatedMonotonicOrNot = FALSE;\r
- AuthencitatedBasedTimeOrNot = FALSE;\r
- //\r
- // Judge the layout of NV by gEfiVariableGuid\r
- //\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore (VariableStoreHeader);\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot (VariableStoreHeader);\r
-\r
- if (AuthencitatedMonotonicOrNot) {\r
- //\r
- // Update the Monotonic based authenticate variable\r
- //\r
- Status = SynAuthEfiVariable (VarToList, StorageListHead);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- //\r
- // Update the Time Sample authenticate variable\r
- //\r
- Status = SynAuthEfiVariableBasedTime (VarToList, StorageListHead);\r
- } else {\r
- //\r
- // Update the normal variable\r
- //\r
- Status = SynEfiVariable (VarToList, StorageListHead);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Check the layout of NvStorage and remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-static\r
-EFI_STATUS\r
-RemoveEfiVar (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- EFI_STATUS Status;\r
- VOID *VariableStoreHeader;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
-\r
- Status = EFI_ABORTED;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VOID *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- AuthencitatedMonotonicOrNot = FALSE;\r
- AuthencitatedBasedTimeOrNot = FALSE;\r
- //\r
- // Judge the layout of NV by gEfiVariableGuid\r
- //\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore (VariableStoreHeader);\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot (VariableStoreHeader);\r
-\r
- if (AuthencitatedMonotonicOrNot) {\r
- //\r
- // Update the Monotonic based authenticate variable\r
- //\r
- Status = RemoveAuthEfiVariable (StorageListHead);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- //\r
- // Update the Time Sample authenticate variable\r
- //\r
- Status = RemoveAuthEfiVariableBasedTime (StorageListHead);\r
- } else {\r
- //\r
- // Update the normal variable\r
- //\r
- Status = RemoveNormalEfiVariable (StorageListHead);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Parse the all formset in one VfrBin.\r
-\r
- Parse all questions, variables and expression in VfrBin, and store\r
- it in Formset and Form.\r
-\r
- @param BaseAddr The pointer to the array of VfrBin base address.\r
- @param UniBinBaseAddress The pointer to one Uni string base address.\r
-\r
- @retval EFI_SUCCESS The Search was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-ParseFormSetInVfrBin (\r
- IN UINTN **BaseAddr,\r
- IN UINTN *UniBinBaseAddress,\r
- IN UINT8 Index\r
- )\r
-{\r
- UINT32 PackageLength;\r
- EFI_STATUS Status;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- UINT8 *IfrBinaryData;\r
- EFI_IFR_OP_HEADER *IfrOpHdr;\r
- UINT32 IfrOffset;\r
-\r
- PackageLength = 0;\r
- Status = EFI_SUCCESS;\r
- FormSet = NULL;\r
- IfrBinaryData = NULL;\r
- IfrOpHdr = NULL;\r
-\r
- //\r
- // The first 4 Bytes of VfrBin is used to record the Array Length\r
- // The header of VfrBin is, ARRAY LENGTH:4 Bytes, PACKAGE HEADER:4 Bytes (2 Bytes for Len, and the other for Type)\r
- //\r
- PackageLength = *(UINT32 *)*(BaseAddr + Index) - 4;\r
- IfrBinaryData = (UINT8 *)*(BaseAddr + Index) + 4;\r
-\r
- //\r
- // Go through the form package to parse OpCode one by one.\r
- //\r
- IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
-\r
- while (IfrOffset < PackageLength) {\r
- //\r
- // Search the Formset in VfrBin\r
- //\r
- IfrOpHdr = (EFI_IFR_OP_HEADER *) (IfrBinaryData + IfrOffset);\r
-\r
- if (IfrOpHdr->OpCode == EFI_IFR_FORM_SET_OP) {\r
- FormSet = calloc (sizeof (FORM_BROWSER_FORMSET), sizeof (CHAR8));\r
- if (FormSet == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- FormSet->IfrBinaryData = IfrBinaryData + IfrOffset;\r
- FormSet->UnicodeBinary = (UINT8 *) UniBinBaseAddress;\r
- //\r
- //This length will be corrected in ParseOpCodes function.\r
- //\r
- FormSet->IfrBinaryLength = PackageLength - IfrOffset;\r
- //\r
- // Parse opcodes in the formset IFR binary.\r
- //\r
- Status = ParseOpCodes (FormSet);\r
- if (EFI_ERROR (Status)) {\r
- DestroyAllStorage (FormSet->StorageListHead);\r
- DestroyFormSet (FormSet);\r
- return EFI_ABORTED;\r
- }\r
- IfrOffset += FormSet->IfrBinaryLength;\r
- FormSet->EnUsStringList.StringInfoList = calloc (sizeof (STRING_INFO), STRING_NUMBER);\r
- FormSet->EnUsStringList.CachedIdNum = 0;\r
- FormSet->EnUsStringList.MaxIdNum = STRING_NUMBER;\r
- FormSet->UqiStringList.StringInfoList = calloc (sizeof (STRING_INFO), STRING_NUMBER);\r
- FormSet->UqiStringList.CachedIdNum = 0;\r
- FormSet->UqiStringList.MaxIdNum = STRING_NUMBER;\r
- //\r
- // Insert the FormSet to mFormSet\r
- //\r
- InsertTailList (&mFormSetListEntry, &FormSet->Link);\r
- } else {\r
- IfrOffset += IfrOpHdr->Length;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Store all defaultId to mMultiPlatformParam.\r
-\r
- The mMultiPlatformParam.DefaultId[0] is used to store standard default.\r
-\r
- @param DefaultId The current defaultID.\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-VOID\r
-StoreAllDefaultId (\r
- IN UINT16 DefaultId\r
-)\r
-{\r
- UINT32 Index;\r
-\r
- if ((mMultiPlatformParam.DefaultIdNum == 0) && (DefaultId != 0)) {\r
- mMultiPlatformParam.DefaultId[0] = DefaultId;\r
- mMultiPlatformParam.DefaultIdNum++;\r
- return;\r
- }\r
- //\r
- // Only store the different value to mMultiPlatformParam.DefaultId[1] - mMultiPlatformParam.DefaultId[n]\r
- //\r
- for (Index = 0; Index < mMultiPlatformParam.DefaultIdNum; Index++) {\r
- if (mMultiPlatformParam.DefaultId[Index] == DefaultId) {\r
- return;\r
- }\r
- }\r
- mMultiPlatformParam.DefaultId[Index] = DefaultId;\r
- mMultiPlatformParam.DefaultIdNum++;\r
-}\r
-\r
-/**\r
- Read all defaultId and platformId from binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-**/\r
-VOID\r
-ReadDefaultAndPlatformIdFromBfv (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-)\r
-{\r
- UINT16 Length;\r
- UINT16 Size;\r
- UINT32 Index;\r
-\r
- Length = *(UINT16 *)Binary - sizeof (UINT16);\r
- Index = 0;\r
- Size = 0;\r
-\r
- Binary = Binary + sizeof (UINT16);\r
-\r
- for (Size = 0; Size < Length; Size += sizeof (UINT16) + mMultiPlatformParam.PlatformIdWidth, Index++) {\r
- Storage->DefaultId[Index] = *(UINT16 *)(Binary + Size);\r
- memcpy (&Storage->PlatformId[Index], (Binary + Size + sizeof (UINT16)), mMultiPlatformParam.PlatformIdWidth);\r
- }\r
- Storage->DefaultPlatformIdNum = Index - 1;\r
-}\r
-\r
-/**\r
- Store all defaultId and platformId to binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-\r
- @retval Length Return the length of the header\r
-**/\r
-UINT32\r
-WriteDefaultAndPlatformId (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-)\r
-{\r
- UINT16 Length;\r
- UINT32 Index;\r
- UINT8 *Buffer;\r
-\r
- Length = 0;\r
- Buffer = Binary;\r
-\r
- Buffer = Buffer + sizeof (CHAR16);\r
-\r
- for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r
- *(UINT16 *)Buffer = Storage->DefaultId[Index];\r
- Buffer = Buffer + sizeof (CHAR16);\r
- memcpy (Buffer, &Storage->PlatformId[Index], mMultiPlatformParam.PlatformIdWidth);\r
- Buffer = Buffer + mMultiPlatformParam.PlatformIdWidth;\r
- }\r
- Length = (UINT16) (Buffer - Binary);\r
- //\r
- // Record the offset to the first two bytes\r
- //\r
- *(UINT16 *)Binary = Length;\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Store all defaultId and platformId to binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-\r
- @retval Length Return the length of the header\r
-**/\r
-UINT32\r
-WriteNvStoreDefaultAndPlatformId (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-)\r
-{\r
- UINT16 Length;\r
- UINT32 Index;\r
- UINT8 *Buffer;\r
-\r
- Length = 0;\r
- Buffer = Binary + 8;\r
-\r
- for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r
- *(UINT64 *)Buffer = Storage->PlatformId[Index];\r
- Buffer = Buffer + sizeof(UINT64);\r
- *(UINT16 *)Buffer = Storage->DefaultId[Index];\r
- Buffer = Buffer + sizeof(UINT16);\r
- // for Resered\r
- Buffer = Buffer + 6;\r
- }\r
- Length = (UINT16) (Buffer - Binary - 8);\r
- // for Header size\r
- Length += 4;\r
- return Length;\r
-}\r
-\r
-/**\r
- Read the platformId from questions.\r
-\r
- @retval EFI_SUCCESS It was complete successfully.\r
- @return EFI_ABORTED An error occurred.\r
-**/\r
-EFI_STATUS\r
-ReadPlaformId (\r
- IN FORM_BROWSER_STATEMENT *CurQuestion\r
-)\r
-{\r
- UINT16 Index;\r
- UINT64 IdValue;\r
- LIST_ENTRY *Link;\r
- QUESTION_OPTION *Option;\r
- UINT64 Step;\r
-\r
- Index = 0;\r
- IdValue = 0;\r
- Step = 0;\r
- //\r
- // Check whether it is the question of paltform Id\r
- //\r
- if (!CompareUqiHeader (&(CurQuestion->Uqi), &(mMultiPlatformParam.Uqi))) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Copy the Question with platform to mMultiPlatformParam\r
- //\r
- memcpy (&mMultiPlatformParam.PlatformIdQuestion, CurQuestion, sizeof (FORM_BROWSER_STATEMENT));\r
- mMultiPlatformParam.Question = CurQuestion;\r
- //\r
- // Pick up the value of NUMERIC and ONE_OF from current question and fill it in mMultiPlatformParam\r
- //\r
- mMultiPlatformParam.PlatformIdWidth = CurQuestion->StorageWidth;\r
-\r
- if (CurQuestion->Operand == EFI_IFR_NUMERIC_OP) {\r
- Index = 0;\r
- if (CurQuestion->Step == 0) {\r
- Step = 1;\r
- } else {\r
- Step = CurQuestion->Step;\r
- }\r
- for (IdValue = CurQuestion->Minimum; IdValue < CurQuestion->Maximum; IdValue += Step) {\r
- mMultiPlatformParam.PlatformId[Index++] = (UINT64)IdValue;\r
- }\r
- }\r
-\r
- if (CurQuestion->Operand == EFI_IFR_ONE_OF_OP) {\r
- Index = 0;\r
-\r
- Link = GetFirstNode (&CurQuestion->OptionListHead);\r
- while (!IsNull (&CurQuestion->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
- mMultiPlatformParam.PlatformId[Index++] = Option->Value.Value.u64;\r
- Link = GetNextNode (&CurQuestion->OptionListHead, Link);\r
- }\r
- }\r
-\r
- if (Index >= MAX_PLATFORM_DEFAULT_ID_NUM) {\r
- return EFI_ABORTED;\r
- }\r
- mMultiPlatformParam.PlatformIdNum = Index;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Clear the buffer of Storage list.\r
-\r
- @param StorageListHead The pointer to the entry of the storage list\r
- @param DefaultId The default Id for multi-platform support\r
- @param PlatformId The platform Id for multi-platform support\r
-\r
- @retval NULL\r
-**/\r
-VOID\r
-ClearStorageEntryList (\r
- IN LIST_ENTRY *StorageListHead,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
- )\r
-{\r
-\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
-\r
- Storage = NULL;\r
-\r
- StorageLink = GetFirstNode (StorageListHead);\r
-\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if (Storage != NULL) {\r
- memset (Storage->Buffer, 0x0, Storage->Size);\r
- Storage->DefaultId[0] = DefaultId;\r
- Storage->PlatformId[0] = PlatformId;\r
- Storage->DefaultPlatformIdNum = 0;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
-}\r
-\r
-/**\r
- Append the platformid and default to the variables of CurDefaultId and CurPlatformId\r
-\r
- @param StorageListHead The pointer to the storage list\r
- @param CurDefaultId The default Id for multi-platform mode\r
- @param CurPlatformId The platform Id for multi-platform mode\r
- @param DefaultId The default Id for multi-platform mode\r
- @param PlatformId The platform Id for multi-platform mode\r
-\r
- @retval NULL\r
-**/\r
-VOID\r
-AppendIdToVariables (\r
- IN LIST_ENTRY *StorageListHead,\r
- IN UINT16 CurDefaultId,\r
- IN UINT64 CurPlatformId,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
-)\r
-{\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
-\r
- Storage = NULL;\r
-\r
- StorageLink = GetFirstNode (StorageListHead);\r
-\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
-\r
- if ((Storage->DefaultId[0] == CurDefaultId)\r
- && (Storage->PlatformId[0] == CurPlatformId)\r
- ) {\r
- ++Storage->DefaultPlatformIdNum;\r
- Storage->DefaultId[Storage->DefaultPlatformIdNum] = DefaultId;\r
- Storage->PlatformId[Storage->DefaultPlatformIdNum] = PlatformId;\r
- }\r
-\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
-}\r
-\r
-\r
-/**\r
- Check whether StorageListHead2 is included in StorageListHead1\r
-\r
- @param StorageListHead1 The pointer to the entry of storage list\r
- @param StorageListHead2 The pointer to the entry of storage list\r
- @param DefaultId The default Id for multi-platform mode\r
- @param PlatformId The platform Id for multi-platform mode\r
-\r
- @retval TRUE Totally included.\r
- @return FALSE Other cases.\r
-**/\r
-BOOLEAN\r
-ComparePartSameVariableList (\r
- IN LIST_ENTRY *StorageListHead1,\r
- IN LIST_ENTRY *StorageListHead2,\r
- OUT UINT16 *DefaultId,\r
- OUT UINT64 *PlatformId\r
-)\r
-{\r
- LIST_ENTRY *StorageLink;\r
- LIST_ENTRY *TempStorageHead;\r
- LIST_ENTRY *TempStorageLink;\r
- LIST_ENTRY *TempStorageHead2;\r
- LIST_ENTRY *TempStorageLink2;\r
- FORMSET_STORAGE *Storage;\r
- FORMSET_STORAGE *TempStorage;\r
- FORMSET_STORAGE *TempStorage2;\r
- UINT16 CurDefaultId;\r
- UINT64 CurPlatformId;\r
- UINT32 VariableNum;\r
- UINT32 Index;\r
-\r
- StorageLink = NULL;\r
- TempStorageHead = NULL;\r
- TempStorageLink = NULL;\r
- TempStorageHead2 = NULL;\r
- TempStorageLink2 = NULL;\r
- Storage = NULL;\r
- TempStorage = NULL;\r
- TempStorage2 = NULL;\r
- CurDefaultId = 0;\r
- CurPlatformId = 0;\r
- VariableNum = 0;\r
- Index = 0;\r
- TempStorageHead = StorageListHead1;\r
-\r
-\r
- //\r
- // Get the number of variables in StorageListHead2;\r
- //\r
- StorageLink = GetFirstNode (StorageListHead2);\r
-\r
- while (!IsNull (StorageListHead2, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // For multi-platform support, only need to calcuate the type of EFI_IFR_VARSTORE_EFI_OP.\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot &&\r
- (Storage->Type == EFI_IFR_VARSTORE_EFI_OP) && (Storage->Name != NULL) && (Storage->NewEfiVarstore) &&\r
- ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE)) {\r
- VariableNum++;\r
- }\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- }\r
- //\r
- // Parse every variables in StorageListHead1 and compare with ones in StorageListHead2\r
- // Only all variables in StorageListHead2 are included in StorageListHead1, return TRUE.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead1);\r
-\r
- while (!IsNull (StorageListHead1, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Get specified DefaultId and PlatformId firstly\r
- //\r
- CurDefaultId = Storage->DefaultId[0];\r
- CurPlatformId = Storage->PlatformId[0];\r
- Index = 0;\r
- //\r
- // Compare all variables under same defaultId and platformId\r
- //\r
- TempStorageLink = GetFirstNode (TempStorageHead);\r
- while (!IsNull (TempStorageHead, TempStorageLink)) {\r
- TempStorage = FORMSET_STORAGE_FROM_LINK (TempStorageLink);\r
- if ((TempStorage->DefaultId[0] == CurDefaultId)\r
- && (TempStorage->PlatformId[0] == CurPlatformId)\r
- && (TempStorage->Name != NULL)\r
- && (TempStorage->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- && (TempStorage->NewEfiVarstore)\r
- && ((TempStorage->Attributes & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE)\r
- ) {\r
- //\r
- //Search the matched variable by Guid and name in StorageListHead2\r
- //\r
- TempStorageHead2 = StorageListHead2;\r
- TempStorageLink2 = GetFirstNode (TempStorageHead2);\r
-\r
- while (!IsNull (TempStorageHead2, TempStorageLink2)) {\r
- TempStorage2 = FORMSET_STORAGE_FROM_LINK (TempStorageLink2);\r
- if ((TempStorage2->Name != NULL)\r
- && (TempStorage2->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- && (TempStorage2->NewEfiVarstore)\r
- && ((TempStorage2->Attributes & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE)\r
- && !FceStrCmp (TempStorage->Name, TempStorage2->Name)\r
- && !CompareGuid(&TempStorage->Guid, &TempStorage2->Guid)\r
- ) {\r
- if (CompareMem (TempStorage->Buffer, TempStorage2->Buffer, TempStorage->Size) == 0) {\r
- Index++;\r
- }\r
- }\r
- TempStorageLink2 = GetNextNode (TempStorageHead2, TempStorageLink2);\r
- }\r
- }\r
- TempStorageLink = GetNextNode (TempStorageHead, TempStorageLink);\r
- }\r
- //\r
- // Check the matched variable number\r
- //\r
- if (Index == VariableNum) {\r
- *DefaultId = CurDefaultId;\r
- *PlatformId = CurPlatformId;\r
- return TRUE;\r
- }\r
- StorageLink = GetNextNode (StorageListHead1, StorageLink);\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Check whether the defaultId and platformId mathched the variable or not\r
-\r
- @param Storage The pointer to the storage\r
- @param DefaultId The default Id for multi-platform mode\r
- @param PlatformId The platform Id for multi-platform mode\r
-\r
- @retval TRUE Not Matched.\r
- @return FALSE Matched any one\r
-**/\r
-BOOLEAN\r
-NotEqualAnyIdOfStorage (\r
-IN FORMSET_STORAGE *Storage,\r
-IN UINT16 DefaultId,\r
-IN UINT64 PlatformId\r
-)\r
-{\r
- UINT32 Index;\r
-\r
- for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r
- if ((Storage->DefaultId[Index] == DefaultId)\r
- &&(Storage->PlatformId[Index] == PlatformId)\r
- ) {\r
- return FALSE;\r
- }\r
- }\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Copy Stroage from StorageListHead2 to StorageListHead1\r
-\r
- @param NewStorageListHead The pointer to the entry of storage list\r
- @param OldStorageListHead The pointer to the entry of storage list\r
- @param DefaultId The default Id for multi-platform mode\r
- @param PlatformId The platform Id for multi-platform mode\r
- @param AssignIdOrNot If True, assign the platform Id and default Id to storage;\r
- Or else, only copy the variables under the specified platform\r
- Id and default to the other list.\r
- @param Mode The operation of mode\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-BuildVariableList (\r
- IN LIST_ENTRY *NewStorageListHead,\r
- IN LIST_ENTRY *OldStorageListHead,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId,\r
- IN BOOLEAN AssignIdOrNot,\r
- IN OPERATION_TYPE Mode\r
-)\r
-{\r
- LIST_ENTRY *StorageLink;\r
- LIST_ENTRY *NameValueLink;\r
- FORMSET_STORAGE *Storage;\r
- FORMSET_STORAGE *StorageCopy;\r
- IN LIST_ENTRY *StorageListHead1;\r
- IN LIST_ENTRY *StorageListHead2;\r
- NAME_VALUE_NODE *NameValueNode;\r
- NAME_VALUE_NODE *CopyNameValueNode;\r
-\r
- Storage = NULL;\r
- NameValueNode = NULL;\r
- StorageListHead1 = NewStorageListHead;\r
- StorageListHead2 = OldStorageListHead;\r
-\r
- StorageLink = GetFirstNode (StorageListHead2);\r
-\r
- while (!IsNull (StorageListHead2, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
-\r
- if ((Storage->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- ||(Storage->Type == EFI_IFR_VARSTORE_OP)\r
- ) {\r
- //\r
- // Only support EfiVarStore in Multi-Platform mode, and the attribute must be EFI_VARIABLE_NON_VOLATILE\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- if (Storage->Type == EFI_IFR_VARSTORE_OP) {\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- continue;\r
- }\r
- if ((Storage->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- && Storage->NewEfiVarstore\r
- && ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- continue;\r
- }\r
- if (AssignIdOrNot) {\r
- Storage->DefaultId[0] = DefaultId;\r
- Storage->PlatformId[0] = PlatformId;\r
- } else {\r
- //\r
- //only copy the variables under the specified platform Id and default to the other list.\r
- //\r
- if ((Mode == VERIFY) && (NotEqualAnyIdOfStorage (Storage, DefaultId, PlatformId))) {\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- continue;\r
- } else if ((Mode != VERIFY) && (Storage->DefaultId[0] != DefaultId || Storage->PlatformId[0] != PlatformId) ) {\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- continue;\r
- }\r
- }\r
- }\r
- //\r
- // Copy Storage Node\r
- //\r
- if (Storage->Name == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- StorageCopy = NULL;\r
- StorageCopy = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));\r
- if (StorageCopy == NULL) {\r
- printf ("Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- memcpy (StorageCopy, Storage, sizeof (FORMSET_STORAGE));\r
-\r
- if (Mode == VERIFY) {\r
- StorageCopy->DefaultId[0] = DefaultId;\r
- StorageCopy->PlatformId[0] = PlatformId;\r
- }\r
- //\r
- //Set the flags for sorting out the variables\r
- //\r
- StorageCopy->Skip = FALSE;\r
-\r
- StorageCopy->Name = NULL;\r
- StorageCopy->Name = calloc (FceStrLen (Storage->Name) + 1, sizeof (CHAR16));\r
- if (StorageCopy->Name == NULL) {\r
- printf ("Memory allocation failed.\n");\r
- free (StorageCopy);\r
- return EFI_ABORTED;\r
- }\r
- StrCpy (StorageCopy->Name, Storage->Name);\r
-\r
- StorageCopy->Buffer = NULL;\r
- StorageCopy->Buffer = calloc (Storage->Size, sizeof (CHAR8));\r
- if (StorageCopy->Buffer == NULL) {\r
- free (StorageCopy->Name);\r
- free (StorageCopy);\r
- printf ("Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- CopyMem (StorageCopy->Buffer, Storage->Buffer, Storage->Size);\r
- //\r
- // Copy NameValue list of storage node\r
- //\r
- InitializeListHead (&StorageCopy->NameValueListHead);\r
-\r
- NameValueLink = GetFirstNode (&Storage->NameValueListHead);\r
-\r
- while (!IsNull (&Storage->NameValueListHead, NameValueLink)) {\r
-\r
- NameValueNode = NAME_VALUE_NODE_FROM_LINK (NameValueLink);\r
- CopyNameValueNode = NULL;\r
- CopyNameValueNode = calloc (sizeof (NAME_VALUE_NODE), sizeof (CHAR8));\r
- if (CopyNameValueNode == NULL) {\r
- free (StorageCopy->Name);\r
- free (StorageCopy->Buffer);\r
- free (StorageCopy);\r
- printf ("Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- memcpy (CopyNameValueNode, NameValueNode, sizeof (NAME_VALUE_NODE));\r
-\r
- CopyNameValueNode->Name = NULL;\r
- CopyNameValueNode->Value = NULL;\r
- CopyNameValueNode->EditValue = NULL;\r
-\r
- CopyNameValueNode->Name = calloc (FceStrLen (NameValueNode->Name) + 1, sizeof (CHAR16));\r
- CopyNameValueNode->Value = calloc (FceStrLen (NameValueNode->Value) + 1, sizeof (CHAR16));\r
- CopyNameValueNode->EditValue = calloc (FceStrLen (NameValueNode->EditValue) + 1, sizeof (CHAR16));\r
- if ((CopyNameValueNode->Name == NULL)\r
- || (CopyNameValueNode->Value == NULL)\r
- || (CopyNameValueNode->EditValue == NULL)\r
- ) {\r
- free (StorageCopy->Name);\r
- free (StorageCopy->Buffer);\r
- free (StorageCopy);\r
- if (CopyNameValueNode->Name != NULL) {\r
- free (CopyNameValueNode->Name );\r
- }\r
- if (CopyNameValueNode->Value != NULL) {\r
- free (CopyNameValueNode->Value);\r
- }\r
- if (CopyNameValueNode->EditValue != NULL) {\r
- free (CopyNameValueNode->EditValue);\r
- }\r
- free (CopyNameValueNode);\r
- printf ("Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- StrCpy (CopyNameValueNode->Name, NameValueNode->Name);\r
- StrCpy (CopyNameValueNode->Value, NameValueNode->Value);\r
- StrCpy (CopyNameValueNode->EditValue, NameValueNode->EditValue);\r
- //\r
- // Insert it to StorageCopy->NameValueListHead\r
- //\r
- InsertTailList(&StorageCopy->NameValueListHead,&CopyNameValueNode->Link);\r
- NameValueLink = GetNextNode (&Storage->NameValueListHead, NameValueLink);\r
- }\r
-\r
- //\r
- // Insert it to StorageListHead1\r
- //\r
- InsertTailList(StorageListHead1,&StorageCopy->Link);\r
- }\r
- StorageLink = GetNextNode (StorageListHead2, StorageLink);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check whether the current defaultId and platfrom is equal to the first one of one\r
- group of defaultId and platformId which have the same variable data.\r
-\r
- @param DefaultId The default Id\r
- @param PlatformId The platform Id\r
-\r
- @retval TRUE If not equal to the first defaultId and platformId, return TRUE\r
- @return EFI_ABORTED Others\r
-**/\r
-BOOLEAN\r
-NoTheKeyIdOfGroup (\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
- )\r
-{\r
- UINT32 Index;\r
-\r
- for (Index = 0; Index < mMultiPlatformParam.KeyIdNum; Index++) {\r
- if (\r
- (DefaultId == mMultiPlatformParam.KeyDefaultId[Index])\r
- && (PlatformId == mMultiPlatformParam.KeyPlatformId[Index])\r
- ) {\r
- return FALSE;\r
- }\r
- }\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Evaluate the value in all formset according to the defaultId and platformId.\r
-\r
- If not the multi-platform mode, the defaultId is 0. In this case, the\r
- platform Id will be the default value of that question.\r
-\r
- @param UpdateMode It will be TRUE in update Mode\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-EvaluateTheValueInFormset (\r
- IN BOOLEAN UpdateMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 DefaultId;\r
- UINT64 PlatformId;\r
- UINT16 CurDefaultId;\r
- UINT64 CurPlatformId;\r
- UINT16 DefaultIndex;\r
- UINT16 PlatformIndex;\r
- UINT32 Index;\r
- UQI_PARAM_LIST *CurUqiList;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- ScanUqiFullList (mUqiList);\r
-\r
- //\r
- // Multi-platform mode support\r
- //\r
- for (DefaultIndex = 0; DefaultIndex < mMultiPlatformParam.DefaultIdNum; DefaultIndex++) {\r
- for (PlatformIndex = 0; PlatformIndex < mMultiPlatformParam.PlatformIdNum; PlatformIndex++) {\r
- DefaultId = mMultiPlatformParam.DefaultId[DefaultIndex];\r
- PlatformId = mMultiPlatformParam.PlatformId[PlatformIndex];\r
- //\r
- //Only parse one time, if a group of defaultId and platformId which have the same variable\r
- // Take the first one as a key Id of a group\r
- //\r
- if (UpdateMode && NoTheKeyIdOfGroup (DefaultId, PlatformId)) {\r
- continue;\r
- }\r
- //\r
- // Initialize the Storage of mVarListEntry\r
- //\r
- ClearStorageEntryList (&mVarListEntry, DefaultId, PlatformId);\r
-\r
- Status = ExtractDefault (\r
- NULL,\r
- NULL,\r
- DefaultId,\r
- PlatformId,\r
- SystemLevel\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Clear the platformId as 0 after calculation.\r
- //\r
- Status = AssignThePlatformId (0);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Failed to clear the platformid.\n");\r
- return Status;\r
- }\r
- //\r
- // Update the value from script file\r
- //\r
- if (UpdateMode) {\r
- SetUqiParametersMultiMode (mUqiList,DefaultId, PlatformId);\r
- }\r
- //\r
- // If not existed the same variables in mAllVarListEntry, insert the new ones.\r
- // Or else, only add the defaultId and platformId to the former one.\r
- //\r
- if (ComparePartSameVariableList (&mAllVarListEntry, &mVarListEntry, &CurDefaultId, &CurPlatformId)) {\r
- AppendIdToVariables (&mAllVarListEntry, CurDefaultId, CurPlatformId, DefaultId, PlatformId);\r
- } else {\r
- //\r
- // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well\r
- //\r
- Status = BuildVariableList (&mAllVarListEntry, &mVarListEntry, DefaultId, PlatformId, TRUE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // In update mode, add the other defaultId and platform of a group to the variale list\r
- //\r
- if (UpdateMode) {\r
- CurUqiList = mUqiList;\r
-\r
- while (CurUqiList != NULL) {\r
- if ((DefaultId == CurUqiList->Header.DefaultId[0])\r
- && (PlatformId == CurUqiList->Header.PlatformId[0])\r
- ) {\r
- break;\r
- }\r
- CurUqiList = CurUqiList->Next;\r
- }\r
-\r
- if (CurUqiList == NULL) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- for (Index = 1; Index < CurUqiList->Header.IdNum; Index++) {\r
- CurDefaultId = CurUqiList->Header.DefaultId[Index];\r
- CurPlatformId = CurUqiList->Header.PlatformId[Index];\r
- AppendIdToVariables (&mAllVarListEntry, DefaultId, PlatformId, CurDefaultId, CurPlatformId);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- } else {\r
- //\r
- // General mode\r
- //\r
- Status = ExtractDefault (\r
- NULL,\r
- NULL,\r
- 0,\r
- 0,\r
- SystemLevel\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // If existed the variable in NvStorage, copy them to mVarListEntry.\r
- // Synchronize the default value from the EFI variable zone to variable list\r
- //\r
- Status = EfiVarAndListExchange (TRUE, &mVarListEntry);\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- Status = EFI_ABORTED;\r
- return Status;\r
- }\r
- //\r
- // Update the value from script file\r
- //\r
- if (UpdateMode) {\r
- Status = SetUqiParameters (mUqiList,0, 0);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Copy Stroage from mVarListEntry to mAllVarListEntry\r
- //\r
- Status = BuildVariableList (&mAllVarListEntry, &mVarListEntry, 0, 0, TRUE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check and compare the value between the script file and variable from BFV.\r
-\r
- It's used in the update operation of multi-plaform mode.\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-CheckValueUpdateList (\r
- VOID\r
- )\r
-{\r
- UINT16 DefaultId;\r
- UINT64 PlatformId;\r
- UINT16 DefaultIndex;\r
- UINT16 PlatformIndex;\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *Storage;\r
- LIST_ENTRY *StorageLink;\r
- UINT16 PreDefaultId;\r
- UINT64 PrePlatformId;\r
-\r
- Storage = NULL;\r
- PreDefaultId = 0xFFFF;\r
- PrePlatformId = 0xFFFFFFFFFFFFFFFF;\r
-\r
- ScanUqiFullList (mUqiList);\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- StorageLink = GetFirstNode (&mBfvVarListEntry);\r
- while (!IsNull (&mBfvVarListEntry, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if (PreDefaultId == Storage->DefaultId[0] && PrePlatformId == Storage->PlatformId[0]) {\r
- StorageLink = GetNextNode (&mBfvVarListEntry, StorageLink);\r
- continue;\r
- } else {\r
- PreDefaultId = Storage->DefaultId[0];\r
- PrePlatformId = Storage->PlatformId[0];\r
- }\r
- DefaultId = PreDefaultId;\r
- PlatformId = PrePlatformId;\r
- //\r
- //Only parse one time, if a group of defaultId and platformId which have the same variable\r
- // Take the first one as a key Id of a group\r
- //\r
- if (NoTheKeyIdOfGroup (DefaultId, PlatformId)) {\r
- continue;\r
- }\r
- //\r
- // Copy Stroage from mBfvVarListEntry to mVarListEntry. The mVarListEntry was attached to\r
- // the FormSet->StorageListHead.\r
- //\r
- DestroyAllStorage (&mVarListEntry);\r
- Status = BuildVariableList (&mVarListEntry, &mBfvVarListEntry, DefaultId, PlatformId, FALSE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- SetUqiParametersMultiMode (mUqiList,DefaultId, PlatformId);\r
- //\r
- // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well\r
- //\r
- Status = BuildVariableList (&mAllVarListEntry, &mVarListEntry, DefaultId, PlatformId, TRUE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- StorageLink = GetNextNode (&mBfvVarListEntry, StorageLink);\r
- }\r
- } else {\r
- for (DefaultIndex = 0; DefaultIndex < mMultiPlatformParam.DefaultIdNum; DefaultIndex++) {\r
- for (PlatformIndex = 0; PlatformIndex < mMultiPlatformParam.PlatformIdNum; PlatformIndex++) {\r
- DefaultId = mMultiPlatformParam.DefaultId[DefaultIndex];\r
- PlatformId = mMultiPlatformParam.PlatformId[PlatformIndex];\r
- //\r
- //Only parse one time, if a group of defaultId and platformId which have the same variable\r
- // Take the first one as a key Id of a group\r
- //\r
- if (NoTheKeyIdOfGroup (DefaultId, PlatformId)) {\r
- continue;\r
- }\r
- //\r
- // Copy Stroage from mBfvVarListEntry to mVarListEntry. The mVarListEntry was attached to\r
- // the FormSet->StorageListHead.\r
- //\r
- DestroyAllStorage (&mVarListEntry);\r
- Status = BuildVariableList (&mVarListEntry, &mBfvVarListEntry, DefaultId, PlatformId, FALSE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- SetUqiParametersMultiMode (mUqiList,DefaultId, PlatformId);\r
- //\r
- // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well\r
- //\r
- Status = BuildVariableList (&mAllVarListEntry, &mVarListEntry, DefaultId, PlatformId, TRUE, UPDATE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-/**\r
- Read defaultId and platformId from the whole FD, and store these two values to mMultiPlatformParam.\r
-\r
- If not multi-platform mode, only return EFI_ABORTED.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param Length the length of FFS\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-ReadAllIfrToFromset (\r
- IN VOID *Fv,\r
- IN UINTN Length\r
- )\r
-{\r
- UINT8 NumberofMachingVfrBin;\r
- UINTN *VfrBinBaseAddress;\r
- UINTN *UniBinBaseAddress;\r
- EFI_STATUS Status;\r
- UINT8 Index;\r
- EFI_SECTION_STRUCT *EfiBufferHeader;\r
- VOID *EfiAddr;\r
-\r
- NumberofMachingVfrBin = 0;\r
- VfrBinBaseAddress = NULL;\r
- UniBinBaseAddress = NULL;\r
- Status = EFI_SUCCESS;\r
- EfiBufferHeader = NULL;\r
- EfiAddr = NULL;\r
-\r
- //\r
- // Locate the efi base address\r
- //\r
- EfiBufferHeader = malloc (sizeof (EFI_SECTION_STRUCT));\r
- if (EfiBufferHeader == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- memset (\r
- EfiBufferHeader,\r
- 0,\r
- sizeof (EFI_SECTION_STRUCT)\r
- );\r
-\r
- Status = ParseSection (\r
- TRUE,\r
- (UINT8 *)Fv,\r
- Length,\r
- &EfiBufferHeader\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
-\r
- EfiAddr = (VOID *)EfiBufferHeader->BufferBase;\r
- //\r
- //Search the Offset at the end of FFS, whatever it is compressed or not\r
- //\r
- Status = SearchVfrBinInFFS (Fv, EfiAddr, Length, &VfrBinBaseAddress, &NumberofMachingVfrBin);\r
- if (Status != EFI_SUCCESS) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- Status = SearchUniBinInFFS (\r
- Fv,\r
- EfiAddr,\r
- Length,\r
- &UniBinBaseAddress\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //\r
- // Read all Ifr information into Formset and Form structure\r
- //\r
- for (Index = 0; Index < NumberofMachingVfrBin; Index++) {\r
- if ((EfiBufferHeader->BufferBase + EfiBufferHeader->Length) < *(VfrBinBaseAddress + Index)\r
- || (EfiBufferHeader->BufferBase + EfiBufferHeader->Length) < *UniBinBaseAddress\r
- ) {\r
- printf ("Failed to locate Ifr data from efi by the offset.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- Status = ParseFormSetInVfrBin (\r
- (UINTN **)VfrBinBaseAddress,\r
- (UINTN *)*UniBinBaseAddress,\r
- Index\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- }\r
-\r
-Done:\r
- //\r
- // Free the memory which stores the offset\r
- //\r
- if (VfrBinBaseAddress != NULL) {\r
- free (VfrBinBaseAddress);\r
- }\r
- if (UniBinBaseAddress != NULL) {\r
- free (UniBinBaseAddress);\r
- }\r
- //\r
- // Free the memory for uncompressed space in section\r
- //\r
- for (Index = 0; Index < EfiBufferHeader->UnCompressIndex; Index++) {\r
- if ((VOID *)EfiBufferHeader->UncompressedBuffer[Index] != NULL) {\r
- free ((VOID *)EfiBufferHeader->UncompressedBuffer[Index]);\r
- }\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Get next questions of four kinds in FormSet list.\r
-\r
- If not one kinds of ONE_OF CHECK_BOX ORDER_LIST and NUMERIC, continue to parse next question.\r
- If parse to the end of questions, return NULL.\r
-\r
- @param FormSetEntryListHead the pointer to the LIST_ENTRY\r
- @param OrderOfQuestion the order of question\r
-\r
- @retval If succeed, return the pointer to the question\r
- @return NULL\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-GetNextQuestion (\r
- IN LIST_ENTRY *FormSetEntryListHead,\r
- IN OUT UINT32 *OrderOfQuestion\r
- )\r
-{\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormSetLink;\r
- FORM_BROWSER_FORM *Form;\r
- LIST_ENTRY *FormLink;\r
- FORM_BROWSER_STATEMENT *Question;\r
- LIST_ENTRY *QuestionLink;\r
- UINT32 Index;\r
-\r
- FormSet = NULL;\r
- FormSetLink = NULL;\r
- Form = NULL;\r
- FormLink = NULL;\r
- Question = NULL;\r
- QuestionLink = NULL;\r
- Index = 0;\r
-\r
- FormSetLink = GetFirstNode (FormSetEntryListHead);\r
- while (!IsNull (FormSetEntryListHead, FormSetLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r
- //\r
- // Parse all forms in formset\r
- //\r
- FormLink = GetFirstNode (&FormSet->FormListHead);\r
-\r
- while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- if (*OrderOfQuestion == Index++) {\r
- (*OrderOfQuestion)++;\r
- return Question;\r
- }\r
- }\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- }\r
-\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- }\r
- FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- Read defaultId and platformId from the whole FD, and store these two values to mMultiPlatformParam.\r
-\r
- If not multi-platform mode, only return EFI_ABORTED.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param Length the length of FFS\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-ReadDefaultAndPlatformId (\r
- IN LIST_ENTRY *FormSetEntryListHead\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormLink;\r
- FORMSET_DEFAULTSTORE *DefaultStore;\r
- LIST_ENTRY *DefaultStoreLink;\r
- FORM_BROWSER_STATEMENT *CurQuestion;\r
- UINT32 MatchedNum;\r
- UINT32 QuestionOrder;\r
-\r
- Status = EFI_SUCCESS;\r
- CurQuestion = NULL;\r
- MatchedNum = 0;\r
- QuestionOrder = 0;\r
- //\r
- //Check whether it is the Multi-Platform solution or not\r
- //\r
- if (!mMultiPlatformParam.MultiPlatformOrNot) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
- //\r
- // Read defaultId from FormSet List\r
- //\r
- FormLink = GetFirstNode (FormSetEntryListHead);\r
- while (!IsNull (FormSetEntryListHead, FormLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormLink);\r
- //\r
- // Parse Default Store in formset\r
- //\r
- DefaultStoreLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
-\r
- while (!IsNull (&FormSet->DefaultStoreListHead, DefaultStoreLink)) {\r
- DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (DefaultStoreLink);\r
- StoreAllDefaultId (DefaultStore->DefaultId);\r
- DefaultStoreLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultStoreLink);\r
- }\r
- FormLink = GetNextNode (FormSetEntryListHead, FormLink);\r
- }\r
-\r
- //\r
- //Read the platformId from FormSetList\r
- //\r
- while ((CurQuestion = GetNextQuestion (FormSetEntryListHead, &QuestionOrder)) != NULL) {\r
- Status = ReadPlaformId (CurQuestion);\r
- if (!EFI_ERROR (Status)) {\r
- MatchedNum++;\r
- }\r
- }\r
-\r
- if (MatchedNum == 0) {\r
- printf ("There are no questions included in the platformid in the FD.");\r
- Status = EFI_ABORTED;\r
- } else if (MatchedNum > 1) {\r
- printf ("There are %d questions included in the platformid in the FD.", MatchedNum);\r
- Status = EFI_ABORTED;\r
- } else {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
-Done:\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Read the first two bytes to check whether it is Ascii or UCS2.\r
-\r
- @param ScriptFile Pointer to the script file.\r
-\r
- @reture TRUE If ascii, return TRUE\r
- @reture FALSE Others, return FALSE.\r
-\r
-**/\r
-FILE_TYPE\r
-IsAsciiOrUcs2 (\r
- IN FILE *ScriptFile\r
- )\r
-{\r
- CHAR16 FirstTwoBytes;\r
-\r
- fread(&FirstTwoBytes, 1, 2, ScriptFile);\r
-\r
- if (FirstTwoBytes == BigUnicodeFileTag) {\r
- return BIG_UCS2;\r
- } else if (FirstTwoBytes == LittleUnicodeFileTag) {\r
- return LITTLE_UCS2;\r
- } else {\r
- return ASCII;\r
- }\r
-}\r
-\r
-/**\r
- Read Unicode characters and transfer it to ASCII.\r
-\r
- @param ScriptFile The pointer to the script file.\r
- @param Type The type of BigUCS2 or LittleUCS2\r
-\r
- @return The ASCII characters\r
-\r
-**/\r
-CHAR8 *\r
-ReadUcs2ToStr (\r
- IN OUT FILE *ScriptFile,\r
- IN FILE_TYPE Type\r
-)\r
-{\r
- CHAR16 TempChar16;\r
- CHAR16 TempChar8;\r
- CHAR8 *StrChar8;\r
- UINTN Index;\r
- BOOLEAN FirstParse;\r
-\r
- TempChar16 = L'\0';\r
- TempChar8 = '\0';\r
- StrChar8 = NULL;\r
- Index = 0;\r
- FirstParse = TRUE;\r
-\r
- if (ScriptFile == NULL) {\r
- return NULL;\r
- }\r
- StrChar8 = calloc (MAX_STR_LEN_FOR_PICK_UQI, sizeof (CHAR8));\r
- assert (StrChar8);\r
-\r
- for (Index = 0; Index < MAX_STR_LEN_FOR_PICK_UQI; Index++) {\r
- //\r
- // The first parse should skip the 0x0020 (BigUCS2) or 0x2000 (LittleUCS2)\r
- //\r
- if (FirstParse) {\r
- do {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- } while ((TempChar16 == 0x0020) || (TempChar16 == 0x2000));\r
- FirstParse = FALSE;\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- }\r
- //\r
- // Read until break the "Space"\r
- //\r
- if ((TempChar16 == 0x0020) || (TempChar16 == 0x2000)) {\r
- break;\r
- }\r
- if (Type == BIG_UCS2) {\r
- TempChar8 = (CHAR8)TempChar16;\r
- } else {\r
- TempChar8 = (CHAR8)(TempChar16 >> 8);\r
- }\r
- memcpy (StrChar8 + Index, &TempChar8, 0x1);\r
- }\r
- if (Index == MAX_STR_LEN_FOR_PICK_UQI) {\r
- free (StrChar8);\r
- return NULL;\r
- }\r
- *(StrChar8 + Index) = '\0';\r
-\r
- return StrChar8;\r
-}\r
-\r
-/**\r
- Read Unicode characters and transfer it to ASCII.\r
-\r
- @param AsciiStr The pointer to the Ascii string. It may inlcudes blank space.\r
- @param IdArray The pointer to the array of Id.\r
-\r
- @return The number of default or platform Id\r
-\r
-**/\r
-static\r
-UINT16\r
-GetNumFromAsciiString (\r
- IN CHAR8 *AsciiStr,\r
- IN OUT UINT64 *IdArray\r
-)\r
-{\r
- UINT16 Index1;\r
- UINT16 Index2;\r
- UINT16 NumofId;\r
- CHAR8 CharArray[16];\r
- BOOLEAN ExistedValue;\r
-\r
- Index1 = 0;\r
- Index2 = 0;\r
- NumofId = 0;\r
- ExistedValue = FALSE;\r
-\r
- while (*(AsciiStr + Index1) != '\n') {\r
-\r
- Index2 = 0;\r
- ExistedValue = FALSE;\r
- memset (CharArray, 0, 16);\r
- for (; *(AsciiStr + Index1) == ' '; Index1++);\r
- for (; (*(AsciiStr + Index1) != ' ') && (*(AsciiStr + Index1) != '\n'); Index1++) {\r
- assert (Index2 <= 15);\r
- *(CharArray + Index2++) = *(AsciiStr + Index1);\r
- ExistedValue = TRUE;\r
- }\r
- if (ExistedValue && (*(AsciiStr + Index1 - 1) != '\n')) {\r
- sscanf(CharArray, "%lld", (long long *)&IdArray[NumofId++]);\r
- }\r
- }\r
- return NumofId;\r
-}\r
-\r
-/**\r
- Parse the script file to build the linked list of question structures.\r
-\r
- Pick up the UQI information and save it to the UqiList. The current scripts\r
- could be Ascii or UCS2 (Little or Big Mode).\r
-\r
- @param ScriptFile The pointer to the script file.\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_INVALID_PARAMETER ScriptFile is NULL\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-PickUpUqiFromScript (\r
- IN FILE *ScriptFile\r
- )\r
-{\r
- CHAR8 TempChar;\r
- BOOLEAN InQuote;\r
- CHAR16 TempChar16;\r
- UINT32 UqiSize;\r
- CHAR16 *UqiBuffer;\r
- CHAR8 Type[32];\r
- UINT16 Index;\r
- UQI_PARAM_LIST *UqiNode;\r
- UINTN MaxContainers;\r
- UINT32 ScriptsLine;\r
- FILE_TYPE AsciiOrUcs2;\r
- CHAR8 *Char8Str;\r
- CHAR8 DefaultIdStr[30];\r
- CHAR8 PlatformIdStr[30];\r
- CHAR8 PlatformUqi[30];\r
- UINT16 Index1;\r
- UINT16 Index2;\r
- UINT16 Index3;\r
- UINT16 Index4;\r
- UINT16 Index5;\r
- BOOLEAN ReadDefaultId;\r
- BOOLEAN ReadPlatformId;\r
- BOOLEAN ReadPlatformIdUqi;\r
- UINT64 DefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT64 PlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT16 DefaultIdNum;\r
- UINT16 PlatformIdNum;\r
- UINT8 Array[MAX_PLATFORM_DEFAULT_ID_NUM * MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT16 IdStart;\r
- UINT16 IdEnd;\r
-\r
- Char8Str = NULL;\r
- ScriptsLine = 0;\r
- AsciiOrUcs2 = ASCII;\r
- Index1 = 0;\r
- Index2 = 0;\r
- Index3 = 0;\r
- Index4 = 0;\r
- Index5 = 0;\r
- ReadDefaultId = FALSE;\r
- ReadPlatformId = FALSE;\r
- ReadPlatformIdUqi = FALSE;\r
- DefaultIdNum = 1;\r
- PlatformIdNum = 1;\r
- InQuote = FALSE;\r
-\r
- memset (DefaultId, 0, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- memset (PlatformId, 0, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- memcpy (DefaultIdStr, "/ FCEKEY DEFAULT_ID:", strlen ("/ FCEKEY DEFAULT_ID:") + 1);\r
- memcpy (PlatformIdStr,"/FCEKEY PLATFORM_ID:", strlen ("/FCEKEY PLATFORM_ID:") + 1);\r
- memcpy (PlatformUqi, "/FCEKEY PLATFORM_UQI:", strlen ("/FCEKEY PLATFORM_UQI:") + 1);\r
-\r
- if (ScriptFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Check the file type\r
- //\r
- AsciiOrUcs2 = IsAsciiOrUcs2 (ScriptFile);\r
- if (AsciiOrUcs2 == ASCII) {\r
- fseek (ScriptFile, 0, SEEK_SET);\r
- }\r
-\r
- while(!feof(ScriptFile)) {\r
- //\r
- // Reset local data\r
- //\r
- TempChar = '\0';\r
- TempChar16 = L'\0';\r
- UqiSize = 0;\r
- UqiBuffer = NULL;\r
- MaxContainers = 0;\r
- UqiNode = NULL;\r
- memset(Type, 0, 32);\r
- //\r
- // Read first character of the line to find the line type\r
- //\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- //\r
- // Take "\n\r" one line\r
- //\r
- if (TempChar != 0x0d) {\r
- ScriptsLine++;\r
- }\r
- switch (TempChar) {\r
-\r
- case 'Q':\r
- //\r
- // Process question line\r
- //\r
- // Read size of UQI string\r
- //\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %x", (INT32 *)&UqiSize);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %x", (INT32 *)&UqiSize);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- if (UqiSize > MAX_INPUT_ALLOCATE_SIZE) {\r
- return EFI_ABORTED;\r
- }\r
- if (UqiSize == 0) {\r
- do {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- } while((TempChar != '\n') && !feof(ScriptFile));\r
- break;\r
- }\r
- //\r
- // Malloc buffer for string size + null termination\r
- //\r
- UqiBuffer = (CHAR16 *)calloc(UqiSize + 1, sizeof(CHAR16));\r
-\r
- if (UqiBuffer == NULL) {\r
- printf("Error. Unable to allocate 0x%04lx bytes for UQI string -- FAILURE\n", (unsigned long)((UqiSize + 1) * sizeof(CHAR16)));\r
- break;\r
- }\r
- //\r
- // Read UQI string\r
- //\r
- for (Index = 0; Index < UqiSize; Index++) {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %hx", (short *)&(UqiBuffer[Index]));\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- free (UqiBuffer );\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %hx", (short *)&(UqiBuffer[Index]));\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- }\r
- //\r
- // Set null termination\r
- //\r
- UqiBuffer[Index] = 0;\r
- //\r
- // Read question type\r
- //\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, "%31s", Type);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %31s", Type);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- if (stricmp(Type, "ONE_OF") == 0) {\r
- UqiNode = CreateInsertUqiNode ();\r
- if (UqiNode == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.Type = ONE_OF;\r
- UqiNode->Header.HexNum = UqiSize;\r
- UqiNode->Header.Data = UqiBuffer;\r
- UqiNode->Header.Value = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.DiffValue = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.IdNum = PlatformIdNum;\r
- UqiNode->Header.DefaultId = (UINT16 *)calloc (PlatformIdNum, sizeof (UINT16));\r
- if (UqiNode->Header.DefaultId == NULL) {\r
- printf("Fail to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.PlatformId = (UINT64 *)calloc (PlatformIdNum, sizeof (UINT64));\r
- if (UqiNode->Header.PlatformId == NULL) {\r
- printf("Fail to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- for (Index5 = 0; Index5 < PlatformIdNum; Index5++) {\r
- UqiNode->Header.DefaultId[Index5] = (UINT16)DefaultId[Index5];\r
- }\r
- memcpy (UqiNode->Header.PlatformId, PlatformId, PlatformIdNum * sizeof (UINT64));\r
-\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %llx", (long long *)UqiNode->Header.Value);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %llx", (long long *)UqiNode->Header.Value);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
-\r
- } else if (stricmp(Type, "CHECKBOX") == 0) {\r
- UqiNode = CreateInsertUqiNode ();\r
- if (UqiNode == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.Type = CHECKBOX;\r
- UqiNode->Header.HexNum = UqiSize;\r
- UqiNode->Header.Data = UqiBuffer;\r
- UqiNode->Header.Value = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.DiffValue = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.IdNum = PlatformIdNum;\r
- UqiNode->Header.DefaultId = (UINT16 *)calloc (PlatformIdNum, sizeof (UINT16));\r
- if (UqiNode->Header.DefaultId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.PlatformId = (UINT64 *)calloc (PlatformIdNum, sizeof (UINT64));\r
- if (UqiNode->Header.PlatformId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- for (Index5 = 0; Index5 < PlatformIdNum; Index5++) {\r
- UqiNode->Header.DefaultId[Index5] = (UINT16)DefaultId[Index5];\r
- }\r
- memcpy (UqiNode->Header.PlatformId, PlatformId, PlatformIdNum * sizeof (UINT64));\r
-\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %llx", (long long *)UqiNode->Header.Value);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %llx", (long long *)UqiNode->Header.Value);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
-\r
- } else if (stricmp(Type, "STRING") == 0) {\r
- UqiNode = CreateInsertUqiNode ();\r
- if (UqiNode == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- UqiNode->Header.Type = STRING;\r
- UqiNode->Header.HexNum = UqiSize;\r
- UqiNode->Header.Data = UqiBuffer;\r
- UqiNode->Header.Value = (UINT8 *)calloc(MAX_INPUT_ALLOCATE_SIZE, sizeof(CHAR16));\r
- UqiNode->Header.DiffValue = (UINT8 *)calloc(MAX_INPUT_ALLOCATE_SIZE, sizeof(CHAR16));\r
- if (UqiNode->Header.Value == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- if (UqiNode->Header.DiffValue == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.IdNum = PlatformIdNum;\r
- UqiNode->Header.DefaultId = (UINT16 *)calloc (PlatformIdNum, sizeof (UINT16));\r
- if (UqiNode->Header.DefaultId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.PlatformId = (UINT64 *)calloc (PlatformIdNum, sizeof (UINT64));\r
- if (UqiNode->Header.PlatformId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- for (Index5 = 0; Index5 < PlatformIdNum; Index5++) {\r
- UqiNode->Header.DefaultId[Index5] = (UINT16)DefaultId[Index5];\r
- }\r
- memcpy (UqiNode->Header.PlatformId, PlatformId, PlatformIdNum * sizeof (UINT64));\r
- InQuote = FALSE;\r
- IdStart = 0;\r
- IdEnd = 0;\r
- for (Index = 0; Index < MAX_INPUT_ALLOCATE_SIZE; Index ++) {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- if (TempChar == '\"') {\r
- if (InQuote == TRUE) {\r
- InQuote = FALSE;\r
- IdEnd = Index;\r
- } else {\r
- InQuote = TRUE;\r
- IdStart = Index;\r
- }\r
- }\r
- if (Index > IdStart) {\r
- if (InQuote == FALSE) {\r
- break;\r
- }\r
- *(UqiNode->Header.Value + Index - IdStart -1) = TempChar;\r
- Index ++;\r
- }\r
-\r
- }\r
- if (IdEnd < IdStart) {\r
- printf("The STRING is not end with \" character!\n");\r
- return EFI_ABORTED;\r
- }\r
- if (IdStart == 0) {\r
- printf("The STRING is not start with \" character!\n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- } else if (stricmp(Type, "NUMERIC") == 0) {\r
- UqiNode = CreateInsertUqiNode ();\r
- if (UqiNode == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.Type = NUMERIC;\r
- UqiNode->Header.HexNum = UqiSize;\r
- UqiNode->Header.Data = UqiBuffer;\r
- UqiNode->Header.Value = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.DiffValue = (UINT8 *)calloc(1, sizeof(UINT64));\r
- UqiNode->Header.IdNum = PlatformIdNum;\r
- UqiNode->Header.DefaultId = (UINT16 *)calloc (PlatformIdNum, sizeof (UINT16));\r
- if (UqiNode->Header.DefaultId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.PlatformId = (UINT64 *)calloc (PlatformIdNum, sizeof (UINT64));\r
- if (UqiNode->Header.PlatformId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- for (Index5 = 0; Index5 < PlatformIdNum; Index5++) {\r
- UqiNode->Header.DefaultId[Index5] = (UINT16)DefaultId[Index5];\r
- }\r
- memcpy (UqiNode->Header.PlatformId, PlatformId, PlatformIdNum * sizeof (UINT64));\r
-\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %llx", (long long *)UqiNode->Header.Value);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %llx", (long long *)UqiNode->Header.Value);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
-\r
- } else if (stricmp(Type, "ORDERED_LIST") == 0) {\r
- UqiNode = CreateInsertUqiNode ();\r
- if (UqiNode == NULL) {\r
- free (UqiBuffer);\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.Type = ORDERED_LIST;\r
- UqiNode->Header.HexNum = UqiSize;\r
- UqiNode->Header.Data = UqiBuffer;\r
- UqiNode->Header.IdNum = PlatformIdNum;\r
- UqiNode->Header.DefaultId = (UINT16 *)calloc (PlatformIdNum, sizeof (UINT16));\r
- if (UqiNode->Header.DefaultId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.PlatformId = (UINT64 *)calloc (PlatformIdNum, sizeof (UINT64));\r
- if (UqiNode->Header.PlatformId == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- for (Index5 = 0; Index5 < PlatformIdNum; Index5++) {\r
- UqiNode->Header.DefaultId[Index5] = (UINT16)DefaultId[Index5];\r
- }\r
- memcpy (UqiNode->Header.PlatformId, PlatformId, PlatformIdNum * sizeof (UINT64));\r
-\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %x", (INT32 *)&MaxContainers);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %x", (INT32 *)&MaxContainers);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- if (MaxContainers > MAX_INPUT_ALLOCATE_SIZE) {\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.Value = (UINT8 *)calloc(MaxContainers + 1, sizeof(UINT64));\r
- if (UqiNode->Header.Value == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- UqiNode->Header.DiffValue = (UINT8 *)calloc(MaxContainers + 1, sizeof(UINT64));\r
- if (UqiNode->Header.DiffValue == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- *UqiNode->Header.Value = (UINT8) MaxContainers;\r
- *UqiNode->Header.DiffValue = (UINT8) MaxContainers;\r
-\r
- for (Index = 1; Index <= MaxContainers; Index++) {\r
- if (*(UqiNode->Header.Value + Index) == '/') {\r
- printf ("Error. Failed to parse the value of ORDERED_LIST.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %llx", ((long long *)UqiNode->Header.Value + Index));\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %llx", ((long long *)UqiNode->Header.Value + Index));\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- }\r
-\r
- } else {\r
- //\r
- // Unknown type\r
- //\r
- // Free UQI buffer before skipping to next line\r
- //\r
- free(UqiBuffer);\r
- UqiBuffer = NULL;\r
- printf ("Error. Invalid parameters exist in scripts line %d", ScriptsLine);\r
- return EFI_ABORTED;\r
- }\r
- UqiNode->Header.ScriptsLine = ScriptsLine;\r
- //\r
- // Skip to next line\r
- //\r
- do {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- } while((TempChar != '\n') && !feof(ScriptFile));\r
- break;\r
-\r
- case '\n':\r
- case '\r':\r
- //\r
- // Newline, skip to next character\r
- //\r
- break;\r
-\r
- case '/':\r
- //\r
- // Get the value of PlatformId and DefaultId from comments\r
- //\r
- do {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- //\r
- //"/ DefaultId :"\r
- //\r
- if (!ReadDefaultId) {\r
- if (TempChar == DefaultIdStr[Index1]) {\r
- Index1++;\r
- } else {\r
- Index1 = 0;\r
- }\r
- if (Index1 == strlen (DefaultIdStr)) {\r
- Index1 = 0;\r
- Index3 = 0;\r
- memset (Array, 0, MAX_PLATFORM_DEFAULT_ID_NUM * MAX_PLATFORM_DEFAULT_ID_NUM);\r
- ReadDefaultId = TRUE;\r
- mMultiPlatformParam.MultiPlatformOrNot = TRUE;\r
- }\r
- } else if (ReadDefaultId) {\r
- if (TempChar == '\n') {\r
- ReadDefaultId = FALSE;\r
- Array[Index3] = TempChar;\r
- DefaultIdNum = GetNumFromAsciiString ((CHAR8 *)Array, DefaultId);\r
- mMultiPlatformParam.KeyDefaultId[mMultiPlatformParam.KeyIdNum] = (UINT16)DefaultId[0];\r
- } else {\r
- Array[Index3++] = TempChar;\r
- }\r
- }\r
- //\r
- //"/ PlatformId:"\r
- //\r
- if (!ReadPlatformId) {\r
- if (TempChar == PlatformIdStr[Index2]) {\r
- Index2++;\r
- } else {\r
- Index2 = 0;\r
- }\r
- if (Index2 == strlen (PlatformIdStr)) {\r
- Index2 = 0;\r
- Index3 = 0;\r
- memset (Array, 0, MAX_PLATFORM_DEFAULT_ID_NUM * MAX_PLATFORM_DEFAULT_ID_NUM);\r
- ReadPlatformId = TRUE;\r
- }\r
- } else if (ReadPlatformId) {\r
- if (TempChar == '\n') {\r
- ReadPlatformId = FALSE;\r
- Array[Index3] = TempChar;\r
- PlatformIdNum = GetNumFromAsciiString ((CHAR8 *)Array, PlatformId);\r
- //\r
- // Take the first defaultid an platformid as the key of this group\r
- //\r
- mMultiPlatformParam.KeyPlatformId[mMultiPlatformParam.KeyIdNum++] = PlatformId[0];\r
- assert (DefaultIdNum == PlatformIdNum);\r
- } else {\r
- Array[Index3++] = TempChar;\r
- }\r
- }\r
- //\r
- //"/ PlatformIdUqi:"\r
- //\r
- if (!ReadPlatformIdUqi) {\r
- if (TempChar == PlatformUqi[Index4]) {\r
- Index4++;\r
- } else {\r
- Index4 = 0;\r
- }\r
- if (Index4 == strlen (PlatformUqi)) {\r
- Index4 = 0;\r
- Index3 = 0;\r
- memset (Array, 0, MAX_PLATFORM_DEFAULT_ID_NUM * MAX_PLATFORM_DEFAULT_ID_NUM);\r
- ReadPlatformIdUqi = TRUE;\r
- }\r
- } else if (ReadPlatformIdUqi) {\r
- if (mMultiPlatformParam.Uqi.HexNum > 0) {\r
- continue;\r
- }\r
- //\r
- // Read size of UQI string\r
- //\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %x", (INT32 *)&mMultiPlatformParam.Uqi.HexNum);\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %x", (INT32 *)&mMultiPlatformParam.Uqi.HexNum);\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- if (mMultiPlatformParam.Uqi.HexNum > MAX_INPUT_ALLOCATE_SIZE) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Malloc buffer for string size + null termination\r
- //\r
- if (mMultiPlatformParam.Uqi.Data != NULL) {\r
- free (mMultiPlatformParam.Uqi.Data);\r
- mMultiPlatformParam.Uqi.Data = NULL;\r
- }\r
- mMultiPlatformParam.Uqi.Data = (CHAR16 *)calloc(mMultiPlatformParam.Uqi.HexNum + 1, sizeof(CHAR16));\r
-\r
- if (mMultiPlatformParam.Uqi.Data == NULL) {\r
- printf("Error. Unable to allocate 0x%04zx bytes for UQI string -- FAILURE\n", (mMultiPlatformParam.Uqi.HexNum + 1) * sizeof(CHAR16));\r
- break;\r
- }\r
- //\r
- // Read UQI string\r
- //\r
- for (Index = 0; Index < mMultiPlatformParam.Uqi.HexNum; Index++) {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fscanf(ScriptFile, " %hx", (short *)&(mMultiPlatformParam.Uqi.Data[Index]));\r
- } else {\r
- Char8Str = ReadUcs2ToStr (ScriptFile, AsciiOrUcs2);\r
- if (Char8Str == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- sscanf(Char8Str, " %hx", (short *)&(mMultiPlatformParam.Uqi.Data[Index]));\r
- if (Char8Str != NULL) {\r
- free (Char8Str);\r
- Char8Str = NULL;\r
- }\r
- }\r
- }\r
- //\r
- // Set null termination\r
- //\r
- mMultiPlatformParam.Uqi.Data[Index] = 0;\r
- ReadPlatformIdUqi = FALSE;\r
- }\r
-\r
- } while((TempChar != '\n') && !feof(ScriptFile));\r
- break;\r
- //\r
- // To do: Get and set DefaultId and PlatformId here!\r
- //\r
- default:\r
- //\r
- // Comment or garbage, skip to next line\r
- //\r
- do {\r
- if (AsciiOrUcs2 == ASCII) {\r
- fread(&TempChar, sizeof (CHAR8), 1, ScriptFile);\r
- } else {\r
- fread(&TempChar16, sizeof (CHAR16), 1, ScriptFile);\r
- if (AsciiOrUcs2 == BIG_UCS2) {\r
- TempChar = (CHAR8)TempChar16;\r
- } else {\r
- TempChar = (CHAR8)(TempChar16 >> 8);\r
- }\r
- }\r
- } while((TempChar != '\n') && !feof(ScriptFile));\r
- break;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get the offset of file name from the whole path.\r
-\r
- @param NameStr The whole file path.\r
-\r
- @retval Offset Return the offset of file name in path\r
-**/\r
-static\r
-UINTN\r
-GetOffsetOfFileName (\r
- IN CHAR8 *NameStr\r
- )\r
-{\r
- CHAR8 *Str;\r
- UINTN Index;\r
- UINTN CurIndex;\r
-\r
- Index = 0;\r
- CurIndex = 0;\r
- Str = NameStr;\r
-\r
- if (NameStr == NULL) {\r
- return 0;\r
- }\r
- while (*Str != '\0') {\r
- if (*Str == OS_SEP) {\r
- CurIndex = Index;\r
- }\r
- Str++;\r
- Index++;\r
- }\r
- if (*(NameStr + CurIndex) == OS_SEP) {\r
- return CurIndex + 1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-/**\r
- Print the questions which is updated to the current platform successfully.\r
-\r
- Parse the Uqi List, and print it till break NULL.\r
-\r
- @param List Pointer to a List.\r
-\r
- @retval EFI_SUCCESS The Print was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-VOID\r
-PrintUpdateListInfo (\r
- IN UQI_PARAM_LIST *UqiList\r
- )\r
-{\r
- UINT32 Index;\r
- UINT32 Index1;\r
- UINT32 Index2;\r
- UQI_PARAM_LIST *CurList;\r
-\r
- Index1 = 0;\r
- Index2 = 0;\r
- Index = 0;\r
- CurList = UqiList;\r
-\r
- printf ("\n\n -- Update List -- ");\r
-\r
- while (CurList != NULL) {\r
- if (!CurList->ErrorOrNot && CurList->ParseOrNot && !CurList->SameOrNot) {\r
- ++Index;\r
- printf ("\n\n[Script line %d] Update No.%d:\n", CurList->Header.ScriptsLine, ++Index1);\r
- printf ("Q %04x ", CurList->Header.HexNum);\r
- for (Index2 = 0; Index2 < CurList->Header.HexNum; Index2++) {\r
- printf ("%04x ", CurList->Header.Data[Index2]);\r
- }\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- printf ("ORDERED_LIST ");\r
- } else if (CurList->Header.Type == CHECKBOX) {\r
- printf ("CHECKBOX ");\r
- } else if (CurList->Header.Type == ONE_OF) {\r
- printf ("ONE_OF ");\r
- } else if (CurList->Header.Type == NUMERIC) {\r
- printf ("NUMERIC ");\r
- } else if (CurList->Header.Type == STRING) {\r
- printf ("STRING ");\r
- } else {\r
- printf ("UNKNOWN ");\r
- }\r
- //\r
- //Print the value of scripts\r
- //\r
- printf ("\n[ Update Value From: ");\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- for (Index2 = 0; Index2 <= *(CurList->Header.DiffValue); Index2++) {\r
- printf ("%02x ", *(CurList->Header.DiffValue + Index2));\r
- }\r
- } else if (CurList->Header.Type == STRING) {\r
- printf("\"");\r
- WriteUnicodeStr((CHAR16 *)CurList->Header.DiffValue);\r
- printf("\"");\r
- } else {\r
- printf ("%llx ", *(unsigned long long*)(UINT64 *)CurList->Header.DiffValue);\r
- }\r
- //\r
- //Print the value of current platform\r
- //\r
- printf (" To: ");\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- for (Index2 = 0; Index2 <= *(CurList->Header.Value); Index2++) {\r
- printf ("%02x ", *(CurList->Header.Value + Index2));\r
- }\r
- } else if (CurList->Header.Type == STRING) {\r
- printf("\"");\r
- WriteUnicodeStr((CHAR16 *)CurList->Header.Value);\r
- printf("\"");\r
- } else {\r
- printf ("%llx ", *(unsigned long long*)(UINT64 *)CurList->Header.Value);\r
- }\r
- printf ("]");\r
- }\r
- CurList = CurList->Next;\r
- }\r
- if (Index > 1) {\r
- printf ("\n\n\n[Results]: %d questions have been updated successfully in total. \n", Index);\r
- } else {\r
- printf ("\n\n\n[Results]: %d question has been updated successfully in total. \n", Index);\r
- }\r
-}\r
-\r
-\r
-/**\r
- Print the error, when update questions.\r
-\r
- Parse the Uqi List, and print it till break NULL.\r
-\r
- @param List The Pointer to a List.\r
-\r
-**/\r
-static\r
-BOOLEAN\r
-PrintErrorInfo (\r
- IN UQI_PARAM_LIST *UqiList\r
- )\r
-{\r
- UINT32 Index1;\r
- UINT32 Index2;\r
- UINT32 Index;\r
- UQI_PARAM_LIST *CurList;\r
- BOOLEAN IsError;\r
-\r
- Index1 = 0;\r
- Index2 = 0;\r
- Index = 0;\r
- CurList = UqiList;\r
- IsError = FALSE;\r
-\r
- while (CurList != NULL) {\r
- if (CurList->ErrorOrNot && CurList->ParseOrNot) {\r
- IsError = TRUE;\r
- ++Index;\r
- printf ("\n\n[Script line %d] Error Information No.%d:\n", CurList->Header.ScriptsLine, ++Index1);\r
- printf ("Q %04x ", CurList->Header.HexNum);\r
- for (Index2 = 0; Index2 < CurList->Header.HexNum; Index2++) {\r
- printf ("%04x ", CurList->Header.Data[Index2]);\r
- }\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- printf ("ORDERED_LIST ");\r
- } else if (CurList->Header.Type == CHECKBOX) {\r
- printf ("CHECKBOX ");\r
- } else if (CurList->Header.Type == ONE_OF) {\r
- printf ("ONE_OF ");\r
- } else if (CurList->Header.Type == NUMERIC) {\r
- printf ("NUMERIC ");\r
- } else if (CurList->Header.Type == STRING) {\r
- printf ("STRING ");\r
- } else {\r
- printf ("UNKNOWN ");\r
- }\r
- //\r
- //Print the Input value of scripts\r
- //\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- for (Index2 = 0; Index2 <= *CurList->Header.Value; Index2++) {\r
- printf ("%02x ", *(CurList->Header.Value + Index2));\r
- }\r
- } else if (CurList->Header.Type == STRING) {\r
- printf("\"");\r
- WriteUnicodeStr((CHAR16 *)CurList->Header.Value);\r
- printf("\"");\r
- } else {\r
- printf ("%llx ", *(unsigned long long*)(UINT64 *)CurList->Header.Value);\r
- }\r
- //\r
- //Print the Error information\r
- //\r
- if (CurList->Error != NULL) {\r
- printf ("\n%s ", CurList->Error);\r
- }\r
- }\r
- CurList = CurList->Next;\r
- }\r
- if (IsError) {\r
- if (Index > 1) {\r
- printf ("\n\n[Results]: Occurred %d errors during the update process. \n", Index);\r
- } else {\r
- printf ("\n\n[Results]: Occurred %d error during the update process. \n", Index);\r
- }\r
- }\r
- return IsError;\r
-}\r
-\r
-/**\r
- Any questions that exist in both the script and the current platform and have\r
- different values will be logged to the screen.\r
-\r
- Parse the Uqi List, and print it till break NULL.\r
-\r
- @param List Pointer to a List.\r
-\r
- @retval EFI_SUCCESS The Print was complete successfully\r
- @return EFI_ABORTED An error occurreds\r
-**/\r
-static\r
-VOID\r
-PrintVerifiedListInfo (\r
- IN UQI_PARAM_LIST *UqiList\r
- )\r
-{\r
- UINT32 Index1;\r
- UINT32 Index2;\r
- UINT32 Index3;\r
- UINT32 Index;\r
- UQI_PARAM_LIST *CurList;\r
- UINT32 StrLen;\r
- UINT32 StrLen1;\r
- UINT32 StrLen2;\r
-\r
- Index1 = 0;\r
- Index2 = 0;\r
- Index = 0;\r
- StrLen = 0;\r
- CurList = UqiList;\r
-\r
- StrLen1 = strlen (mSetupTxtName + GetOffsetOfFileName (mSetupTxtName));\r
- StrLen2 = strlen (mInputFdName + GetOffsetOfFileName (mInputFdName));\r
-\r
- StrLen = (StrLen1 > StrLen2) ? StrLen1:StrLen2;\r
-\r
- printf ("\n\n -- Different List -- ");\r
-\r
- while (CurList != NULL) {\r
- if (!CurList->SameOrNot && CurList->ParseOrNot) {\r
- ++Index;\r
- printf ("\n\n[Script line %d] Difference No.%d:", CurList->Header.ScriptsLine, ++Index1);\r
- printf ("\n[%s", mSetupTxtName + GetOffsetOfFileName (mSetupTxtName));\r
- for (Index3 = 0; Index3 < StrLen - StrLen1; Index3++) {\r
- printf (" ");\r
- }\r
- printf ("]:");\r
- printf (" Q %04x ", CurList->Header.HexNum);\r
- for (Index2 = 0; Index2 < CurList->Header.HexNum; Index2++) {\r
- printf ("%04x ", CurList->Header.Data[Index2]);\r
- }\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- printf ("ORDERED_LIST ");\r
- } else if (CurList->Header.Type == CHECKBOX) {\r
- printf ("CHECKBOX ");\r
- } else if (CurList->Header.Type == ONE_OF) {\r
- printf ("ONE_OF ");\r
- } else if (CurList->Header.Type == NUMERIC) {\r
- printf ("NUMERIC ");\r
- } else if (CurList->Header.Type == STRING) {\r
- printf ("STRING ");\r
- } else {\r
- printf ("UNKNOWN ");\r
- }\r
- //\r
- //Print the Input value of scripts\r
- //\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- for (Index2 = 0; Index2 <= *(CurList->Header.Value); Index2++) {\r
- printf ("%02x ", *(CurList->Header.Value + Index2));\r
- }\r
- } else if (CurList->Header.Type == STRING) {\r
- printf("\"");\r
- WriteUnicodeStr((CHAR16 *)CurList->Header.Value);\r
- printf("\"");\r
- } else {\r
- printf ("%llx ", *(unsigned long long*)(UINT64 *)CurList->Header.Value);\r
- }\r
- //\r
- //Print the value of current platform\r
- //\r
- printf ("\n[%s", mInputFdName + GetOffsetOfFileName (mInputFdName));\r
- for (Index3 = 0; Index3 < StrLen - StrLen2; Index3++) {\r
- printf (" ");\r
- }\r
- printf ("]:");\r
- printf (" Q %04x ", CurList->Header.HexNum);\r
- for (Index2 = 0; Index2 < CurList->Header.HexNum; Index2++) {\r
- printf ("%04x ", CurList->Header.Data[Index2]);\r
- }\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- printf ("ORDERED_LIST ");\r
- } else if (CurList->Header.Type == CHECKBOX) {\r
- printf ("CHECKBOX ");\r
- } else if (CurList->Header.Type == ONE_OF) {\r
- printf ("ONE_OF ");\r
- } else if (CurList->Header.Type == NUMERIC) {\r
- printf ("NUMERIC ");\r
- } else if (CurList->Header.Type == STRING) {\r
- printf ("STRING ");\r
- } else {\r
- printf ("UNKNOWN ");\r
- }\r
- if (CurList->Header.Type == ORDERED_LIST) {\r
- for (Index2 = 0; Index2 <= *(CurList->Header.DiffValue); Index2++) {\r
- printf ("%02x ", *(CurList->Header.DiffValue + Index2));\r
- }\r
- } else if (CurList->Header.Type == STRING) {\r
- printf("\"");\r
- WriteUnicodeStr((CHAR16 *)CurList->Header.DiffValue);\r
- printf("\"");\r
- } else {\r
- printf ("%llx ", *(unsigned long long*)(UINT64 *)CurList->Header.DiffValue);\r
- }\r
- }\r
- CurList = CurList->Next;\r
- }\r
- if (Index > 1) {\r
- printf (\r
- "\n\n\n[Results]: There are %d differences between '%s' and '%s' in total.\n\n\n",\r
- Index,\r
- mSetupTxtName + GetOffsetOfFileName (mSetupTxtName),\r
- mInputFdName + GetOffsetOfFileName (mInputFdName)\r
- );\r
- } else {\r
- printf (\r
- "\n\n\n[Results]: There is %d difference between '%s' and '%s' in total.\n\n\n",\r
- Index,\r
- mSetupTxtName + GetOffsetOfFileName (mSetupTxtName),\r
- mInputFdName + GetOffsetOfFileName (mInputFdName)\r
- );\r
- }\r
-}\r
-\r
-/**\r
- Insert Uqi object to the end of unidirection List.\r
-\r
- @param InList The Pointer to the current object\r
- @param UqiListEntry The pointer to the entry of UqiList\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-InsertUnidirectionList (\r
- IN UQI_PARAM_LIST *InList,\r
- IN UQI_PARAM_LIST **UqiListEntry\r
- )\r
-{\r
- UQI_PARAM_LIST **UqiCurList;\r
- UQI_PARAM_LIST *UqiNext;\r
-\r
- UqiCurList = NULL;\r
- UqiNext = NULL;\r
-\r
- if (UqiListEntry == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Insert to Uqi Node to UqiList\r
- //\r
- UqiCurList = UqiListEntry;\r
- UqiNext = *UqiCurList;\r
- if (UqiNext == NULL) {\r
- //\r
- //Insert is the first node as node header\r
- //\r
- *UqiCurList = InList;\r
- } else {\r
- while ((UqiNext != NULL) && (UqiNext->Next != NULL)) {\r
- UqiNext = UqiNext->Next;\r
- }\r
- UqiNext->Next = InList;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Free variable unidirection List.\r
-\r
- @param UqiListEntry The pointer to the entry of UqiList\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-FreeUnidirectionList (\r
- IN UQI_PARAM_LIST *UqiListEntry\r
- )\r
-{\r
- UQI_PARAM_LIST *Next;\r
-\r
- Next = NULL;\r
- //\r
- // Free Uqi List\r
- //\r
- while (UqiListEntry != NULL) {\r
- Next = UqiListEntry->Next;\r
- if (UqiListEntry->Header.Value != NULL) {\r
- free (UqiListEntry->Header.Value);\r
- }\r
- if (UqiListEntry->Header.DiffValue != NULL) {\r
- free (UqiListEntry->Header.DiffValue);\r
- }\r
- if (UqiListEntry->Header.Data != NULL) {\r
- free (UqiListEntry->Header.Data);\r
- }\r
- if (UqiListEntry->Header.DefaultId != NULL) {\r
- free (UqiListEntry->Header.DefaultId);\r
- }\r
- if (UqiListEntry->Header.PlatformId != NULL) {\r
- free (UqiListEntry->Header.PlatformId);\r
- }\r
- if (UqiListEntry->Error != NULL) {\r
- free (UqiListEntry->Error);\r
- }\r
- free (UqiListEntry);\r
- UqiListEntry = Next;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Delete a directory and files in it.\r
-\r
- @param DirName Name of the directory need to be deleted.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-static\r
-EFI_STATUS\r
-LibRmDir (\r
- IN CHAR8* DirName\r
-)\r
-{\r
- CHAR8* SystemCommand;\r
-\r
- SystemCommand = NULL;\r
-\r
- if (DirName == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Delete a directory and files in it.\r
- //\r
-\r
- SystemCommand = malloc (\r
- strlen (RMDIR_STR) +\r
- strlen (DirName) +\r
- 1\r
- );\r
- if (SystemCommand == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- RMDIR_STR,\r
- DirName\r
- );\r
-\r
- system (SystemCommand);\r
- free(SystemCommand);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Pick up the FFS from the FD image.\r
-\r
- Call BfmLib to get all FFS in one FD image, and save all which includes IFR\r
- Binary to gEfiFdInfo structure.\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
-**/\r
-static\r
-EFI_STATUS\r
-PickUpFfsFromFd (\r
- VOID\r
- )\r
-{\r
- CHAR8 *SystemCommandFormatString;\r
- CHAR8 *SystemCommand;\r
- CHAR8 *TempSystemCommand;\r
- CHAR8 *TemDir;\r
- EFI_STATUS Status;\r
- INT32 ReturnValue;\r
-\r
- Status = EFI_SUCCESS;\r
- SystemCommandFormatString = NULL;\r
- SystemCommand = NULL;\r
- TempSystemCommand = NULL;\r
- TemDir = NULL;\r
- ReturnValue = 0;\r
-\r
- memset (&gEfiFdInfo, 0, sizeof (G_EFI_FD_INFO));\r
- //\r
- // Construction 'system' command string\r
- //\r
- SystemCommandFormatString = "BfmLib -e \"%s\" ";\r
-\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (mInputFdName) + 1\r
- );\r
-\r
- if (SystemCommand == NULL) {\r
- printf ("Fail to allocate memory.\n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -e \"%s\" ",\r
- mInputFdName\r
- );\r
-\r
- if (mFullGuidToolDefinitionDir[0] != 0) {\r
- TempSystemCommand = SystemCommand;\r
- SystemCommand = malloc (\r
- strlen (mFullGuidToolDefinitionDir) + strlen (OS_SEP_STR) + strlen (TempSystemCommand) + 1\r
- );\r
-\r
- if (SystemCommand == NULL) {\r
- free (TempSystemCommand);\r
- return EFI_UNSUPPORTED;\r
- }\r
- strcpy (SystemCommand, mFullGuidToolDefinitionDir);\r
- strcat (SystemCommand, OS_SEP_STR);\r
- strcat (SystemCommand, TempSystemCommand);\r
- free (TempSystemCommand);\r
-\r
- }\r
-\r
- //\r
- // Call BfmLib to get all FFS in Temp folder of current path\r
- //\r
- ReturnValue = system (SystemCommand);\r
- free (SystemCommand);\r
- if (ReturnValue == -1) {\r
- printf ("Error. Call BfmLib failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- //Pick up the FFS which is interrelated with the IFR binary.\r
- //\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TemDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME)> _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- return EFI_ABORTED;\r
- }\r
- strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen (TemDir) - 1);\r
- strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TemDir) - 1);\r
- mMultiPlatformParam.ExistStorageFfsInBfv = FALSE;\r
- Status = FindFileInFolder (TemDir, &mMultiPlatformParam.ExistStorageFfsInBfv, &mMultiPlatformParam.SizeOptimized);\r
-\r
- return Status;\r
-}\r
-\r
-#define BUILD_IN_TOOL_COUNT 4\r
-/**\r
- Generate pre-defined guided tools data.\r
-\r
- @return An EFI_HANDLE contain guided tools data.\r
-\r
-**/\r
-static\r
-EFI_HANDLE\r
-PreDefinedGuidedTools (\r
- VOID\r
-)\r
-{\r
- EFI_GUID Guid;\r
- STRING_LIST *Tool;\r
- GUID_SEC_TOOL_ENTRY *FirstGuidTool;\r
- GUID_SEC_TOOL_ENTRY *LastGuidTool;\r
- GUID_SEC_TOOL_ENTRY *NewGuidTool;\r
- UINT8 Index;\r
- EFI_STATUS Status;\r
-\r
- CHAR8 PreDefinedGuidedTool[BUILD_IN_TOOL_COUNT][255] = {\r
- "a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress",\r
- "ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress",\r
- "fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32",\r
- "3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress"\r
- };\r
-\r
- Tool = NULL;\r
- FirstGuidTool = NULL;\r
- LastGuidTool = NULL;\r
- NewGuidTool = NULL;\r
-\r
- for (Index = 0; Index < BUILD_IN_TOOL_COUNT; Index++) {\r
- Tool = SplitStringByWhitespace (PreDefinedGuidedTool[Index]);\r
- if ((Tool != NULL) &&\r
- (Tool->Count == 3)\r
- ) {\r
- Status = StringToGuid (Tool->Strings[0], &Guid);\r
- if (!EFI_ERROR (Status)) {\r
- NewGuidTool = malloc (sizeof (GUID_SEC_TOOL_ENTRY));\r
- if (NewGuidTool != NULL) {\r
- memcpy (&(NewGuidTool->Guid), &Guid, sizeof (Guid));\r
- NewGuidTool->Name = CloneString(Tool->Strings[1]);\r
- NewGuidTool->Path = CloneString(Tool->Strings[2]);\r
- NewGuidTool->Next = NULL;\r
- } else {\r
- printf ( "Fail to allocate memory. \n");\r
- if (Tool != NULL) {\r
- FreeStringList (Tool);\r
- }\r
- return NULL;\r
- }\r
- if (FirstGuidTool == NULL) {\r
- FirstGuidTool = NewGuidTool;\r
- } else {\r
- LastGuidTool->Next = NewGuidTool;\r
- }\r
- LastGuidTool = NewGuidTool;\r
- }\r
-\r
- } else {\r
- fprintf (stdout, "Error");\r
- }\r
- if (Tool != NULL) {\r
- FreeStringList (Tool);\r
- Tool = NULL;\r
- }\r
- }\r
- return FirstGuidTool;\r
-}\r
-\r
-/**\r
- Read all storages under a specified platformId and defaultId from BFV.\r
-\r
- @param Binary The pointer to the buffer of binary.\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadStorageFromBinary (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- UINT32 Length;\r
- UINT8 *DataBase;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
-\r
- Length = 0;\r
- AuthencitatedMonotonicOrNot = FALSE;\r
- AuthencitatedBasedTimeOrNot = FALSE;\r
- DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);\r
- //\r
- // Judge the layout of NV by Variable Guid\r
- //\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore ((VOID *)(DataBase + *(UINT16 *)DataBase));\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot ((VOID *)(DataBase + *(UINT16 *)DataBase));\r
-\r
- if (AuthencitatedMonotonicOrNot) {\r
- //\r
- // Read variable with Monotonic based layout from binary\r
- //\r
- Length = ReadMonotonicBasedVariableToList (Binary, StorageListEntry);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- //\r
- // Read variable with time-based layout from binary\r
- //\r
- Length = ReadTimeBasedVariableToList (Binary, StorageListEntry);\r
- } else {\r
- //\r
- // Read variable with normal layout from binary\r
- //\r
- Length = ReadVariableToList (Binary, StorageListEntry);\r
- }\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Insert one storage to the raw bianry, and return its length.\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param Binary The pointer to the buffer of binary.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-PutStorageToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- UINT32 Length;\r
- UINT32 Index;\r
- UINT8 *BinaryBeginning;\r
- FORMSET_STORAGE *CurStorage;\r
- LIST_ENTRY *StorageLink;\r
- VOID *VariableStoreHeader;\r
- BOOLEAN AuthencitatedMonotonicOrNot;\r
- BOOLEAN AuthencitatedBasedTimeOrNot;\r
-\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- Length = 0;\r
- Index = 0;\r
- BinaryBeginning = Binary;\r
- VariableStoreHeader = (VOID *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- AuthencitatedMonotonicOrNot = FALSE;\r
- AuthencitatedBasedTimeOrNot = FALSE;\r
- //\r
- // Judge the layout of NV by gEfiVariableGuid\r
- //\r
- AuthencitatedMonotonicOrNot = CheckMonotonicBasedVarStore (VariableStoreHeader);\r
- AuthencitatedBasedTimeOrNot = CheckTimeBasedVarStoreOrNot (VariableStoreHeader);\r
- //\r
- // Build the binary for BFV\r
- //\r
- StorageLink = GetFirstNode (StorageListEntry);\r
-\r
- while (!IsNull (StorageListEntry, StorageLink)) {\r
- CurStorage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if ((CurStorage->DefaultId[0] == Storage->DefaultId[0])\r
- && (CurStorage->PlatformId[0] == Storage->PlatformId[0])\r
- && !CurStorage->Skip\r
- ) {\r
- CurStorage->Skip = TRUE;\r
-\r
- if (AuthencitatedMonotonicOrNot) {\r
- //\r
- // Copy variable with Monotonic based layout to binary\r
- //\r
- Length = CopyMonotonicBasedVariableToBinary (CurStorage, BinaryBeginning, Index);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- //\r
- // Copy variable with time-based layout to binary\r
- //\r
- Length = CopyTimeBasedVariableToBinary (CurStorage, BinaryBeginning, Index);\r
- } else {\r
- //\r
- // Copy variable with normall layout to binary\r
- //\r
- Length = CopyVariableToBinary (CurStorage, BinaryBeginning, Index);\r
- }\r
- Index++;\r
- }\r
- StorageLink = GetNextNode (StorageListEntry, StorageLink);\r
- }\r
- //\r
- // Fix the length of storage header under a specified DefaultId and PlatformId\r
- //\r
- if (AuthencitatedMonotonicOrNot) {\r
- FixMontonicVariableHeaderSize (BinaryBeginning, Length);\r
- } else if (AuthencitatedBasedTimeOrNot){\r
- FixBasedTimeVariableHeaderSize (BinaryBeginning, Length);\r
- } else {\r
- FixVariableHeaderSize (BinaryBeginning, Length);\r
- }\r
- return Length;\r
-}\r
-\r
-/**\r
- Insert one storage to Fd's NvStoreDatabase, and return its length.\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param Binary The pointer to the buffer of binary.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-PutStorageToNvStoreBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- UINT32 Length;\r
- UINT32 Index;\r
- UINT8 *BinaryBeginning;\r
- FORMSET_STORAGE *CurStorage;\r
- LIST_ENTRY *StorageLink;\r
-\r
- Length = 0;\r
- Index = 0;\r
- BinaryBeginning = Binary;\r
- //\r
- // Build the binary for NvStorDatabase\r
- //\r
- StorageLink = GetFirstNode (StorageListEntry);\r
- while (!IsNull (StorageListEntry, StorageLink)) {\r
- CurStorage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if ((CurStorage->PlatformId[0] == Storage->PlatformId[0])\r
- && (CurStorage->DefaultId[0] == Storage->DefaultId[0])\r
- && !CurStorage->Skip\r
- ) {\r
- CurStorage->Skip = TRUE;\r
- Length = CopyVariableToNvStoreBinary (CurStorage, BinaryBeginning, Index);\r
- Index++;\r
- }\r
- StorageLink = GetNextNode (StorageListEntry, StorageLink);\r
- }\r
- // Alignment\r
- Length = (Length + 3) & ~3;\r
- FixNvStoreVariableHeaderSize (BinaryBeginning, Length);\r
- return Length;\r
-}\r
-\r
-/**\r
- Optimize the Delta binary size based on the default setting binary, and\r
- create a new binary with new size on the Storage.ffs.\r
-\r
- @param DefaultBinary The pointer to a default setting binary\r
- @param DefaultHeaderLen The header lenght of default setting binary\r
- @param DeltaBinary The pointer to a delta setting binary\r
- @param CurrentSize The size of current delta data.\r
-\r
- @return length The length of new storage\r
-**/\r
-UINT32\r
-OptimizeStorageDeltaData (\r
- IN UINT8 *DefaultBinary,\r
- IN UINT8 *CurrentBinary,\r
- IN OUT UINT8 *DeltaBinary,\r
- IN UINT32 CurrentSize\r
- )\r
-{\r
- UINT32 Size;\r
- UINT16 Index;\r
- UINT32 DefaultHeaderSize;\r
- UINT32 DeltaHeaderSize;\r
- UINT32 AlignSize;\r
- PCD_DATA_DELTA DeltaData;\r
- DefaultHeaderSize = ((PCD_DEFAULT_DATA *)DefaultBinary)->HeaderSize + 4;\r
- DeltaHeaderSize = ((PCD_DEFAULT_DATA *)CurrentBinary)->HeaderSize + 4;\r
- //\r
- // Copy the Delta Header directly\r
- //\r
- Size = DeltaHeaderSize;\r
- memcpy (DeltaBinary, CurrentBinary, Size);\r
- //\r
- // Compare the delta data and optimize the size\r
- //\r
- for (Index = 0; Index < CurrentSize - DeltaHeaderSize; Index++) {\r
- if (*(DefaultBinary + DefaultHeaderSize + Index) != *(CurrentBinary + DeltaHeaderSize + Index)) {\r
- DeltaData.Offset = Index;\r
- DeltaData.Value = *(CurrentBinary + DeltaHeaderSize + Index);\r
- memcpy (DeltaBinary + Size, &DeltaData, sizeof (DeltaData));\r
- Size = Size + sizeof(DeltaData);\r
- }\r
- }\r
- *(UINT32 *)DeltaBinary = Size;\r
- AlignSize = (Size + 7) & ~7;\r
- //set Alignment data 0x00\r
- for (Index = 0; Index < AlignSize - Size; Index++){\r
- *(DeltaBinary + Size + Index) = 0x0;\r
- }\r
- return Size;\r
-}\r
-\r
-/**\r
- Optimize the Delta binary size based on the default setting binary, and\r
- create a new binary with new size on the Storage.ffs.\r
-\r
- @param DefaultBinary The pointer to a default setting binary\r
- @param DefaultHeaderLen The header lenght of default setting binary\r
- @param DeltaBinary The pointer to a delta setting binary\r
- @param CurrentSize The size of current delta data.\r
-\r
- @return length The length of new storage\r
-**/\r
-UINT32\r
-OptimizeStorageSection (\r
- IN UINT8 *DefaultBinary,\r
- IN UINT8 *CurrentBinary,\r
- IN OUT UINT8 *DeltaBinary,\r
- IN UINT32 CurrentSize\r
- )\r
-{\r
- UINT32 Size;\r
- UINT16 Index;\r
- UINT32 DefaultHeaderSize;\r
- UINT32 DeltaHeaderSize;\r
- DATA_DELTA DeltaData;\r
-\r
- DefaultHeaderSize = *(UINT16 *)DefaultBinary;\r
- DeltaHeaderSize = *(UINT16 *)CurrentBinary;\r
-\r
- //\r
- // Copy the Delta Header directly\r
- //\r
- Size = DeltaHeaderSize;\r
- memcpy (DeltaBinary, CurrentBinary, Size);\r
- //\r
- // Compare the delta data and optimize the size\r
- //\r
- for (Index = 0; Index < CurrentSize - DeltaHeaderSize; Index++) {\r
- if (*(DefaultBinary + DefaultHeaderSize + Index) != *(CurrentBinary + DeltaHeaderSize + Index)) {\r
- DeltaData.Offset = Index;\r
- DeltaData.Value = *(CurrentBinary + DeltaHeaderSize + Index);\r
- memcpy (DeltaBinary + Size, &DeltaData, sizeof (DeltaData));\r
- Size = Size + sizeof(DeltaData);\r
- }\r
- }\r
- return Size;\r
-}\r
-\r
-/**\r
- Create the storage section and copy it to memory.\r
-\r
- @param Buffer The pointer to the buffer\r
- @param Size The size of input buffer.\r
-\r
- @return the new size\r
-**/\r
-UINT32\r
-CreateStorageSection (\r
- IN OUT UINT8 *Buffer,\r
- IN UINT32 Size,\r
- IN CHAR8 *FileName\r
-)\r
-{\r
- FILE *BinaryFd;\r
- UINTN BytesWrite;\r
- UINT32 SectionSize;\r
-\r
- BinaryFd = NULL;\r
- //\r
- // Create the raw section files in FFS\r
- //\r
- BinaryFd = fopen (FileName, "wb+");\r
- if (BinaryFd == NULL) {\r
- printf ("Error. Failed to create the raw data section.\n");\r
- return 0;\r
- }\r
- fseek (BinaryFd, 0, SEEK_SET);\r
- BytesWrite = fwrite (Buffer, sizeof (CHAR8), Size, BinaryFd);\r
- fclose (BinaryFd);\r
- if (BytesWrite != Size) {\r
- printf ("Error. Failed to write the raw data section.\n");\r
- return 0;\r
- }\r
- CreateRawSection (FileName, FileName);\r
-\r
- BinaryFd = fopen (FileName, "rb");\r
- if (BinaryFd == NULL) {\r
- printf ("Error. Failed to open the raw data section.\n");\r
- return 0;\r
- }\r
- fseek (BinaryFd, 0, SEEK_SET);\r
- BytesWrite = fread (Buffer, sizeof (CHAR8), (Size + sizeof (EFI_COMMON_SECTION_HEADER)), BinaryFd);\r
- fclose (BinaryFd);\r
- if (BytesWrite != (Size + sizeof (EFI_COMMON_SECTION_HEADER))) {\r
- printf ("Error. Failed to read the raw data section.\n");\r
- return 0;\r
- }\r
-\r
- SectionSize = FvBufExpand3ByteSize (((EFI_COMMON_SECTION_HEADER *)Buffer)->Size);\r
- return SectionSize;\r
-}\r
-\r
-/**\r
- Read NvStoreDataBase and insert it to the Storage list.\r
-\r
- @param InputFdName The pointer to the input fd name.\r
- @param VarListEntry The pointer to the variable list.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-ReadStorageFromNvStoreDatabase (\r
- IN LIST_ENTRY *VarListEntry\r
-)\r
-{\r
-\r
- UINT8 *Binary;\r
- UINT8 *FullBinary;\r
- UINT8 *VarDataBinary;\r
- UINT8 *PreVarDataBinary;\r
- UINT8 *DataBase;\r
- PCD_DEFAULT_DATA *DeltaVarStoreHeader;\r
- PCD_DEFAULT_DATA *PrePcdDefaultData;\r
- UINT8 *DeltaData;\r
- UINT32 DeltaSize;\r
- UINT32 DataSize;\r
- UINT32 HeaderSize;\r
- UINT32 BinaryLength;\r
- UINT32 Size;\r
- UINT32 PreVarDataSize;\r
- PCD_NV_STORE_DEFAULT_BUFFER_HEADER *NvStoreHeader;\r
- UINT32 Offset;\r
- UINT32 Value;\r
- UINT32 Index;\r
-\r
- BinaryLength = 0;\r
- Binary = NULL;\r
- FullBinary = NULL;\r
- DataBase = NULL;\r
- DeltaVarStoreHeader = NULL;\r
- PreVarDataBinary = NULL;\r
- PreVarDataSize = 0;\r
- DeltaSize = 0;\r
- Size = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER);\r
- VarDataBinary = NULL;\r
-\r
- //\r
- // Check whether the FD has included the storage FFS\r
- //\r
- //if (!mMultiPlatformParam.ExistStorageFfsInBfv) {\r
- // return EFI_ABORTED;\r
- //}\r
- NvStoreHeader = (PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)gEfiFdInfo.NvStoreDatabase;\r
- BinaryLength = NvStoreHeader->Length;\r
- Binary = (UINT8 *)gEfiFdInfo.NvStoreDatabase;\r
- //\r
- // If detect size optimized format, transfer it to normal format\r
- // before parse it\r
- //\r
- if (mMultiPlatformParam.SizeOptimized) {\r
- FullBinary = calloc(gEfiFdInfo.FdSize, sizeof(UINT8));\r
- if (FullBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- }\r
- while (Size < BinaryLength) {\r
- DataBase = Binary + Size;\r
- DataSize = *(UINT32 *)DataBase;\r
- if (Size == sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
- PrePcdDefaultData = (PCD_DEFAULT_DATA *) DataBase;\r
- HeaderSize = PrePcdDefaultData->HeaderSize;\r
- PreVarDataSize = DataSize - 4 - HeaderSize;\r
- VarDataBinary = malloc(DataSize);\r
- if (VarDataBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- memcpy (VarDataBinary, DataBase, DataSize);\r
- PreVarDataBinary = malloc(DataSize - 4 - HeaderSize);\r
- if (PreVarDataBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- memcpy (PreVarDataBinary, DataBase + 4 + HeaderSize , DataSize - 4 - HeaderSize);\r
- } else {\r
- DeltaVarStoreHeader = (PCD_DEFAULT_DATA *)DataBase;\r
- DeltaSize = DeltaVarStoreHeader->DataSize;\r
- HeaderSize = DeltaVarStoreHeader->HeaderSize;\r
- DeltaData = (UINT8*) DeltaVarStoreHeader;\r
-\r
- VarDataBinary = malloc(PreVarDataSize + HeaderSize + 4);\r
- if (VarDataBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Copy the default setting data\r
- //\r
- memcpy (VarDataBinary, DataBase, HeaderSize + 4);\r
- memcpy (VarDataBinary + HeaderSize + 4, PreVarDataBinary, PreVarDataSize);\r
- //\r
- // Merge the delta data with default setting to get the full delta data\r
- //\r
- for (Index = 0; Index < (DeltaSize - HeaderSize - 4)/sizeof(PCD_DATA_DELTA); Index++) {\r
- Offset = ((PCD_DATA_DELTA *)(DeltaData + HeaderSize + 4 + Index * sizeof(PCD_DATA_DELTA)))->Offset;\r
- Value = ((PCD_DATA_DELTA *)(DeltaData + HeaderSize + 4 + Index * sizeof(PCD_DATA_DELTA)))->Value;\r
- if (*(VarDataBinary + HeaderSize + 4 + Offset) != Value) {\r
- *(VarDataBinary + HeaderSize + 4 + Offset) = (UINT8)Value;\r
- }\r
- }\r
- }\r
- //\r
- // Store the Variable Data to VarListEntry\r
- //\r
-\r
- ReadNvStoreVariableToList(VarDataBinary, VarListEntry);\r
- Size += (DataSize + 7) & ~7;\r
- }\r
-\r
- if (VarDataBinary != NULL) {\r
- free (VarDataBinary);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read FFS from BFV and insert it to the Storage list.\r
-\r
- @param InputFdName The pointer to the input fd name.\r
- @param VarListEntry The pointer to the variable list.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-ReadStorageFromBfv (\r
- IN LIST_ENTRY *VarListEntry\r
-)\r
-{\r
-\r
- UINT8 *Binary;\r
- UINT8 *FullBinary;\r
- UINT8 *DataBase;\r
- UINT8 *PreVarStoreHeader;\r
- DATA_DELTA *DeltaVarStoreHeader;\r
- UINT8 *DeltaData;\r
- UINT32 PreDataSize;\r
- UINT32 DeltaSize;\r
- UINT32 BinaryLength;\r
- UINT32 Size;\r
- UINT32 SectionSize;\r
- UINT32 FullSectionLen;\r
- UINT32 FullSectionSize;\r
- EFI_FFS_FILE_HEADER *FfsHeader;\r
- UINT16 Offset;\r
- UINT8 Value;\r
- UINT32 Index;\r
- CHAR8 *SectionName;\r
-\r
- BinaryLength = 0;\r
- Binary = NULL;\r
- FullBinary = NULL;\r
- DataBase = NULL;\r
- PreVarStoreHeader = NULL;\r
- DeltaVarStoreHeader = NULL;\r
- PreDataSize = 0;\r
- DeltaSize = 0;\r
- FullSectionSize = 0;\r
- Size = sizeof (EFI_FFS_FILE_HEADER);\r
- FfsHeader = NULL;\r
- FullSectionLen = 0;\r
- SectionName = NULL;\r
-\r
- SectionName = getcwd(NULL, _MAX_PATH);\r
- if (strlen (SectionName) + 2 * strlen (OS_SEP_STR) + strlen ("Temp") + strlen ("TempSection.sec") >\r
- _MAX_PATH - 1) {\r
- printf ("Error. The current path is too long.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- sprintf (SectionName + strlen (SectionName), "%cTemp%cTempSection.sec", OS_SEP, OS_SEP);\r
- //\r
- // Check whether the FD has included the storage FFS\r
- //\r
- if (!mMultiPlatformParam.ExistStorageFfsInBfv) {\r
- return EFI_ABORTED;\r
- }\r
- FfsHeader = (EFI_FFS_FILE_HEADER *)gEfiFdInfo.StorageFfsInBfv;\r
- BinaryLength = FvBufExpand3ByteSize (FfsHeader->Size);\r
- Binary = (UINT8 *)FfsHeader;\r
- //\r
- // If detect size optimized format, transfer it to normal format\r
- // before parse it\r
- //\r
- if (mMultiPlatformParam.SizeOptimized) {\r
- FullBinary = calloc(gEfiFdInfo.FdSize, sizeof(UINT8));\r
- if (FullBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- return EFI_ABORTED;\r
- }\r
- while (Size < BinaryLength) {\r
- SectionSize = FvBufExpand3ByteSize (((EFI_COMMON_SECTION_HEADER *)(Binary + Size))->Size);\r
- DataBase = Binary + Size + sizeof (EFI_COMMON_SECTION_HEADER);\r
- if (Size == sizeof (EFI_FFS_FILE_HEADER)) {\r
- PreVarStoreHeader = DataBase + *(UINT16 *)DataBase;\r
- PreDataSize = SectionSize - (*(UINT16 *)DataBase + sizeof(EFI_COMMON_SECTION_HEADER));\r
- memcpy (FullBinary, DataBase, SectionSize - sizeof(EFI_COMMON_SECTION_HEADER));\r
- FullSectionLen = CreateStorageSection (FullBinary, *(UINT16 *)DataBase + PreDataSize, SectionName);\r
- } else {\r
- DeltaVarStoreHeader = (DATA_DELTA *)(DataBase + *(UINT16 *)DataBase);\r
- DeltaSize = *(UINT16 *)DataBase + PreDataSize;\r
- DeltaData = FullBinary + FullSectionSize + *(UINT16 *)DataBase;\r
- //\r
- // Copy the DefaultId and PlatformId directly\r
- //\r
- memcpy (FullBinary + FullSectionSize, DataBase, *(UINT16 *)DataBase);\r
- //\r
- // Copy the default setting data\r
- //\r
- memcpy (DeltaData, PreVarStoreHeader, PreDataSize);\r
- //\r
- // Merge the delta data with default setting to get the full delta data\r
- //\r
- for (Index = 0; Index < (SectionSize - *(UINT16 *)DataBase - sizeof(EFI_COMMON_SECTION_HEADER))/sizeof(DATA_DELTA); Index++) {\r
- Offset = (DeltaVarStoreHeader + Index)->Offset;\r
- Value = (DeltaVarStoreHeader + Index)->Value;\r
- if (*(DeltaData + Offset) != Value) {\r
- *(DeltaData + Offset) = Value;\r
- }\r
- }\r
- FullSectionLen = CreateStorageSection (FullBinary + FullSectionSize, DeltaSize, SectionName);\r
- }\r
- //\r
- // Store the previous binary information\r
- //\r
- DataBase = FullBinary + FullSectionSize + sizeof (EFI_COMMON_SECTION_HEADER);\r
- PreVarStoreHeader = DataBase + *(UINT16 *)DataBase;\r
-\r
- Size += (SectionSize + 3) & ~3;\r
- FullSectionSize += (FullSectionLen + 3) & ~3;;\r
- }\r
- //\r
- // Update to the new size\r
- //\r
- BinaryLength = FullSectionSize;\r
- Binary = FullBinary;\r
- Size = 0;\r
- }\r
-\r
- //\r
- // Read the storage from BFV and insert to storage list\r
- //\r
- while (Size < BinaryLength) {\r
- SectionSize = ReadStorageFromBinary ((Binary + Size), VarListEntry);\r
- Size += (SectionSize + 3) & ~3;\r
- }\r
- if (FullBinary != NULL) {\r
- free (FullBinary);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-#define SIZE_64K 0x10000\r
-\r
-/**\r
- Create the storage and insert it to BFV by calling BfmLib.\r
-\r
- @param InputFdName The pointer to the input fd name.\r
- @param OutputFdName The pointer to the input fd name.\r
- @param VarListEntry The pointer to the variable list.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-InsertBinaryToBfv (\r
- IN CHAR8 *InputFdName,\r
- IN CHAR8 *OutputFdName,\r
- IN LIST_ENTRY *VarListEntry\r
-)\r
-{\r
- UINT8 *Binary;\r
- UINT8 *PreBinary;\r
- UINT32 BinaryLength;\r
- UINT32 PreBinaryLength;\r
- UINT32 OptimizedBinaryLength;\r
- UINT32 Size;\r
- UINT32 OptimizedSize;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- CHAR8 *SystemCommandFormatString;\r
- CHAR8 *SectionNameFormatString;\r
- CHAR8 *SystemCommand;\r
- CHAR8 *TempSystemCommand;\r
- INT32 ReturnValue;\r
- CHAR8 *FileName;\r
- BOOLEAN SizeOptimizedFlag;\r
- CHAR8 *SectionName[_MAXIMUM_SECTION_FILE_NUM];\r
- UINT32 Index;\r
- CHAR8 *TemDir;\r
- //\r
- // Workaround for static code checkers.\r
- // Ensures the size of 'IndexStr' can hold all the digits of an unsigned\r
- // 32-bit integer.\r
- //\r
- CHAR8 IndexStr[16];\r
-\r
- BinaryLength = 0;\r
- PreBinaryLength = 0;\r
- Storage = NULL;\r
- StorageLink = NULL;\r
- Binary = NULL;\r
- PreBinary = NULL;\r
- Size = 0;\r
- OptimizedSize = 0;\r
- Status = EFI_SUCCESS;\r
- SystemCommandFormatString = NULL;\r
- SectionNameFormatString = NULL;\r
- SystemCommand = NULL;\r
- TempSystemCommand = NULL;\r
- SizeOptimizedFlag = FALSE;\r
- Index = 0;\r
- FileName = NULL;\r
-\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- SectionNameFormatString = "%s%cTemp%c%s.sec";\r
-\r
- memset (SectionName, 0, _MAXIMUM_SECTION_FILE_NUM * sizeof(CHAR8 *));\r
- FileName = malloc (strlen (TemDir) + 1 + strlen ("Storage.ffs") + 1);\r
- if (FileName == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (FileName, "%s%cStorage.ffs", TemDir, OS_SEP);\r
- //\r
- // Allocate the buffer which is the same with the input FD\r
- //\r
- Binary = malloc (SIZE_64K);\r
- if (Binary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- PreBinary = malloc (SIZE_64K);\r
- if (PreBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //\r
- // If already existed a Storage.ffs in FD, keep the same format when execute update operation whatever input -a or not -a options.\r
- //\r
- if (mMultiPlatformParam.SizeOptimized\r
- || (!mMultiPlatformParam.ExistStorageFfsInBfv && mMultiPlatformParam.SizeOptimizedParam)\r
- ) {\r
- SizeOptimizedFlag = TRUE;\r
- } else if (mMultiPlatformParam.ExistStorageFfsInBfv && mMultiPlatformParam.SizeOptimizedParam && !mMultiPlatformParam.SizeOptimized) {\r
- printf ("\nWarning. The \"-a\" parameter is ignored.\n");\r
- }\r
- //\r
- // Build the binary for BFV\r
- //\r
- StorageLink = GetFirstNode (VarListEntry);\r
-\r
- while (!IsNull (VarListEntry, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if (!Storage->Skip) {\r
- //\r
- // Assign the section name under the Temp directory\r
- //\r
- sprintf (IndexStr, "%d", Index);\r
- SectionName[Index] = calloc (\r
- strlen (SectionNameFormatString) + strlen (TemDir) + strlen(IndexStr) + 1,\r
- sizeof(CHAR8)\r
- );\r
- if (SectionName[Index] == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (\r
- SectionName[Index],\r
- "%s%cTemp%c%s.sec",\r
- TemDir,\r
- OS_SEP,\r
- OS_SEP,\r
- IndexStr\r
- );\r
- memset(Binary, 0, SIZE_64K);\r
- Size = PutStorageToBinary (Storage, Binary, VarListEntry);\r
- assert (Size < SIZE_64K);\r
- //\r
- // Re-calculate the storage section by size optimization\r
- //\r
- if (PreBinaryLength != 0 && SizeOptimizedFlag) {\r
- OptimizedSize = OptimizeStorageSection (\r
- PreBinary + sizeof (EFI_COMMON_SECTION_HEADER),\r
- Binary,\r
- PreBinary + PreBinaryLength,\r
- Size\r
- );\r
- if (OptimizedSize == 0) {\r
- printf ("Error. Failed to optimize the storage section.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- }\r
- //\r
- // Create the raw section with normal format\r
- //\r
- assert (Size < SIZE_64K - sizeof (EFI_COMMON_SECTION_HEADER));\r
- BinaryLength = CreateStorageSection (Binary, Size, SectionName[Index]);\r
- if (BinaryLength == 0) {\r
- printf ("Error. Failed to create the storage section.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- assert (BinaryLength < SIZE_64K);\r
-\r
- //\r
- // Create the raw section with optimized format\r
- //\r
- if (PreBinaryLength != 0 && SizeOptimizedFlag) {\r
- OptimizedBinaryLength = CreateStorageSection (PreBinary + PreBinaryLength, OptimizedSize, SectionName[Index]);\r
- if (OptimizedBinaryLength == 0) {\r
- printf ("Error. Failed to create the storage section.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- }\r
- PreBinaryLength = BinaryLength;\r
- memcpy (PreBinary, Binary, PreBinaryLength);\r
- Index++;\r
- }\r
- StorageLink = GetNextNode (VarListEntry, StorageLink);\r
- }\r
- //\r
- // Create the raw ffs by GenFfs\r
- //\r
- CreateRawFfs (&SectionName[0], FileName, SizeOptimizedFlag);\r
-\r
- //\r
- // Call BfmLib to insert this binary into the BFV of FD.\r
- //\r
- //\r
- // Construction 'system' command string\r
- //\r
- if (mMultiPlatformParam.ExistStorageFfsInBfv) {\r
- if (mFvNameGuidString != NULL) {\r
- SystemCommandFormatString = "BfmLib -r \"%s\" \"%s\" \"%s\" -g %s";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (mInputFdName) + strlen (mOutputFdName) + strlen (FileName) + strlen (mFvNameGuidString) + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -r \"%s\" \"%s\" \"%s\" -g %s",\r
- mInputFdName,\r
- FileName,\r
- mOutputFdName,\r
- mFvNameGuidString\r
- );\r
- } else {\r
- SystemCommandFormatString = "BfmLib -r \"%s\" \"%s\" \"%s\"";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (mInputFdName) + strlen (mOutputFdName) + strlen (FileName) + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -r \"%s\" \"%s\" \"%s\"",\r
- mInputFdName,\r
- FileName,\r
- mOutputFdName\r
- );\r
- }\r
- } else {\r
- if (mFvNameGuidString != NULL) {\r
- SystemCommandFormatString = "BfmLib -i \"%s\" \"%s\" \"%s\" -g %s";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (mInputFdName) + strlen (mOutputFdName) + strlen (FileName) + strlen (mFvNameGuidString) + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -i \"%s\" \"%s\" \"%s\" -g %s",\r
- mInputFdName,\r
- FileName,\r
- mOutputFdName,\r
- mFvNameGuidString\r
- );\r
- } else {\r
- SystemCommandFormatString = "BfmLib -i \"%s\" \"%s\" \"%s\"";\r
- SystemCommand = malloc (\r
- strlen (SystemCommandFormatString) + strlen (mInputFdName) + strlen (mOutputFdName) + strlen (FileName) + 1\r
- );\r
- if (SystemCommand == NULL) {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- sprintf (\r
- SystemCommand,\r
- "BfmLib -i \"%s\" \"%s\" \"%s\"",\r
- mInputFdName,\r
- FileName,\r
- mOutputFdName\r
- );\r
- }\r
- }\r
-\r
- if (mFullGuidToolDefinitionDir[0] != 0) {\r
- TempSystemCommand = SystemCommand;\r
- SystemCommand = malloc (\r
- strlen (mFullGuidToolDefinitionDir) + strlen ("\\") + strlen (TempSystemCommand ) + 1\r
- );\r
-\r
- if (SystemCommand == NULL) {\r
- free (TempSystemCommand);\r
- goto Done;\r
- }\r
- strcpy (SystemCommand, mFullGuidToolDefinitionDir);\r
- strcat (SystemCommand, OS_SEP_STR);\r
- strcat (SystemCommand, TempSystemCommand);\r
- free (TempSystemCommand);\r
- }\r
-\r
- ReturnValue = system (SystemCommand);\r
- free (SystemCommand);\r
- remove (FileName);\r
- if (ReturnValue == -1) {\r
- Status = EFI_ABORTED;\r
- }\r
-Done:\r
- for (Index = 0; SectionName[Index] != NULL; Index++) {\r
- free (SectionName[Index]);\r
- }\r
- if (PreBinary != NULL) {\r
- free (PreBinary);\r
- }\r
- if (Binary) {\r
- free (Binary);\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Create the storage and insert it to NvStoreDatabase.\r
-\r
- @param InputFdName The pointer to the input fd name.\r
- @param OutputFdName The pointer to the input fd name.\r
- @param VarListEntry The pointer to the variable list.\r
-\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-InsertBinaryToNvStoreDatabase (\r
- IN CHAR8 *InputFdName,\r
- IN CHAR8 *OutputFdName,\r
- IN LIST_ENTRY *VarListEntry\r
-)\r
-{\r
- UINT8 *Binary;\r
- UINT8 *PreBinary;\r
- UINT8 *NvStoreDatabaseBuffer;\r
- UINT32 PreBinaryLength;\r
- UINT32 Size;\r
- UINT32 NvStoreDatabaseSize;\r
- UINT32 OptimizedSize;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- BOOLEAN SizeOptimizedFlag;\r
- PCD_NV_STORE_DEFAULT_BUFFER_HEADER *NvStoreBufferHeader;\r
- PCD_DEFAULT_DATA *PcdDefaultData;\r
-\r
- //\r
- // Workaround for static code checkers.\r
- // Ensures the size of 'IndexStr' can hold all the digits of an unsigned\r
- // 32-bit integer.\r
- //\r
-\r
- PreBinaryLength = 0;\r
- Storage = NULL;\r
- StorageLink = NULL;\r
- Binary = NULL;\r
- PreBinary = NULL;\r
- NvStoreDatabaseBuffer = NULL;\r
- PcdDefaultData = NULL;\r
- Size = 0;\r
- NvStoreDatabaseSize = 0;\r
- OptimizedSize = 0;\r
- Status = EFI_SUCCESS;\r
- SizeOptimizedFlag = FALSE;\r
-\r
- //\r
- // Allocate the buffer which is the same with the input FD\r
- //\r
-\r
- Binary = malloc (SIZE_64K);\r
- if (Binary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- NvStoreBufferHeader = (PCD_NV_STORE_DEFAULT_BUFFER_HEADER *) gEfiFdInfo.NvStoreDatabase;\r
- NvStoreDatabaseBuffer = malloc (NvStoreBufferHeader->MaxLength);\r
- if (NvStoreDatabaseBuffer == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- memcpy(NvStoreDatabaseBuffer, gEfiFdInfo.NvStoreDatabase, NvStoreBufferHeader->MaxLength);\r
- PreBinary = malloc (SIZE_64K);\r
- if (PreBinary == NULL) {\r
- printf ("Error. Memory allocation failed.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
-\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- SizeOptimizedFlag = TRUE;\r
- } else {\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //\r
- // Build the binary for BFV\r
- //\r
- StorageLink = GetFirstNode (VarListEntry);\r
- while (!IsNull (VarListEntry, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if (!Storage->Skip) {\r
- memset(Binary, 0, SIZE_64K);\r
- Size = PutStorageToNvStoreBinary (Storage, Binary, VarListEntry);\r
- assert (Size < SIZE_64K);\r
- //\r
- // Re-calculate the storage section by size optimization\r
- //\r
- if (PreBinaryLength != 0 && SizeOptimizedFlag) {\r
- OptimizedSize = OptimizeStorageDeltaData (\r
- PreBinary,\r
- Binary,\r
- NvStoreDatabaseBuffer + NvStoreDatabaseSize,\r
- Size\r
- );\r
- if (OptimizedSize == 0) {\r
- printf ("Error. Failed to optimize the storage section.\n");\r
- Status = EFI_ABORTED;\r
- goto Done;\r
- }\r
- //Alignment\r
- OptimizedSize = (OptimizedSize + 7) & ~7;\r
- NvStoreDatabaseSize += OptimizedSize;\r
- } else {\r
- //Alignment\r
- Size = (Size + 7) & ~7;\r
- PcdDefaultData = (PCD_DEFAULT_DATA *)Binary;\r
- memcpy(NvStoreDatabaseBuffer + sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER), Binary, Size + PcdDefaultData->HeaderSize + 4 );\r
- PreBinaryLength = Size + PcdDefaultData->HeaderSize + 4;\r
- NvStoreDatabaseSize = sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + PreBinaryLength;\r
- memcpy(PreBinary, Binary, PreBinaryLength);\r
- }\r
- }\r
- StorageLink = GetNextNode (VarListEntry, StorageLink);\r
- }\r
- if (NvStoreBufferHeader->Length != NvStoreDatabaseSize) {\r
- ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)NvStoreDatabaseBuffer)->Length = NvStoreDatabaseSize;\r
- }\r
- memcpy(gEfiFdInfo.NvStoreDatabase, NvStoreDatabaseBuffer, NvStoreDatabaseSize);\r
-\r
-Done:\r
- DestroyAllStorage (&mAllVarListEntry);\r
- if (PreBinary != NULL) {\r
- free (PreBinary);\r
- }\r
- if (Binary) {\r
- free (Binary);\r
- }\r
- return Status;\r
-}\r
-\r
-extern UINT32 mMaxCount;\r
-extern UINT32 mCount;\r
-extern CHAR8 *mStringBuffer;\r
-\r
-/**\r
- Read the HII configure file from all FFS\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-ReadCongFile (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT16 DefaultIndex;\r
- UINT16 PlatformIndex;\r
- UINT16 PreDefaultId;\r
- UINT64 PrePlatformId;\r
- LIST_ENTRY NewStorageListHead;\r
- BOOLEAN BfvOverried;\r
- FORMSET_STORAGE *Storage;\r
- LIST_ENTRY *StorageLink;\r
-\r
- Storage = NULL;\r
- Status = EFI_SUCCESS;\r
- BfvOverried = FALSE;\r
- Index = 0;\r
- PreDefaultId = 0xFFFF;\r
- PrePlatformId = 0xFFFFFFFFFFFFFFFF;\r
- //\r
- // Read all Ifr information to Formset list\r
- //\r
- for (Index = 0; (gEfiFdInfo.FfsArray[Index] != NULL) && (gEfiFdInfo.Length[Index] != 0); Index++) {\r
- Status = ReadAllIfrToFromset (\r
- gEfiFdInfo.FfsArray[Index],\r
- gEfiFdInfo.Length[Index]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Read defaultId and platformId\r
- //\r
- if (!gEfiFdInfo.ExistNvStoreDatabase) {\r
- Status = ReadDefaultAndPlatformId (&mFormSetListEntry);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // If existed the variable data in BFV, abstract them to a variable list.\r
- // If not exsited, just skip it.\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- Status = ReadStorageFromNvStoreDatabase(&mBfvVarListEntry);\r
- } else {\r
- Status = ReadStorageFromBfv (&mBfvVarListEntry);\r
- }\r
- if (!EFI_ERROR (Status)) {\r
- BfvOverried = TRUE;\r
- }\r
- }\r
- //\r
- // If not existed the storage data in BFV, evaluate the\r
- // default value according to the defaultId and platformId\r
- // Or else, skip it.\r
- //\r
- if (!BfvOverried) {\r
- Status = EvaluateTheValueInFormset (FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- //\r
- // Output the question and value information on screen\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // Multi-platform mode support\r
- //\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- StorageLink = GetFirstNode (&mBfvVarListEntry);\r
- while (!IsNull (&mBfvVarListEntry, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- if (PreDefaultId == Storage->DefaultId[0] && PrePlatformId == Storage->PlatformId[0]) {\r
- StorageLink = GetNextNode (&mBfvVarListEntry, StorageLink);\r
- continue;\r
- } else {\r
- PreDefaultId = Storage->DefaultId[0];\r
- PrePlatformId = Storage->PlatformId[0];\r
- }\r
- InitializeListHead(&NewStorageListHead);\r
- //\r
- // Use the varaible stroage list from BFV\r
- //\r
- Status = BuildVariableList(\r
- &NewStorageListHead,\r
- &mBfvVarListEntry,\r
- Storage->DefaultId[0],\r
- Storage->PlatformId[0],\r
- FALSE,\r
- READ\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DestroyAllStorage (&NewStorageListHead);\r
- return EFI_ABORTED;\r
- }\r
- if (IsListEmpty (&NewStorageListHead)) {\r
- continue;\r
- }\r
- Status = PrintInfoInAllFormset (&mFormSetListEntry, &NewStorageListHead);\r
- if (EFI_ERROR (Status)) {\r
- DestroyAllStorage (&NewStorageListHead);\r
- return EFI_ABORTED;\r
- }\r
- DestroyAllStorage (&NewStorageListHead);\r
- StorageLink = GetNextNode (&mBfvVarListEntry, StorageLink);\r
- }\r
- } else {\r
- for (DefaultIndex = 0; DefaultIndex < mMultiPlatformParam.DefaultIdNum; DefaultIndex++) {\r
- for (PlatformIndex = 0; PlatformIndex < mMultiPlatformParam.PlatformIdNum; PlatformIndex++) {\r
- InitializeListHead(&NewStorageListHead);\r
- if (BfvOverried) {\r
- //\r
- // Use the varaible stroage list from BFV\r
- //\r
- Status = BuildVariableList(\r
- &NewStorageListHead,\r
- &mBfvVarListEntry,\r
- mMultiPlatformParam.DefaultId[DefaultIndex],\r
- mMultiPlatformParam.PlatformId[PlatformIndex],\r
- FALSE,\r
- READ\r
- );\r
- } else {\r
- //\r
- // Use the varaible storage list from IFR\r
- //\r
- Status = BuildVariableList(\r
- &NewStorageListHead,\r
- &mAllVarListEntry,\r
- mMultiPlatformParam.DefaultId[DefaultIndex],\r
- mMultiPlatformParam.PlatformId[PlatformIndex],\r
- FALSE,\r
- READ\r
- );\r
- }\r
- if (EFI_ERROR (Status)) {\r
- DestroyAllStorage (&NewStorageListHead);\r
- return EFI_ABORTED;\r
- }\r
- if (IsListEmpty (&NewStorageListHead)) {\r
- continue;\r
- }\r
- Status = PrintInfoInAllFormset (&mFormSetListEntry, &NewStorageListHead);\r
- if (EFI_ERROR (Status)) {\r
- DestroyAllStorage (&NewStorageListHead);\r
- return EFI_ABORTED;\r
- }\r
- DestroyAllStorage (&NewStorageListHead);\r
- }\r
- }\r
- }\r
- } else {\r
- Status = PrintInfoInAllFormset (&mFormSetListEntry, &mAllVarListEntry);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Update the HII setup value.\r
-\r
- Read the Config information from config file, and then compare it with the current FFS.\r
- Record the different value to EFI variable.\r
-\r
- @param Fv the Pointer to the FFS\r
- @param Length the length of FFS\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-UpdateCongFile (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- BOOLEAN BfvOverried;\r
-\r
- Status = EFI_SUCCESS;\r
- BfvOverried = FALSE;\r
- Index = 0;\r
- //\r
- // Read all Ifr information to Formset list\r
- //\r
- for (Index = 0; (gEfiFdInfo.FfsArray[Index] != NULL) && (gEfiFdInfo.Length[Index] != 0); Index++) {\r
- Status = ReadAllIfrToFromset (\r
- gEfiFdInfo.FfsArray[Index],\r
- gEfiFdInfo.Length[Index]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Read defaultId and platformId\r
- //\r
- if (!gEfiFdInfo.ExistNvStoreDatabase) {\r
- Status = ReadDefaultAndPlatformId (&mFormSetListEntry);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // If existed the variable data in BFV, abstract them to a variable list.\r
- // If not exsited, just skip it.\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- Status = ReadStorageFromNvStoreDatabase (&mBfvVarListEntry);\r
- } else {\r
- Status = ReadStorageFromBfv (&mBfvVarListEntry);\r
- }\r
- if (!EFI_ERROR (Status)) {\r
- BfvOverried = TRUE;\r
- }\r
- }\r
- if (mMultiPlatformParam.MultiPlatformOrNot && BfvOverried) {\r
- if (mUqiList == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
- Status = CheckValueUpdateList ();\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- //\r
- // Evaluate the default value according to the defaultId and platformId\r
- //\r
- if (mUqiList == NULL) {\r
- Status = EvaluateTheValueInFormset (FALSE);\r
- } else {\r
- Status = EvaluateTheValueInFormset (TRUE);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // print error information in UQI list\r
- //\r
- if (PrintErrorInfo (mUqiList)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Output the variable information to BFV in multi-platform mode\r
- // Or write it to the Nvstrage in general mode\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- if (ExistEfiVarOrNot (&mAllVarListEntry) && Operations == UPDATE) {\r
- printf ("Error. Please use --remove or --ignore to update the variable storage for an FD with variables in its NvStorage.\n");\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- //\r
- // Sync the data from List data to efi variable.\r
- //\r
- Status = EfiVarAndListExchange (FALSE, &mAllVarListEntry);\r
- if (Status == EFI_OUT_OF_RESOURCES) {\r
- printf ("Error. There is no available space in efi variable. \n");\r
- return EFI_ABORTED;\r
- }\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- PrintUpdateListInfo (mUqiList);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Quick Update the HII setup value.\r
-\r
- Read the Config information from command line directly, and then compare it with the current FFS.\r
- Record the different value to EFI variable.\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-\r
-EFI_STATUS\r
-QuickUpdateCongFile (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
-\r
- Status = EFI_SUCCESS;\r
- Index = 0;\r
-\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- printf ("Error. The quick update operation is not supported in multi-platform mode.\n");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Check whether the FD has included the storage FFS\r
- //\r
- if (mMultiPlatformParam.ExistStorageFfsInBfv) {\r
- printf ("Error. Variable storage exists in BFV of Fd. This is generated in multi-platform mode.\n");\r
- printf ("Error. The quick update operation is not supported in multi-platform mode.\n");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Read all Ifr information to Formset list\r
- //\r
- for (Index = 0; (gEfiFdInfo.FfsArray[Index] != NULL) && (gEfiFdInfo.Length[Index] != 0); Index++) {\r
- Status = ReadAllIfrToFromset (\r
- gEfiFdInfo.FfsArray[Index],\r
- gEfiFdInfo.Length[Index]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Evaluate the default value according to the defaultId and platformId\r
- //\r
- Status = EvaluateTheValueInFormset (TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // print error information in UQI list\r
- //\r
- if (PrintErrorInfo (mUqiList)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Sync the data from mAllVarListEntry data to efi variable.\r
- //\r
- Status = EfiVarAndListExchange (FALSE, &mAllVarListEntry);\r
- if (Status == EFI_OUT_OF_RESOURCES) {\r
- printf ("Error. There is no available space in Nvstorage. \n");\r
- return EFI_ABORTED;\r
- }\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- PrintUpdateListInfo (mUqiList);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Check the HII setup value.\r
-\r
- Read the Config information from config file, and then compare it with the current FFS.\r
- Print the different values on screen.\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-static\r
-EFI_STATUS\r
-CheckCongFile (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT16 DefaultIndex;\r
- UINT16 PlatformIndex;\r
- UINT16 DefaultId;\r
- UINT64 PlatformId;\r
-\r
- Status = EFI_SUCCESS;\r
- Index = 0;\r
- DefaultIndex = 0;\r
- PlatformIndex = 0;\r
- DefaultId = 0;\r
- PlatformId = 0;\r
- //\r
- // Read all Ifr information to Formset list\r
- //\r
- for (Index = 0; (gEfiFdInfo.FfsArray[Index] != NULL) && (gEfiFdInfo.Length[Index] != 0); Index++) {\r
- Status = ReadAllIfrToFromset (\r
- gEfiFdInfo.FfsArray[Index],\r
- gEfiFdInfo.Length[Index]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Read defaultId and platformId\r
- //\r
- Status = ReadDefaultAndPlatformId (&mFormSetListEntry);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Read the config data from BFV in multi-platform mode\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- Status = ReadStorageFromBfv (&mAllVarListEntry);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error. No storage variable data exists in BFV.\n");\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- ScanUqiFullList (mUqiList);\r
-\r
- //\r
- // Multi-platform mode support\r
- //\r
- for (DefaultIndex = 0; DefaultIndex < mMultiPlatformParam.DefaultIdNum; DefaultIndex++) {\r
- for (PlatformIndex = 0; PlatformIndex < mMultiPlatformParam.PlatformIdNum; PlatformIndex++) {\r
- DefaultId = mMultiPlatformParam.DefaultId[DefaultIndex];\r
- PlatformId = mMultiPlatformParam.PlatformId[PlatformIndex];\r
- //\r
- //Only parse one time, if a group of defaultId and platformId which have the same variable\r
- // Take the first one as a key Id of a group\r
- //\r
- if (NoTheKeyIdOfGroup (DefaultId, PlatformId)) {\r
- continue;\r
- }\r
-\r
- InitializeListHead(&mVarListEntry);\r
- Status = BuildVariableList(\r
- &mVarListEntry,\r
- &mAllVarListEntry,\r
- DefaultId,\r
- PlatformId,\r
- FALSE,\r
- VERIFY\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- if (IsListEmpty (&mVarListEntry)) {\r
- continue;\r
- }\r
- SetUqiParametersMultiMode (mUqiList, DefaultId, PlatformId);\r
- DestroyAllStorage (&mVarListEntry);\r
- }\r
- }\r
- } else {\r
- //\r
- // General mode\r
- //\r
- Status = ExtractDefault (\r
- NULL,\r
- NULL,\r
- 0,\r
- 0,\r
- SystemLevel\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // If existed the variable in NvStorage, copy them to mVarListEntry.\r
- // Synchronize the default value from the EFI variable zone to variable list\r
- //\r
- Status = EfiVarAndListExchange (TRUE, &mVarListEntry);\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- Status = EFI_ABORTED;\r
- return Status;\r
- }\r
- //\r
- // Update the value from script file\r
- //\r
- Status = SetUqiParameters (mUqiList,0, 0);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Copy Stroage from mVarListEntry to mAllVarListEntry\r
- //\r
- Status = BuildVariableList (&mAllVarListEntry, &mVarListEntry, 0, 0, TRUE, VERIFY);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- PrintVerifiedListInfo (mUqiList);\r
- return Status;\r
-}\r
-\r
-/**\r
- Search the config file from the path list.\r
-\r
- Split the path from env PATH, and then search the cofig\r
- file from these paths. The priority is from left to\r
- right of PATH string. When met the first Config file, it\r
- will break and return the pointer to the full file name.\r
-\r
- @param PathList the pointer to the path list.\r
- @param FileName the pointer to the file name.\r
-\r
- @retval The pointer to the file name.\r
- @return NULL An error occurred.\r
-**/\r
-CHAR8 *\r
-SearchConfigFromPathList (\r
- IN CHAR8 *PathList,\r
- IN CHAR8 *FileName\r
-)\r
-{\r
- CHAR8 *CurDir;\r
- CHAR8 *FileNamePath;\r
-\r
- CurDir = NULL;\r
- FileNamePath = NULL;\r
-#ifndef __GNUC__\r
- CurDir = strtok (PathList,";");\r
-#else\r
- CurDir = strtok (PathList,":");\r
-#endif\r
- while (CurDir != NULL) {\r
- FileNamePath = (char *)calloc(\r
- strlen (CurDir) + strlen (OS_SEP_STR) +strlen (FileName) + 1,\r
- sizeof(char)\r
- );\r
- if (FileNamePath == NULL) {\r
- return NULL;\r
- }\r
- sprintf(FileNamePath, "%s%c%s", CurDir, OS_SEP, FileName);\r
- if (access (FileNamePath, 0) != -1) {\r
- return FileNamePath;\r
- }\r
-#ifndef __GNUC__\r
- CurDir = strtok(NULL, ";");\r
-#else\r
- CurDir = strtok(NULL, ":");\r
-#endif\r
- free (FileNamePath);\r
- FileNamePath = NULL;\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- FCE application entry point\r
-\r
- @param argc The number of input parameters.\r
- @param *argv[] The array pointer to the parameters.\r
-\r
- @retval 0 The application exited normally.\r
- @retval 1 An error occurred.\r
- @retval 2 An error about check occurred.\r
-\r
-**/\r
-int\r
-main (\r
- int argc,\r
- char *argv[]\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FILE *OutputFd;\r
- FILE *ScriptFile;\r
- UINTN BytesWrite;\r
- UINTN Index;\r
- CHAR8 *TemDir;\r
- BOOLEAN IsFileExist;\r
- CHAR8 FullGuidToolDefinition[_MAX_PATH];\r
- CHAR8 *PathList;\r
- UINTN EnvLen;\r
- CHAR8 *NewPathList;\r
- UINTN FileNameIndex;\r
- CHAR8 *InFilePath;\r
- BOOLEAN UqiIsSet;\r
-\r
- Status = EFI_SUCCESS;\r
- OutputFd = NULL;\r
- ScriptFile = NULL;\r
- Operations = NONE;\r
- BytesWrite = 0;\r
- Index = 0;\r
- TemDir = NULL;\r
- mFormSetOrderRead = 0;\r
- mFormSetOrderParse = 0;\r
- IsFileExist = TRUE;\r
- PathList = NULL;\r
- NewPathList = NULL;\r
- EnvLen = 0;\r
- UqiIsSet = FALSE;\r
-\r
- TemDir = getcwd (NULL, _MAX_PATH);\r
- if (strlen (TemDir) + strlen (OS_SEP_STR) + strlen (TEMP_DIR_NAME) > _MAX_PATH - 1) {\r
- printf ("The directory is too long \n");\r
- return FAIL;\r
- }\r
- strncat (TemDir, OS_SEP_STR, _MAX_PATH - strlen (TemDir) - 1);\r
- strncat (TemDir, TEMP_DIR_NAME, _MAX_PATH - strlen (TemDir) - 1);\r
- memset (&mMultiPlatformParam, 0, sizeof (MULTI_PLATFORM_PARAMETERS));\r
-\r
- SetUtilityName (UTILITY_NAME);\r
- //\r
- // Workaroud: the first call to this function\r
- // returns a file name ends with dot\r
- //\r
-#ifndef __GNUC__\r
- tmpnam (NULL);\r
-#else\r
- CHAR8 tmp[] = "/tmp/fileXXXXXX";\r
- UINTN Fdtmp;\r
- Fdtmp = mkstemp(tmp);\r
- close(Fdtmp);\r
-#endif\r
- //\r
- // Save, and then skip filename arg\r
- //\r
- mUtilityFilename = argv[0];\r
- argc--;\r
- argv++;\r
- //\r
- // Get the same path with the application itself\r
- //\r
- if (strlen (mUtilityFilename) > _MAX_PATH - 1) {\r
- Error (NULL, 0, 2000, "Parameter: The input file name is too long", NULL);\r
- return FAIL;\r
- }\r
- strncpy (FullGuidToolDefinition, mUtilityFilename, _MAX_PATH - 1);\r
- FullGuidToolDefinition[_MAX_PATH - 1] = 0;\r
- FileNameIndex = strlen (FullGuidToolDefinition);\r
- while (FileNameIndex != 0) {\r
- FileNameIndex --;\r
- if (FullGuidToolDefinition[FileNameIndex] == OS_SEP) {\r
- FullGuidToolDefinition[FileNameIndex] = 0;\r
- strcpy (mFullGuidToolDefinitionDir, FullGuidToolDefinition);\r
- break;\r
- }\r
- }\r
- //\r
- // Build the path list for Config file scan. The priority is below.\r
- // 1. Scan the current path\r
- // 2. Scan the same path with the application itself\r
- // 3. Scan the current %PATH% of OS environment\r
- // 4. Use the build-in default configuration\r
- //\r
- PathList = getenv("PATH");\r
- if (PathList == NULL) {\r
- Error (NULL, 0, 1001, "Option: Environment variable 'PATH' does not exist", NULL);\r
- return FAIL;\r
- }\r
- EnvLen = strlen(PathList);\r
- NewPathList = (char *)calloc(\r
- strlen (".")\r
- + strlen (";")\r
- + strlen (mFullGuidToolDefinitionDir)\r
- + strlen (";")\r
- + EnvLen\r
- + 1,\r
- sizeof(char)\r
- );\r
- if (NewPathList == NULL) {\r
- Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
- PathList = NULL;\r
- free (PathList);\r
- return -1;\r
- }\r
-#ifndef __GNUC__\r
- sprintf (NewPathList, "%s;%s;%s", ".", mFullGuidToolDefinitionDir, PathList);\r
-#else\r
- sprintf (NewPathList, "%s:%s:%s", ".", mFullGuidToolDefinitionDir, PathList);\r
-#endif\r
-\r
- PathList = NULL;\r
- free (PathList);\r
-\r
- //\r
- // Load Guid Tools definition\r
- //\r
- InFilePath = SearchConfigFromPathList(NewPathList, mGuidToolDefinition);\r
- free (NewPathList);\r
- if (InFilePath != NULL) {\r
- printf ("\nThe Guid Tool Definition comes from the '%s'. \n", InFilePath);\r
- mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (InFilePath);\r
- free (InFilePath);\r
- } else {\r
- //\r
- // Use the pre-defined standard guided tools.\r
- //\r
- printf ("\nThe Guid Tool Definition comes from the build-in default configuration. \n");\r
- mParsedGuidedSectionTools = PreDefinedGuidedTools ();\r
- }\r
- //\r
- // Parse the command line\r
- //\r
- strcpy (mSetupTxtName, "NoSetupFile");\r
- Status = ParseCommmadLine (argc,argv);\r
- if (EFI_ERROR (Status)) {\r
- return FAIL;\r
- }\r
- //\r
- // Print utility header\r
- //\r
- printf ("\nIntel(R) Firmware Configuration Editor. (Intel(R) %s) Version %d.%d. %s.\n\n",\r
- UTILITY_NAME,\r
- UTILITY_MAJOR_VERSION,\r
- UTILITY_MINOR_VERSION,\r
- __BUILD_VERSION\r
- );\r
- //\r
- // Check the revision of BfmLib\r
- //\r
- Status = CheckBfmLibRevision ();\r
- if (EFI_ERROR (Status)) {\r
- printf ("Please use the correct revision of BfmLib %s. \n", __BUILD_VERSION);\r
- return FAIL;\r
- }\r
- if (strcmp (mSetupTxtName, "NoSetupFile")) {\r
- ScriptFile = fopen (mSetupTxtName, "r");\r
- if (ScriptFile == NULL) {\r
- printf ("Error. Cannot open the script file.\n");\r
- return FAIL;\r
- }\r
- Status = PickUpUqiFromScript (ScriptFile);\r
- if (EFI_ERROR (Status)) {\r
- fclose (ScriptFile);\r
- IsFileExist = FALSE;\r
- goto Done;\r
- }\r
- fclose (ScriptFile);\r
- }\r
- if (!mMultiPlatformParam.MultiPlatformOrNot\r
- && (Operations == UPDATE_REMOVE || Operations == UPDATE_IGNORE)\r
- ) {\r
- printf ("Error. --remove and --ignore cannot be used in normal mode.\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
-\r
- if (access (TemDir, 0) != -1) {\r
- LibRmDir (TemDir);\r
- }\r
-\r
- //\r
- // Initialize the variables\r
- //\r
- Status = PickUpFfsFromFd ();\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error. Invalid FD file.\n");\r
- IsFileExist = FALSE;\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- if (gEfiFdInfo.FfsArray[0] == NULL) {\r
- printf ("Error. Cannot find any HII offset in current FD files, please check the BaseTools.\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- //\r
- //Config the global variables\r
- //\r
- if (mMultiPlatformParam.Uqi.Data != NULL) {\r
- UqiIsSet = TRUE;\r
- }\r
- Status = GetEfiVariablesAddr (UqiIsSet);\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error. Cannot locate the EFI variable zone in FD.\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- if (gEfiFdInfo.ExistNvStoreDatabase && !mMultiPlatformParam.MultiPlatformOrNot) {\r
- mMultiPlatformParam.MultiPlatformOrNot = TRUE;\r
- }\r
- //\r
- // Initialize the FormSet and VarList List\r
- //\r
- InitializeListHead (&mFormSetListEntry);\r
- InitializeListHead (&mVarListEntry);\r
- InitializeListHead (&mBfvVarListEntry);\r
- InitializeListHead (&mAllVarListEntry);\r
-\r
- mStringBuffer = malloc (mMaxCount);\r
- if (mStringBuffer == NULL) {\r
- printf ("Fali to allocate memory!\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Decide how to deal with the Fd\r
- //\r
- switch (Operations) {\r
-\r
- case READ:\r
- printf ("\nStart the Read Mode:\n");\r
- Status = ReadCongFile ();\r
- if (EFI_ERROR (Status)) {\r
- Status = FAIL;\r
- }\r
- break;\r
-\r
- case UPDATE:\r
- case UPDATE_REMOVE:\r
- case UPDATE_IGNORE:\r
- printf ("\nStart the Update Mode:\n");\r
- Status = UpdateCongFile ();\r
- if (EFI_ERROR (Status)) {\r
- Status = FAIL;\r
- }\r
- break;\r
-\r
- case VERIFY:\r
- printf ("\nStart the Verify Mode:\n");\r
- Status = CheckCongFile ();\r
- if (EFI_ERROR (Status)) {\r
- Status = VR_FAIL;\r
- }\r
- break;\r
-\r
- case UPDATEQ:\r
- printf ("\nStart the Update Quick Mode:\n");\r
- Status = QuickUpdateCongFile ();\r
- if (EFI_ERROR (Status)) {\r
- Status = FAIL;\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- if (mCount > 0) {\r
- mStringBuffer[mCount] = '\0';\r
- fwrite (mStringBuffer, sizeof (CHAR8), mCount, stdout);\r
- }\r
- free (mStringBuffer);\r
-\r
- if (Status != SUCCESS) {\r
- goto Done;\r
- }\r
- //\r
- // If multi-platform mode, insert the variables to BFV\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot\r
- && (IsListEmpty (&mAllVarListEntry) == FALSE)\r
- &&((Operations == UPDATE) || (Operations == UPDATE_REMOVE) || (Operations == UPDATE_IGNORE) || (Operations == UPDATEQ))\r
- ) {\r
- IsFileExist = FALSE;\r
- if (gEfiFdInfo.ExistNvStoreDatabase) {\r
- Status = InsertBinaryToNvStoreDatabase (mInputFdName, mOutputFdName, &mAllVarListEntry);\r
- } else {\r
- Status = InsertBinaryToBfv (mInputFdName, mOutputFdName, &mAllVarListEntry);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- //\r
- // Remove the variables in NvStorage in multi-platform mode by user specified requirement\r
- //\r
- if (Operations == UPDATE_REMOVE) {\r
- if (gEfiFdInfo.Fd != NULL) {\r
- free (gEfiFdInfo.Fd);\r
- }\r
- gEfiFdInfo.Fd = ReadFileToMemory (mOutputFdName, &gEfiFdInfo.FdSize);\r
- if (gEfiFdInfo.Fd == NULL) {\r
- Status = EFI_ABORTED;\r
- } else {\r
- Status = RemoveEfiVar (&mAllVarListEntry);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- printf ("Error. Failed to remove the variable from NVRAM.\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
- if (\r
- (!mMultiPlatformParam.MultiPlatformOrNot &&((Operations == UPDATE) || (Operations == UPDATEQ)))\r
- || (mMultiPlatformParam.MultiPlatformOrNot && (Operations == UPDATE_REMOVE || ((Operations == UPDATE) && IsListEmpty (&mAllVarListEntry))))\r
- ) {\r
- OutputFd = fopen (mOutputFdName, "wb+");\r
- if (OutputFd == NULL) {\r
- printf ("Error. Failed to create the output FD file.\n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- fseek (OutputFd, 0, SEEK_SET);\r
- BytesWrite = fwrite (gEfiFdInfo.Fd, sizeof (CHAR8), gEfiFdInfo.FdSize, OutputFd);\r
- fclose (OutputFd);\r
- if (BytesWrite != gEfiFdInfo.FdSize) {\r
- printf ("Error. Failed to create the FD image. \n");\r
- Status = FAIL;\r
- goto Done;\r
- }\r
- }\r
- if ((Operations == UPDATE) || (Operations == UPDATE_REMOVE) || (Operations == UPDATE_IGNORE) || (Operations == UPDATEQ)) {\r
- printf ("\nCongratulations. The output Fd file '%s' has been completed successfully.\n", mOutputFdName);\r
- }\r
-Done:\r
- //\r
- // Delete the temporary directory and files\r
- //\r
- if (IsFileExist) {\r
- LibRmDir (TemDir);\r
- }\r
- //\r
- // Clean up\r
- //\r
- if (gEfiFdInfo.Fd != NULL) {\r
- free (gEfiFdInfo.Fd);\r
- }\r
-\r
- if (mMultiPlatformParam.Uqi.Value != NULL) {\r
- free (mMultiPlatformParam.Uqi.Value);\r
- }\r
- if (mMultiPlatformParam.Uqi.Data != NULL) {\r
- free (mMultiPlatformParam.Uqi.Data);\r
- }\r
- while (gEfiFdInfo.FfsArray[Index] != NULL) {\r
- free (gEfiFdInfo.FfsArray[Index++]);\r
- }\r
-\r
- DestroyAllFormSet (&mFormSetListEntry);\r
- DestroyAllStorage (&mVarListEntry);\r
- DestroyAllStorage (&mBfvVarListEntry);\r
- DestroyAllStorage (&mAllVarListEntry);\r
- FreeUnidirectionList (mUqiList);\r
-\r
- return Status;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- FCE is a tool which enables developers to retrieve and change HII configuration ("Setup")\r
- data in Firmware Device files (".fd" files).\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _FCE_H_\r
-#define _FCE_H_ 1\r
-\r
-//#define NDEBUG\r
-\r
-#include "Common.h"\r
-#include "IfrParse.h"\r
-#include "VariableCommon.h"\r
-#include "BinaryParse.h"\r
-#include "BinaryCreate.h"\r
-///\r
-/// Utility global variables\r
-///\r
-#define UTILITY_MAJOR_VERSION 0\r
-#define UTILITY_MINOR_VERSION 34\r
-\r
-#define UTILITY_NAME "FCE"\r
-\r
-#define SUCCESS 0\r
-#define FAIL 1\r
-#define VR_FAIL 2\r
-#define MAX_INPUT_ALLOCATE_SIZE 256\r
-\r
-///\r
-/// The type of file input and operations\r
-///\r
-typedef enum {\r
- INFD,\r
- OUTFD,\r
- OUTTXT,\r
- SETUPTXT\r
-} FILETYPE;\r
-\r
-typedef enum {\r
- NONE,\r
- READ,\r
- UPDATE,\r
- UPDATE_REMOVE,\r
- UPDATE_IGNORE,\r
- VERIFY,\r
- UPDATEQ\r
-} OPERATION_TYPE;\r
-\r
-typedef struct _GUID_SEC_TOOL_ENTRY {\r
- EFI_GUID Guid;\r
- CHAR8* Name;\r
- CHAR8* Path;\r
- struct _GUID_SEC_TOOL_ENTRY *Next;\r
-} GUID_SEC_TOOL_ENTRY;\r
-\r
-///\r
-/// The tag for use in identifying UNICODE files.\r
-/// If the file is UNICODE, the first 16 bits of the file will equal this value.\r
-///\r
-enum {\r
- BigUnicodeFileTag = 0xFEFF,\r
- LittleUnicodeFileTag = 0xFFFE\r
-};\r
-\r
-typedef enum {\r
- ASCII,\r
- BIG_UCS2,\r
- LITTLE_UCS2\r
-} FILE_TYPE;\r
-\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
- @retval EFI_INVALID_PARAMETER Invalid variable name.\r
-**/\r
-EFI_STATUS\r
-SynAuthEfiVariable (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveAuthEfiVariable (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the time stamp authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
- @retval EFI_INVALID_PARAMETER Invalid variable name.\r
-**/\r
-\r
-EFI_STATUS\r
-SynAuthEfiVariableBasedTime (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveAuthEfiVariableBasedTime (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
-**/\r
-\r
-EFI_STATUS\r
-SynEfiVariable (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveNormalEfiVariable (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Read all defaultId and platformId from binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-**/\r
-VOID\r
-ReadDefaultAndPlatformIdFromBfv (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-);\r
-\r
-/**\r
- Store all defaultId and platformId to binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-\r
- @retval Length Return the length of the header\r
-**/\r
-\r
-UINT32\r
-WriteDefaultAndPlatformId (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-);\r
-\r
-/**\r
- Store all defaultId and platformId to binary.\r
-\r
- @param Binary The pointer to the bianry\r
- @param Storage The pointer to the Storage\r
-\r
- @retval Length Return the length of the header\r
-**/\r
-UINT32\r
-WriteNvStoreDefaultAndPlatformId (\r
- IN UINT8 *Binary,\r
- IN FORMSET_STORAGE *Storage\r
-);\r
-\r
-/**\r
- Copy variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- );\r
-\r
-/**\r
- Copy variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyVariableToNvStoreBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- );\r
-\r
-\r
-/**\r
- Read variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-\r
-UINT32\r
-ReadNvStoreVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- );\r
-\r
-/**\r
- Read variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- );\r
-\r
-/**\r
- Check whether exists the valid normal variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistNormalEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Fix the size of variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- );\r
-\r
-/**\r
- Fix the size of variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-\r
-VOID\r
-FixNvStoreVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- );\r
-/**\r
- Copy time-based authenticated variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyTimeBasedVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- );\r
-\r
-/**\r
- Read time-based authenticated variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadTimeBasedVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- );\r
-\r
-/**\r
- Check whether exists the valid time-based variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistTimeBasedEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Fix the size of time-based variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixBasedTimeVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- );\r
-\r
-/**\r
- Copy Monotonic-Based authenticated variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyMonotonicBasedVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- );\r
-\r
-/**\r
- Read Monotonic-based authenticated variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadMonotonicBasedVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- );\r
-\r
-/**\r
- Check whether exists the valid MonotonicBased variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistMonotonicBasedEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- );\r
-\r
-/**\r
- Fix the size of montonic variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixMontonicVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- );\r
-\r
-/**\r
- FCE application entry point\r
-\r
- @param argc The number of input parameters.\r
- @param *argv[] The array pointer to the parameters.\r
-\r
- @retval 0 The application exited normally.\r
- @retval 1 An error occurred.\r
- @retval 2 An error about check occurred.\r
-\r
-**/\r
-int\r
-main (\r
- int argc,\r
- char *argv[]\r
- );\r
-\r
-#endif\r
+++ /dev/null
-## @file GNUmakefile\r
-#\r
-# GNU makefile for 'FCE' module build.\r
-#\r
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
-#\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-\r
-ifndef ARCH\r
- #\r
- # If ARCH is not defined, then we use 'uname -m' to attempt\r
- # try to figure out the appropriate ARCH.\r
- #\r
- uname_m = $(shell uname -m)\r
- $(info Attempting to detect ARCH from 'uname -m': $(uname_m))\r
- ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))\r
- ARCH=X64\r
- endif\r
- ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)\r
- ARCH=IA32\r
- endif\r
- ifneq (,$(findstring aarch64,$(uname_m)))\r
- ARCH=AARCH64\r
- endif\r
- ifneq (,$(findstring arm,$(uname_m)))\r
- ARCH=ARM\r
- endif\r
- ifndef ARCH\r
- $(info Could not detected ARCH from uname results)\r
- $(error ARCH is not defined!)\r
- endif\r
- $(info Detected ARCH of $(ARCH) using uname.)\r
-endif\r
-\r
-export ARCH\r
-export HOST_ARCH=$(ARCH)\r
-\r
-MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r
-\r
-APPNAME = FCE\r
-\r
-OBJECTS = Fce.o Variable.o TimeBasedVariable.o MonotonicBasedVariable.o IfrParse.o Common.o BinaryParse.o BinaryCreate.o Expression.o\r
-\r
-include $(MAKEROOT)/Makefiles/app.makefile\r
-\r
-LIBS = -lCommon -lm\r
-\r
-\r
+++ /dev/null
-/** @file\r
-\r
- Parser for IFR binary encoding.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "IfrParse.h"\r
-\r
-#ifndef EDKII_IFR_BIT_VARSTORE_GUID\r
-#define EDKII_IFR_BIT_VARSTORE_GUID \\r
- {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}}\r
-#endif\r
-\r
-#ifndef EDKII_IFR_NUMERIC_SIZE_BIT\r
-#define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F\r
-#endif\r
-\r
-UINT16 mStatementIndex;\r
-UINT16 mExpressionOpCodeIndex;\r
-\r
-BOOLEAN mInScopeSubtitle;\r
-BOOLEAN mInScopeSuppress;\r
-BOOLEAN mInScopeGrayOut;\r
-BOOLEAN mInScopeDisable;\r
-FORM_EXPRESSION *mSuppressExpression;\r
-FORM_EXPRESSION *mGrayOutExpression;\r
-FORM_EXPRESSION *mDisableExpression;\r
-\r
-extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
-extern LIST_ENTRY mVarListEntry;\r
-extern LIST_ENTRY mFormSetListEntry;\r
-extern UINT32 mFormSetOrderParse;\r
-\r
-#define FORM_SET_GUID_PREFIX "Form Set GUID: "\r
-#define EFI_GUID_FORMAT "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"\r
-\r
-UINT32 mMaxCount = 0x100000;\r
-UINT32 mCount = 0;\r
-CHAR8 *mStringBuffer = NULL;\r
-static EFI_GUID gEdkiiIfrBitVarGuid = EDKII_IFR_BIT_VARSTORE_GUID;\r
-\r
-/**\r
- Produces a Null-terminated ASCII string in mStringBuffer based on a Null-terminated\r
- ASCII format string and variable argument list.\r
-\r
- @param FormatString A null-terminated ASCII format string.\r
- @param ... The variable argument list whose contents are accessed based on the\r
- format string specified by FormatString.\r
-**/\r
-VOID\r
-StringPrint (\r
- CHAR8 *FormatString,\r
- ...\r
-)\r
-{\r
- va_list Marker;\r
- INT32 Count;\r
-\r
- va_start (Marker, FormatString);\r
- Count = vsprintf (mStringBuffer + mCount, FormatString, Marker);\r
- mCount = mCount + Count;\r
- va_end (Marker);\r
- if (mCount + 0x400 > mMaxCount) {\r
- mStringBuffer[mCount] = '\0';\r
- fwrite (mStringBuffer, sizeof (CHAR8), mCount, stdout);\r
- mCount = 0;\r
- }\r
-}\r
-\r
-/**\r
- Print the information of questions.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param FormSet The pointer to the form.\r
- @param Question The pointer to the question.\r
- @param PrintOrNot Decide whether print or not.\r
-\r
- @return NULL.\r
-\r
-**/\r
-static\r
-VOID\r
-PrintQuestion (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN BOOLEAN PrintOrNot\r
- );\r
-\r
-/**\r
- Writes a Unicode string specified by iStringToken and iLanguage to the script file (converted to ASCII).\r
-\r
- @param Package A pointer to the Unicode string.\r
-\r
- @return NULL\r
-\r
-**/\r
-static\r
-VOID\r
-LogUnicodeString (\r
- IN CHAR16 *pcString\r
- )\r
-{\r
- UINTN Index;\r
-\r
- if (pcString == NULL) {\r
- return;\r
- }\r
- //\r
- // replace the 0x0D to 0x20, because if the pcString has 0D 0A, then after print it,\r
- // different editor may have different format\r
- //\r
- for (Index = 0; pcString[Index] != 0; Index++) {\r
- if (pcString[Index] == 0x0D) {\r
- pcString[Index] = 0x20;\r
- }\r
-\r
- StringPrint("%c", pcString[Index] & 0x00FF);\r
- }\r
-}\r
-\r
-/**\r
- Writes a UQIL Unicode string specified by iStringToken to the script file as an array of 16-bit integers in ASCII.\r
-\r
- @param Package A pointer to the Unicode string.\r
-\r
- @return NULL\r
-\r
-**/\r
-static\r
-VOID\r
-LogUqi (\r
- IN CHAR16 *pcString\r
- )\r
-{\r
- UINT16 Index;\r
- //\r
- // Find the UNICODE string length (in CHAR16)\r
- //\r
- for (Index = 0; pcString[Index] != 0; Index++);\r
- //\r
- // Write each word as a hex integer\r
- //\r
- for (Index = 0; pcString[Index] != 0; Index++) {\r
- StringPrint("%04X ", pcString[Index]);\r
- }\r
-}\r
-\r
-/**\r
- Get the question value with bit field from the buffer.\r
-\r
- @param Question The question refer to bit field.\r
- @param Buffer The buffer which the question value get from.\r
- @param Value Retun the value.\r
-\r
-**/\r
-VOID\r
-GetBitsQuestionValue(\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN UINT8 *Buffer,\r
- OUT UINT32 *Value\r
- )\r
-{\r
- UINT32 PreBits;\r
- UINT32 Mask;\r
-\r
- PreBits = Question->BitVarOffset - Question->VarStoreInfo.VarOffset * 8;\r
- Mask = (1<< Question->BitStorageWidth) -1;\r
-\r
- *Value = *(UINT32*)Buffer;\r
- (*Value) >>= PreBits;\r
- (*Value) &= Mask;\r
-}\r
-\r
-/**\r
- Set the question value with bit field to the buffer.\r
-\r
- @param Question The question refer to bit field.\r
- @param Buffer The buffer which the question value set to.\r
- @param Value The value need to set.\r
-\r
-**/\r
-VOID\r
-SetBitsQuestionValue (\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN OUT UINT8 *Buffer,\r
- IN UINT32 Value\r
- )\r
-{\r
- UINT32 PreBits;\r
- UINT32 Mask;\r
- UINT32 TmpValue;\r
-\r
- PreBits = Question->BitVarOffset - Question->VarStoreInfo.VarOffset * 8;\r
- Value <<= PreBits;\r
- Mask = (1<< Question->BitStorageWidth) -1;\r
- Mask <<= PreBits;\r
-\r
- TmpValue = *(UINT32*)(Buffer);\r
- TmpValue = (TmpValue & (~Mask)) | Value;\r
- CopyMem ((UINT32*)Buffer, &TmpValue, sizeof (UINT32));\r
-}\r
-\r
-/**\r
- Print the current value of the specified question.\r
-\r
- @param Question The pointer to question\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-static\r
-EFI_STATUS\r
-LogIfrValue (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 *VarBuffer;\r
- UINT32 Value;\r
-\r
- VarBuffer = NULL;\r
-\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- StringPrint("\nCouldn't read current variable data.");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Log the Value\r
- //\r
- if (\r
- (Question->VarStoreInfo.VarOffset > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_OP)\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else if (\r
- (Question->VarStoreInfo.VarOffset > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r
- && VarList->NewEfiVarstore\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else if (\r
- (Question->StorageWidth > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r
- && !VarList->NewEfiVarstore\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else {\r
- if (Question->QuestionReferToBitField) {\r
- GetBitsQuestionValue (Question, VarBuffer, &Value);\r
- VarBuffer = (UINT8*)(&Value);\r
- }\r
- switch (Question->StorageWidth) {\r
-\r
- case sizeof (UINT8):\r
- StringPrint("%02X", (*(UINT8 *)VarBuffer) & 0xFF);\r
- break;\r
-\r
- case sizeof (UINT16):\r
- StringPrint("%04X", (*(UINT16 *)VarBuffer) & 0xFFFF);\r
- break;\r
-\r
- case sizeof (UINT32):\r
- StringPrint("%08X", (*(UINT32 *)VarBuffer) & 0xFFFFFFFF);\r
- break;\r
-\r
- case sizeof (UINT64):\r
- StringPrint("%016llX", *((UINT64 *)VarBuffer));\r
- break;\r
-\r
- default:\r
- StringPrint("0000 // Width > 16 is not supported -- FAILURE");\r
- break;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Print the current value of the STRING question.\r
-\r
- @param Question The pointer to question\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-static\r
-EFI_STATUS\r
-LogIfrValueStr (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 *VarBuffer;\r
-\r
- VarBuffer = NULL;\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- StringPrint("\nCouldn't read current variable data.");\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Log the Value\r
- //\r
- if (\r
- (Question->VarStoreInfo.VarOffset > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_OP)\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else if (\r
- (Question->VarStoreInfo.VarOffset > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r
- && VarList->NewEfiVarstore\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else if (\r
- (Question->StorageWidth > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r
- && !VarList->NewEfiVarstore\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else {\r
- StringPrint("\"");\r
- LogUnicodeString((CHAR16 *)VarBuffer);\r
- StringPrint("\"");\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Print the current values of an Ordered List question.\r
-\r
- @param Question The pointer to question\r
- @param MaxEntries The max number of options\r
- @param VarList The dual pointer to the Node of VarList\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-static\r
-EFI_STATUS\r
-LogIfrValueList (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 CurrentEntry;\r
- UINT8 *VarBuffer;\r
-\r
- CurrentEntry = 0;\r
- VarBuffer = NULL;\r
-\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- StringPrint("\nCouldn't read current variable data.");\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Log the value\r
- //\r
- if (\r
- ((Question->VarStoreInfo.VarOffset + Question->MaxContainers) > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_OP)\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else if (\r
- (Question->MaxContainers > VarList->Size) \\r
- && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- ) {\r
- StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r
- } else {\r
- for (CurrentEntry = 0; CurrentEntry < Question->MaxContainers; CurrentEntry++) {\r
-\r
- switch (Question->StorageWidth/Question->MaxContainers){\r
-\r
- case 1:\r
- StringPrint("%02X ", VarBuffer[CurrentEntry]);\r
- break;\r
-\r
- case 2:\r
- StringPrint("%04X ", *((UINT16 *)VarBuffer + CurrentEntry));\r
- break;\r
-\r
- case 4:\r
- StringPrint("%08X ", *((UINT32 *)VarBuffer + CurrentEntry));\r
- break;\r
-\r
- case 8:\r
- StringPrint("%016llX ", *((UINT64 *)VarBuffer + CurrentEntry));\r
- break;\r
-\r
- default:\r
- StringPrint("%02X ", VarBuffer[CurrentEntry]);\r
- }\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Compare two Uqi parameters\r
-\r
- @param UqiParm1 The pointer to the first Uqi parameter.\r
- @param UqiParm2 The pointer to the second Uqi parameter.\r
-\r
- @retval TRUE If these two Uqi parameters are the same, return TRUE;\r
- @return FALSE Otherwise, return FALSE;\r
-**/\r
-BOOLEAN\r
-CompareUqiHeader (\r
- IN CONST UQI_HEADER *UqiParm1,\r
- IN CONST UQI_HEADER *UqiParm2\r
- )\r
-{\r
- INT32 Index;\r
-\r
- if (UqiParm1->HexNum != UqiParm2->HexNum) {\r
- return FALSE;\r
- }\r
-\r
- for (Index = UqiParm1->HexNum - 1; Index >= 0; Index--) {\r
- if (UqiParm1->Data[Index] != UqiParm2->Data[Index]) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Check whether existed a same variable in the LIST_ENTRY.\r
-\r
- @param CurVarList A pointer to a variable node.\r
-\r
- @return Pointer If existed the same variable, return the pointer to the Node.\r
- @return NULL Otherwise, return FALSE\r
-\r
-**/\r
-static\r
-FORMSET_STORAGE *\r
-NotSameVariableInVarList (\r
- IN LIST_ENTRY *VariableListEntry,\r
- IN FORMSET_STORAGE *StorageNode\r
- )\r
-{\r
- FORMSET_STORAGE *CurNode;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *StorageListHead;\r
-\r
- StorageListHead = VariableListEntry;\r
- CurNode = NULL;\r
-\r
- //\r
- // Find Storage for this Question\r
- //\r
- Link = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, Link)) {\r
- CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r
-\r
- if (!CompareGuid (&StorageNode->Guid, &CurNode->Guid) \\r
- && (CurNode->Name != NULL) \\r
- && (StorageNode->Name != NULL) \\r
- && !FceStrCmp (StorageNode->Name, CurNode->Name) \\r
- && (StorageNode - CurNode != 0)\r
- ) {\r
- //\r
- // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r
- // two variables with same guid same name, but different type, we will take as the same\r
- // in general mode\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == StorageNode->Type)) {\r
- //\r
- // If matched, get the address of EFI_IFR_VARSTORE data.\r
- //\r
- return CurNode;\r
- break;\r
- } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r
- return CurNode;\r
- break;\r
- }\r
- }\r
- Link = GetNextNode (StorageListHead, Link);\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- Get the UniString by the offset.\r
-\r
- @param UniPackge A pointer to the beginning of Null-terminated Unicode string Array.\r
- @param CurUniPackge A pointer to the current position of Null-terminated Unicode string Array.\r
- @param VarDefaultNameId The string ID.\r
- @param CurOrDefaultLang Use the current language or the default language.\r
- @param VarDefaultName return the name string.\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_INVALID_PARAMETER\r
- @return EFI_NOT_FOUND\r
-**/\r
-static\r
-EFI_STATUS\r
-GetStringByOffset (\r
- IN UINT8 *UniPackge,\r
- IN UINT8 *CurUniPackge,\r
- IN UINT16 VarDefaultNameId,\r
- IN BOOLEAN CurOrDefaultLang,\r
- IN OUT CHAR16 **VarDefaultName\r
- )\r
-{\r
- UINT8 *HiiStringHeader;\r
- UINT32 Offset;\r
- UINT32 Count;\r
- UINT32 Index;\r
- EFI_HII_STRING_BLOCK *Block;\r
- VOID *ThisBlock;\r
-\r
- assert ((UniPackge != NULL) && (CurUniPackge != NULL));\r
-\r
- HiiStringHeader = NULL;\r
- Offset = 1;\r
- Count = 0;\r
- Block = NULL;\r
- ThisBlock = NULL;\r
-\r
- if (VarDefaultNameId == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (CurOrDefaultLang) {\r
- HiiStringHeader = CurUniPackge;\r
- } else {\r
- HiiStringHeader = UniPackge + 4;\r
- }\r
-\r
- Block = (EFI_HII_STRING_BLOCK *)((UINT8*)HiiStringHeader + ((EFI_HII_STRING_PACKAGE_HDR *)HiiStringHeader)->HdrSize);\r
- //\r
- // Search the matched String in specificated language package by the Offset\r
- //\r
- while( Block->BlockType != EFI_HII_SIBT_END ) {\r
- switch (Block->BlockType) {\r
- case EFI_HII_SIBT_STRING_SCSU:\r
- ThisBlock = (VOID *)Block;\r
- for (Index = 0 ; ((EFI_HII_SIBT_STRING_SCSU_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- Block = (EFI_HII_STRING_BLOCK *)&((EFI_HII_SIBT_STRING_SCSU_BLOCK *)ThisBlock)->StringText[Index + 1];\r
- break;\r
-\r
- case EFI_HII_SIBT_STRING_SCSU_FONT:\r
- ThisBlock = (VOID *)Block;\r
- for (Index = 0 ; ((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- Block = (EFI_HII_STRING_BLOCK *)(((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ThisBlock) + 1);\r
- break;\r
-\r
- case EFI_HII_SIBT_STRINGS_SCSU:\r
- ThisBlock = (VOID *)Block;\r
- for( Count= ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) {\r
- for ( ; ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- }\r
- Block = (EFI_HII_STRING_BLOCK *)&((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringText[Index];\r
- break;\r
-\r
- case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
- ThisBlock = (VOID *)Block;\r
- for( Count = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) ;\r
- Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ThisBlock)->StringText[Index];\r
- break;\r
-\r
- case EFI_HII_SIBT_STRING_UCS2:\r
- ThisBlock = (VOID *)Block;\r
- if (Offset == VarDefaultNameId) {\r
- *VarDefaultName = malloc ((FceStrLen ((CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText) + 1) * sizeof (CHAR16));\r
- if (*VarDefaultName == NULL) {\r
- printf ("Fail to allocate memory");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (\r
- *VarDefaultName,\r
- 0,\r
- (FceStrLen ((CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText) + 1) * sizeof (CHAR16)\r
- );\r
- StrCpy (\r
- *VarDefaultName,\r
- (CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *) ThisBlock)->StringText\r
- );\r
- return EFI_SUCCESS;\r
- }\r
-\r
- for (Index = 0 ; ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRING_UCS2_BLOCK *) ThisBlock)->StringText[Index + 1];\r
- Offset += 1;\r
- break;\r
-\r
- case EFI_HII_SIBT_STRING_UCS2_FONT:\r
- ThisBlock = (VOID *)Block;\r
- for (Index = 0 ; ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- Block = (EFI_HII_STRING_BLOCK *)& ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index + 1];\r
- break;\r
-\r
- case EFI_HII_SIBT_STRINGS_UCS2:\r
- ThisBlock = (VOID *)Block;\r
- for( Count = ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) {\r
- for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- }\r
- Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *) ThisBlock)->StringText[Index];\r
- break;\r
-\r
- case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
- ThisBlock = (VOID *)Block;\r
- for( Count= ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *) ThisBlock)->StringCount, Index = 0 ; Count ; Count--, Index++ ) {\r
- for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r
- }\r
- Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ThisBlock)->StringText[Index];\r
- break;\r
-\r
- case EFI_HII_SIBT_DUPLICATE:\r
- ThisBlock = (VOID *)Block;\r
- Block = (EFI_HII_STRING_BLOCK *)((EFI_HII_SIBT_DUPLICATE_BLOCK *) ThisBlock + 1);\r
- break;\r
-\r
- case EFI_HII_SIBT_SKIP2:\r
- ThisBlock = (VOID *)Block;\r
- Offset += ((EFI_HII_SIBT_SKIP2_BLOCK *) ThisBlock)->SkipCount;\r
- Block = (EFI_HII_STRING_BLOCK *)( (EFI_HII_SIBT_SKIP2_BLOCK *) ThisBlock + 1);\r
- break;\r
-\r
- case EFI_HII_SIBT_SKIP1:\r
- ThisBlock = (VOID *)Block;\r
- Offset += ((EFI_HII_SIBT_SKIP1_BLOCK *) ThisBlock)->SkipCount;\r
- Block = (EFI_HII_STRING_BLOCK *)((EFI_HII_SIBT_SKIP1_BLOCK *)ThisBlock + 1);\r
- break;\r
-\r
- case EFI_HII_SIBT_EXT1:\r
- ThisBlock = (VOID *)Block;\r
- Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT1_BLOCK *) ThisBlock)->Length);\r
- break;\r
-\r
- case EFI_HII_SIBT_EXT2:\r
- ThisBlock = (VOID *)Block;\r
- Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT2_BLOCK *) ThisBlock)->Length);\r
- break;\r
-\r
- case EFI_HII_SIBT_EXT4:\r
- ThisBlock = (VOID *)Block;\r
- Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT4_BLOCK *)ThisBlock)->Length);\r
- break;\r
-\r
- case EFI_HII_SIBT_FONT:\r
- ThisBlock = (VOID *)Block;\r
- for (Index = 0 ; ((EFI_HII_SIBT_FONT_BLOCK *) ThisBlock)->FontName[Index] != 0 ; Index++) ;\r
- Block = (EFI_HII_STRING_BLOCK *)& ((EFI_HII_SIBT_FONT_BLOCK *) ThisBlock)->FontName[Index + 1];\r
- break;\r
-\r
- default:\r
- StringPrint("Unhandled type = 0x%x\n", Block->BlockType);\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Parse the UniString to get the string information.\r
-\r
- @param CachedStringList A pointer to cached string list\r
- @param UniPackge A pointer to a Null-terminated Unicode string Array.\r
- @param VarDefaultNameId The string ID.\r
- @param Language The language, en-US UQI or eng.\r
- @param VarDefaultName return the name string.\r
-\r
- @return EFI_SUCCESS If get the name string successfully\r
- @return EFI_NOT_FOUND An error occurred.\r
- @return EFI_INVALID_PARAMETER\r
-\r
-**/\r
-EFI_STATUS\r
-FindDefaultName (\r
- IN FORMSET_STRING_LIST *CachedStringList,\r
- IN UINT8 *UniPackge,\r
- IN UINT16 VarDefaultNameId,\r
- IN LANGUAGE Language,\r
- IN OUT CHAR16 **VarDefaultName\r
- )\r
-{\r
- CHAR8 *UniPackgeEnd;\r
- CHAR8 *UniBin;\r
- CHAR8 LangStr[10];\r
- BOOLEAN IsFound;\r
- EFI_STATUS Status;\r
- EFI_STRING_ID Index;\r
- STRING_INFO *TempBuffer;\r
-\r
- UniBin = NULL;\r
- IsFound = FALSE;\r
- Status = EFI_NOT_FOUND;\r
-\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
- UniPackgeEnd = (CHAR8 *) UniPackge + *(UINT32 *)UniPackge;\r
-\r
- //\r
- //Handle with the invalid usage "STRING_TOKEN(0)"\r
- //\r
- if (VarDefaultNameId == 0) {\r
- *VarDefaultName = L"";\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (CachedStringList != NULL) {\r
- for (Index = 0; Index < CachedStringList->CachedIdNum; Index ++) {\r
- if (VarDefaultNameId == CachedStringList->StringInfoList[Index].StringId) {\r
- *VarDefaultName = CachedStringList->StringInfoList[Index].String;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- switch (Language) {\r
-\r
- case UQI:\r
- strcpy (LangStr, "uqi");\r
- break;\r
-\r
- case EN_US:\r
- strcpy (LangStr, "en-US");\r
- break;\r
-\r
- case ENG:\r
- strcpy (LangStr, "eng");\r
- break;\r
-\r
- default:\r
- strcpy (LangStr, "en-US");\r
- break;\r
- }\r
- IsFound = FALSE;\r
-\r
- if (((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- //\r
- // Search the specified language package\r
- //\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, LangStr) == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- //\r
- //If not find the string ID, use the en eng or en-US instead.\r
- //\r
- if (!IsFound) {\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
-\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if ((strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en") == 0) \\r
- || (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en-US") == 0) \\r
- || (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "eng") == 0) \\r
- ) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- }\r
- //\r
- //If not still find the string ID, use the first one instead.\r
- //\r
- Status = GetStringByOffset (\r
- UniPackge,\r
- (UINT8 *)UniBin,\r
- VarDefaultNameId,\r
- IsFound,\r
- VarDefaultName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- //\r
- //If not find the specified string in UQI package, we use the en en-us eng or uqi insteadly\r
- //\r
- IsFound = FALSE;\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
-\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en") == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- Status = GetStringByOffset (\r
- UniPackge,\r
- (UINT8 *)UniBin,\r
- VarDefaultNameId,\r
- IsFound,\r
- VarDefaultName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- IsFound = FALSE;\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
-\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en-US") == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- Status = GetStringByOffset (\r
- UniPackge,\r
- (UINT8 *)UniBin,\r
- VarDefaultNameId,\r
- IsFound,\r
- VarDefaultName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- IsFound = FALSE;\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
-\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "eng") == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- Status = GetStringByOffset (\r
- UniPackge,\r
- (UINT8 *)UniBin,\r
- VarDefaultNameId,\r
- IsFound,\r
- VarDefaultName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- IsFound = FALSE;\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
-\r
- while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "uqi") == 0) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- Status = GetStringByOffset (\r
- UniPackge,\r
- (UINT8 *)UniBin,\r
- VarDefaultNameId,\r
- IsFound,\r
- VarDefaultName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- *VarDefaultName = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (CachedStringList != NULL) {\r
- if (CachedStringList->CachedIdNum >= CachedStringList->MaxIdNum) {\r
- TempBuffer = calloc (sizeof (STRING_INFO), CachedStringList->MaxIdNum + STRING_NUMBER);\r
- if (TempBuffer == NULL) {\r
- printf ("Fail to allocate memory! \n");\r
- free (*VarDefaultName);\r
- *VarDefaultName = NULL;\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (TempBuffer, CachedStringList->StringInfoList, sizeof (STRING_INFO) * CachedStringList->MaxIdNum);\r
- FreePool (CachedStringList->StringInfoList);\r
- CachedStringList->StringInfoList = TempBuffer;\r
- CachedStringList->MaxIdNum = CachedStringList->MaxIdNum + STRING_NUMBER;\r
- }\r
- CachedStringList->StringInfoList[CachedStringList->CachedIdNum].StringId = VarDefaultNameId;\r
- CachedStringList->StringInfoList[CachedStringList->CachedIdNum].String = *VarDefaultName;\r
- CachedStringList->CachedIdNum ++;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get the variable Guid and Name by the variableId and FormSetOrder.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param FormSet The pointer to the form.\r
- @param ListEntry The pointer to the LIST_ENTRY.\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_NOT_FOUND If not find the the variable, or the variable doesn't belong to EfiVarStore or VarStore.\r
-**/\r
-static\r
-EFI_STATUS\r
-GetGuidNameByVariableId (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_STATEMENT *Question,\r
- IN LIST_ENTRY *ListEntry\r
- )\r
-{\r
- FORMSET_STORAGE *CurNode;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *StorageListHead;\r
- EFI_STATUS Status;\r
- CHAR16 *EfiVariableName;\r
-\r
- StorageListHead = ListEntry;\r
- CurNode = NULL;\r
- Status = EFI_SUCCESS;\r
- EfiVariableName = NULL;\r
-\r
- Link = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, Link)) {\r
- CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r
-\r
- if ((FormSet->FormSetOrder == CurNode->FormSetOrder) \\r
- && (Question->VarStoreId == CurNode->VarStoreId)\r
- ) {\r
- //\r
- // Copy type to question to avoid the case that EfiVarStore and VarStore have the same Guid and name.\r
- //\r
- Question->Type = CurNode->Type;\r
- Question->NewEfiVarstore = CurNode->NewEfiVarstore;\r
- Question->Attributes = CurNode->Attributes;\r
-\r
- if (CurNode->Type == EFI_IFR_VARSTORE_EFI_OP) {\r
- CopyMem (&Question->Guid, &CurNode->Guid, sizeof (EFI_GUID));\r
- //\r
- // If the first time to access the old EfiVarStore, need to sync the variable name\r
- //\r
- if (!CurNode->NewEfiVarstore) {\r
- if (CurNode->Buffer == NULL) {\r
- CurNode->Buffer = malloc (Question->StorageWidth);\r
- }\r
- if (CurNode->Name == NULL) {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->VarStoreInfo.VarName,\r
- EN_US,\r
- &EfiVariableName\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- CurNode->Name = EfiVariableName;\r
- }\r
- if (CurNode->Size == 0) {\r
- CurNode->Size = Question->StorageWidth;\r
- }\r
- }\r
- //\r
- // Check whether the Efivariable variable name is valid.\r
- //\r
- if ((CurNode->Name == NULL) || (FceStrLen (CurNode->Name) == 0)) {\r
- StringPrint ("Error. The variable name of question is NULL. Its UQI is: ");\r
- StringPrint("Q %04X ", Question->Uqi.HexNum);\r
- LogUqi (Question->Uqi.Data);\r
- StringPrint ("\n");\r
- return EFI_ABORTED;\r
- }\r
- if (Question->VariableName == NULL) {\r
- Question->VariableName = (CHAR16 *) malloc (2 * (FceStrLen ((CONST CHAR16 *)CurNode->Name) + 1));\r
- if (Question->VariableName == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- StrCpy (Question->VariableName, CurNode->Name);\r
-\r
- return EFI_SUCCESS;\r
-\r
- } else if (CurNode->Type == EFI_IFR_VARSTORE_OP) {\r
- CopyMem (&Question->Guid, &CurNode->Guid, sizeof (EFI_GUID));\r
- if (Question->VariableName == NULL) {\r
- Question->VariableName = (CHAR16 *) malloc (2 * (FceStrLen ((CONST CHAR16 *)CurNode->Name) + 1));\r
- if (Question->VariableName == NULL) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Check whether the variable variable name is valid.\r
- //\r
- if ((CurNode->Name == NULL) || (FceStrLen (CurNode->Name) == 0)) {\r
- StringPrint ("Error. The variable name of question is NULL. UQI:");\r
- StringPrint("Q %04X ", Question->Uqi.HexNum);\r
- LogUqi (Question->Uqi.Data);\r
- StringPrint ("\n");\r
- return EFI_ABORTED;\r
- }\r
- StrCpy (Question->VariableName, CurNode->Name);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- Link = GetNextNode (StorageListHead, Link);\r
- }\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Search the variable list according to the variable Guid and name, and return the pointer\r
- of that Node.\r
-\r
- @param HiiObjList The pointer to the Question\r
- @param VarName The EFI variable name need to be updated to VarList\r
- @param Offset The offset of the variable\r
- @param StorageListHead The pointer to the LIST_ENTRY of Storage\r
- @param Vaue The value in that value offset of the variable\r
- @param VarList The dual pointer of Varlist\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_NOT_FOUND\r
-**/\r
-EFI_STATUS\r
-SearchVarStorage (\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN CHAR16* VarName,\r
- IN UINT32 Offset,\r
- IN LIST_ENTRY *StorageListHead,\r
- IN OUT CHAR8 **Value,\r
- IN OUT FORMSET_STORAGE **VarList\r
- )\r
-{\r
- FORMSET_STORAGE *CurNode;\r
- LIST_ENTRY *Link;\r
- BOOLEAN FindOrNot;\r
-\r
- CurNode = NULL;\r
- FindOrNot = FALSE;\r
- *VarList = NULL;\r
- //\r
- // Find Storage for this Question\r
- //\r
- Link = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, Link)) {\r
- CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r
- //\r
- // Deal with the old EfiVarstore before UEFI2.31\r
- //\r
- if (!CompareGuid (&Question->Guid, &CurNode->Guid) \\r
- && (CurNode->Type == EFI_IFR_VARSTORE_EFI_OP) \\r
- && !CurNode->NewEfiVarstore \\r
- && (Question->VariableName != NULL) \\r
- && (CurNode->Name != NULL) \\r
- && !FceStrCmp(Question->VariableName, CurNode->Name)\r
- ) {\r
- //\r
- // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r
- // two variables with same guid same name, but different type, we will take as the same\r
- // in general mode\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == Question->Type)) {\r
- //\r
- // check whether exist a old EFI_IFR_VARSTORE_EFI or not.\r
- //\r
- *Value = (CHAR8 *)CurNode->Buffer;\r
- *VarList = CurNode;\r
- FindOrNot = TRUE;\r
- break;\r
- } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // check whether exist a old EFI_IFR_VARSTORE_EFI or not.\r
- //\r
- *Value = (CHAR8 *)CurNode->Buffer;\r
- *VarList = CurNode;\r
- FindOrNot = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- if (!CompareGuid (&Question->Guid, &CurNode->Guid) \\r
- && (CurNode->Name != NULL) \\r
- && (Question->VariableName != NULL) \\r
- && !FceStrCmp(Question->VariableName, CurNode->Name)\r
- ) {\r
- //\r
- // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r
- // two variables with same guid same name, but different type, we will take as the same\r
- // in general mode\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == Question->Type)) {\r
- //\r
- // If matched, get the address of EFI_IFR_VARSTORE data.\r
- //\r
- *Value = (CHAR8 *)(CurNode->Buffer + Offset);\r
- *VarList = CurNode;\r
- FindOrNot = TRUE;\r
- break;\r
- } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // If matched, get the address of EFI_IFR_VARSTORE data.\r
- //\r
- *Value = (CHAR8 *)(CurNode->Buffer + Offset);\r
- *VarList = CurNode;\r
- FindOrNot = TRUE;\r
- break;\r
- }\r
- }\r
- Link = GetNextNode (StorageListHead, Link);\r
- }\r
- if (!FindOrNot) {\r
- return EFI_NOT_FOUND;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get the string based on the StringId and HII Package List Handle.\r
-\r
- @param Token The String's ID.\r
- @param HiiHandle The package list in the HII database to search for\r
- the specified string.\r
-\r
- @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-GetToken (\r
- IN EFI_STRING_ID Token,\r
- IN UINT8 *UniPackge\r
- )\r
-{\r
- CHAR16 *VarDefaultName;\r
- EFI_STATUS Status;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if (UniPackge == NULL) {\r
- return NULL;\r
- }\r
-\r
- Status = FindDefaultName (\r
- NULL,\r
- UniPackge,\r
- Token,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
- }\r
-\r
- return VarDefaultName;\r
-}\r
-\r
-/**\r
- Initialize Statement header members.\r
-\r
- @param OpCodeData Pointer of the raw OpCode data.\r
- @param FormSet Pointer of the current FormSe.\r
- @param Form Pointer of the current Form.\r
-\r
- @return The Statement.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-CreateStatement (\r
- IN UINT8 *OpCodeData,\r
- IN OUT FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- FORM_BROWSER_STATEMENT *Statement;\r
- EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
-\r
- if (Form == NULL) {\r
- //\r
- // We are currently not in a Form Scope, so just skip this Statement\r
- //\r
- return NULL;\r
- }\r
-\r
- Statement = &FormSet->StatementBuffer[mStatementIndex];\r
- mStatementIndex++;\r
-\r
- InitializeListHead (&Statement->DefaultListHead);\r
- InitializeListHead (&Statement->OptionListHead);\r
- InitializeListHead (&Statement->InconsistentListHead);\r
- InitializeListHead (&Statement->NoSubmitListHead);\r
- InitializeListHead (&Statement->WarningListHead);\r
-\r
- Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
-\r
- Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
- Statement->QuestionReferToBitField = FALSE;\r
-\r
- StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
- CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
- CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
-\r
- if (mInScopeSuppress) {\r
- Statement->SuppressExpression = mSuppressExpression;\r
- }\r
-\r
- if (mInScopeGrayOut) {\r
- Statement->GrayOutExpression = mGrayOutExpression;\r
- }\r
-\r
-\r
- if (mInScopeDisable) {\r
- Statement->DisableExpression = mDisableExpression;\r
- }\r
-\r
- Statement->InSubtitle = mInScopeSubtitle;\r
-\r
- //\r
- // Insert this Statement into current Form\r
- //\r
- InsertTailList (&Form->StatementListHead, &Statement->Link);\r
-\r
- return Statement;\r
-}\r
-\r
-/**\r
- Initialize Question's members.\r
-\r
- @param OpCodeData Pointer of the raw OpCode data.\r
- @param FormSet Pointer of the current FormSet.\r
- @param Form Pointer of the current Form.\r
-\r
- @return The Question.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-CreateQuestion (\r
- IN UINT8 *OpCodeData,\r
- IN OUT FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- FORM_BROWSER_STATEMENT *Statement;\r
- EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
- LIST_ENTRY *Link;\r
- FORMSET_STORAGE *Storage;\r
- NAME_VALUE_NODE *NameValueNode;\r
-\r
- Statement = CreateStatement (OpCodeData, FormSet, Form);\r
- if (Statement == NULL) {\r
- return NULL;\r
- }\r
-\r
- QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
- CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
- CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
- CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
-\r
- Statement->QuestionFlags = QuestionHdr->Flags;\r
-\r
- Statement->FormSetOrder = mFormSetOrderParse;\r
-\r
- if (Statement->VarStoreId == 0) {\r
- //\r
- // VarStoreId of zero indicates no variable storage\r
- //\r
- return Statement;\r
- }\r
-\r
- //\r
- // Find Storage for this Question\r
- //\r
- Link = GetFirstNode (FormSet->StorageListHead);\r
- while (!IsNull (FormSet->StorageListHead, Link)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
-\r
- if ((Storage->VarStoreId == Statement->VarStoreId)\r
- && (Storage->FormSetOrder == Statement->FormSetOrder)) {\r
- Statement->Storage = Storage;\r
- break;\r
- }\r
-\r
- Link = GetNextNode (FormSet->StorageListHead, Link);\r
- }\r
- ASSERT (Statement->Storage != NULL);\r
-\r
- if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
- Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->UnicodeBinary);\r
- ASSERT (Statement->VariableName != NULL);\r
- //\r
- // Insert to Name/Value varstore list\r
- //\r
- NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
- ASSERT (NameValueNode != NULL);\r
- NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
- NameValueNode->Name = FceAllocateCopyPool (FceStrSize (Statement->VariableName), Statement->VariableName);\r
- ASSERT (NameValueNode->Name != NULL);\r
- NameValueNode->Value = AllocateZeroPool (0x10);\r
- ASSERT (NameValueNode->Value != NULL);\r
- NameValueNode->EditValue = AllocateZeroPool (0x10);\r
- ASSERT (NameValueNode->EditValue != NULL);\r
-\r
- InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
- }\r
-\r
- return Statement;\r
-}\r
-\r
-\r
-/**\r
- Allocate a FORM_EXPRESSION node.\r
-\r
- @param Form The Form associated with this Expression\r
-\r
- @return Pointer to a FORM_EXPRESSION data structure.\r
-\r
-**/\r
-FORM_EXPRESSION *\r
-CreateExpression (\r
- IN OUT FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- FORM_EXPRESSION *Expression;\r
-\r
- Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
- ASSERT (Expression != NULL);\r
- Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
- InitializeListHead (&Expression->OpCodeListHead);\r
-\r
- return Expression;\r
-}\r
-\r
-\r
-/**\r
- Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
-\r
- @param FormSet Pointer of the current FormSet\r
-\r
- @return Pointer to a FORMSET_STORAGE data structure.\r
-\r
-**/\r
-FORMSET_STORAGE *\r
-CreateStorage (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- FORMSET_STORAGE *Storage;\r
-\r
- Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
- ASSERT (Storage != NULL);\r
- Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
- InsertTailList (FormSet->StorageListHead, &Storage->Link);\r
-\r
- return Storage;\r
-}\r
-\r
-/**\r
- Free resources of a Expression.\r
-\r
- @param FormSet Pointer of the Expression\r
-\r
-**/\r
-VOID\r
-DestroyExpression (\r
- IN FORM_EXPRESSION *Expression\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- EXPRESSION_OPCODE *OpCode;\r
- LIST_ENTRY *SubExpressionLink;\r
- FORM_EXPRESSION *SubExpression;\r
-\r
- while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
- Link = GetFirstNode (&Expression->OpCodeListHead);\r
- OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
- RemoveEntryList (&OpCode->Link);\r
-\r
- if (OpCode->ValueList != NULL) {\r
- FreePool (OpCode->ValueList);\r
- }\r
-\r
- if (OpCode->ValueName != NULL) {\r
- FreePool (OpCode->ValueName);\r
- }\r
-\r
- if (OpCode->MapExpressionList.ForwardLink != NULL) {\r
- while (!IsListEmpty (&OpCode->MapExpressionList)) {\r
- SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
- SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
- RemoveEntryList(&SubExpression->Link);\r
- DestroyExpression (SubExpression);\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Free this Expression\r
- //\r
- FreePool (Expression);\r
-}\r
-\r
-\r
-/**\r
- Free resources of a storage.\r
-\r
- @param Storage Pointer of the storage\r
-\r
-**/\r
-VOID\r
-DestroyStorage (\r
- IN FORMSET_STORAGE *Storage\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- NAME_VALUE_NODE *NameValueNode;\r
-\r
- if (Storage == NULL) {\r
- return;\r
- }\r
-\r
- if (Storage->Name != NULL) {\r
- FreePool (Storage->Name);\r
- }\r
- if (Storage->Buffer != NULL) {\r
- FreePool (Storage->Buffer);\r
- }\r
-\r
- while (!IsListEmpty (&Storage->NameValueListHead)) {\r
- Link = GetFirstNode (&Storage->NameValueListHead);\r
- NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
- RemoveEntryList (&NameValueNode->Link);\r
-\r
- if (NameValueNode->Name != NULL) {\r
- FreePool (NameValueNode->Name);\r
- }\r
- if (NameValueNode->Value != NULL) {\r
- FreePool (NameValueNode->Value);\r
- }\r
- if (NameValueNode->EditValue != NULL) {\r
- FreePool (NameValueNode->EditValue);\r
- }\r
- FreePool (NameValueNode);\r
- }\r
-\r
- FreePool (Storage);\r
- Storage = NULL;\r
-}\r
-\r
-/**\r
- Free resources allocated for all Storage in an LIST_ENTRY.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyAllStorage (\r
- IN LIST_ENTRY *StorageEntryListHead\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORMSET_STORAGE *Storage;\r
- //\r
- // Parse Fromset one by one\r
- //\r
- if (StorageEntryListHead->ForwardLink != NULL) {\r
- while (!IsListEmpty (StorageEntryListHead)) {\r
- Link = GetFirstNode (StorageEntryListHead);\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
- RemoveEntryList (&Storage->Link);\r
-\r
- DestroyStorage (Storage);\r
- }\r
- }\r
- StorageEntryListHead = NULL;\r
-}\r
-\r
-/**\r
- Free resources of a Statement.\r
-\r
- @param FormSet Pointer of the FormSet\r
- @param Statement Pointer of the Statement\r
-\r
-**/\r
-VOID\r
-DestroyStatement (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_STATEMENT *Statement\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- QUESTION_DEFAULT *Default;\r
- QUESTION_OPTION *Option;\r
- FORM_EXPRESSION *Expression;\r
-\r
- //\r
- // Free Default value List\r
- //\r
- while (!IsListEmpty (&Statement->DefaultListHead)) {\r
- Link = GetFirstNode (&Statement->DefaultListHead);\r
- Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
- RemoveEntryList (&Default->Link);\r
-\r
- if (Default->Value.Buffer != NULL) {\r
- FreePool(Default->Value.Buffer);\r
- }\r
- FreePool (Default);\r
- }\r
-\r
- //\r
- // Free Options List\r
- //\r
- while (!IsListEmpty (&Statement->OptionListHead)) {\r
- Link = GetFirstNode (&Statement->OptionListHead);\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
- RemoveEntryList (&Option->Link);\r
-\r
- FreePool (Option);\r
- }\r
-\r
- //\r
- // Free Inconsistent List\r
- //\r
- while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
- Link = GetFirstNode (&Statement->InconsistentListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- //\r
- // Free NoSubmit List\r
- //\r
- while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
- Link = GetFirstNode (&Statement->NoSubmitListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- //\r
- // Free WarningIf List\r
- //\r
- while (!IsListEmpty (&Statement->WarningListHead)) {\r
- Link = GetFirstNode (&Statement->WarningListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
- if (Statement->VariableName != NULL) {\r
- FreePool (Statement->VariableName);\r
- }\r
- if (Statement->BufferValue != NULL) {\r
- FreePool (Statement->BufferValue);\r
- }\r
-}\r
-\r
-/**\r
- Free resources of a Form.\r
-\r
- @param FormSet Pointer of the FormSet\r
- @param Form Pointer of the Form.\r
-\r
-**/\r
-VOID\r
-DestroyForm (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
- FORM_BROWSER_STATEMENT *Statement;\r
-\r
- //\r
- // Free Form Expressions\r
- //\r
- while (!IsListEmpty (&Form->ExpressionListHead)) {\r
- Link = GetFirstNode (&Form->ExpressionListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- //\r
- // Free Statements/Questions\r
- //\r
- while (!IsListEmpty (&Form->StatementListHead)) {\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
- RemoveEntryList (&Statement->Link);\r
-\r
- DestroyStatement (FormSet, Statement);\r
- }\r
-\r
- //\r
- // Free this Form\r
- //\r
- FreePool (Form);\r
-}\r
-\r
-\r
-/**\r
- Free resources allocated for a FormSet.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyFormSet (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORMSET_DEFAULTSTORE *DefaultStore;\r
- FORM_EXPRESSION *Expression;\r
- FORM_BROWSER_FORM *Form;\r
- UINT16 Index;\r
-\r
- //\r
- // Free FormSet Default Store\r
- //\r
- if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
- while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
- Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
- DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
- RemoveEntryList (&DefaultStore->Link);\r
-\r
- FreePool (DefaultStore);\r
- }\r
- }\r
-\r
- //\r
- // Free Formset Expressions\r
- //\r
- while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
- Link = GetFirstNode (&FormSet->ExpressionListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- //\r
- // Free Forms\r
- //\r
- if (FormSet->FormListHead.ForwardLink != NULL) {\r
- while (!IsListEmpty (&FormSet->FormListHead)) {\r
- Link = GetFirstNode (&FormSet->FormListHead);\r
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
- RemoveEntryList (&Form->Link);\r
-\r
- DestroyForm (FormSet, Form);\r
- }\r
- }\r
-\r
- if (FormSet->StatementBuffer != NULL) {\r
- FreePool (FormSet->StatementBuffer);\r
- }\r
- if (FormSet->ExpressionBuffer != NULL) {\r
- FreePool (FormSet->ExpressionBuffer);\r
- }\r
- if (FormSet->EnUsStringList.StringInfoList != NULL) {\r
- for (Index = 0; Index < FormSet->EnUsStringList.CachedIdNum; Index ++) {\r
- FreePool (FormSet->EnUsStringList.StringInfoList[Index].String);\r
- }\r
- FreePool (FormSet->EnUsStringList.StringInfoList);\r
- }\r
- if (FormSet->UqiStringList.StringInfoList != NULL) {\r
- for (Index = 0; Index < FormSet->UqiStringList.CachedIdNum; Index ++) {\r
- FreePool (FormSet->UqiStringList.StringInfoList[Index].String);\r
- }\r
- FreePool (FormSet->UqiStringList.StringInfoList);\r
- }\r
-\r
- FreePool (FormSet);\r
-}\r
-\r
-/**\r
- Free resources allocated for all FormSet in an LIST_ENTRY.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyAllFormSet (\r
- IN LIST_ENTRY *FormSetEntryListHead\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- //\r
- // Parse Fromset one by one\r
- //\r
- if (FormSetEntryListHead->ForwardLink != NULL) {\r
- while (!IsListEmpty (FormSetEntryListHead)) {\r
- Link = GetFirstNode (FormSetEntryListHead);\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
- RemoveEntryList (&FormSet->Link);\r
- DestroyFormSet (FormSet);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Tell whether this Operand is an Expression OpCode or not\r
-\r
- @param Operand Operand of an IFR OpCode.\r
-\r
- @retval TRUE This is an Expression OpCode.\r
- @retval FALSE Not an Expression OpCode.\r
-\r
-**/\r
-BOOLEAN\r
-IsExpressionOpCode (\r
- IN UINT8 Operand\r
- )\r
-{\r
- if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
- ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||\r
- ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
- (Operand == EFI_IFR_CATENATE_OP) ||\r
- (Operand == EFI_IFR_TO_LOWER_OP) ||\r
- (Operand == EFI_IFR_TO_UPPER_OP) ||\r
- (Operand == EFI_IFR_MAP_OP) ||\r
- (Operand == EFI_IFR_VERSION_OP) ||\r
- (Operand == EFI_IFR_SECURITY_OP)) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-/**\r
- Calculate number of Statemens(Questions) and Expression OpCodes.\r
-\r
- @param FormSet The FormSet to be counted.\r
- @param NumberOfStatement Number of Statemens(Questions)\r
- @param NumberOfExpression Number of Expression OpCodes\r
-\r
-**/\r
-VOID\r
-CountOpCodes (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT UINT16 *NumberOfStatement,\r
- IN OUT UINT16 *NumberOfExpression\r
- )\r
-{\r
- UINT16 StatementCount;\r
- UINT16 ExpressionCount;\r
- UINT8 *OpCodeData;\r
- UINTN Offset;\r
- UINTN OpCodeLen;\r
-\r
- Offset = 0;\r
- StatementCount = 0;\r
- ExpressionCount = 0;\r
-\r
- while (Offset < FormSet->IfrBinaryLength) {\r
- OpCodeData = FormSet->IfrBinaryData + Offset;\r
- OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
- Offset += OpCodeLen;\r
-\r
- if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
- ExpressionCount++;\r
- } else {\r
- StatementCount++;\r
- }\r
- }\r
-\r
- *NumberOfStatement = StatementCount;\r
- *NumberOfExpression = ExpressionCount;\r
-}\r
-\r
-\r
-\r
-/**\r
- Parse opcodes in the formset IFR binary.\r
-\r
- @param FormSet Pointer of the FormSet data structure.\r
-\r
- @retval EFI_SUCCESS Opcode parse success.\r
- @retval Other Opcode parse fail.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseOpCodes (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 Index;\r
- FORM_BROWSER_FORM *CurrentForm;\r
- FORM_BROWSER_STATEMENT *CurrentStatement;\r
- EXPRESSION_OPCODE *ExpressionOpCode;\r
- FORM_EXPRESSION *CurrentExpression;\r
- UINT8 Operand;\r
- UINT8 Scope;\r
- UINTN OpCodeOffset;\r
- UINTN OpCodeLength;\r
- UINT8 *OpCodeData;\r
- UINT8 ScopeOpCode;\r
- FORMSET_STORAGE *Storage;\r
- FORMSET_STORAGE *TempStorage;\r
- FORMSET_DEFAULTSTORE *DefaultStore;\r
- QUESTION_DEFAULT *CurrentDefault;\r
- QUESTION_OPTION *CurrentOption;\r
- UINT8 Width;\r
- CHAR8 *AsciiString;\r
- UINT16 NumberOfStatement;\r
- UINT16 NumberOfExpression;\r
- BOOLEAN SuppressForQuestion;\r
- BOOLEAN SuppressForOption;\r
- BOOLEAN InScopeOptionSuppress;\r
- FORM_EXPRESSION *OptionSuppressExpression;\r
- BOOLEAN InScopeFormSuppress;\r
- FORM_EXPRESSION *FormSuppressExpression;\r
- UINT16 DepthOfDisable;\r
- BOOLEAN OpCodeDisabled;\r
- BOOLEAN SingleOpCodeExpression;\r
- BOOLEAN InScopeDefault;\r
- EFI_HII_VALUE *Value;\r
- UINT8 MapScopeDepth;\r
- LIST_ENTRY *Link;\r
- FORMSET_STORAGE *VarStorage;\r
- LIST_ENTRY *MapExpressionList;\r
- EFI_VARSTORE_ID TempVarstoreId;\r
- BOOLEAN ConstantFlag;\r
- FORMSET_DEFAULTSTORE *PreDefaultStore;\r
- LIST_ENTRY *DefaultLink;\r
- BOOLEAN HaveInserted;\r
- BOOLEAN BitFieldStorage;\r
- UINT16 TotalBits;\r
-\r
- mInScopeSubtitle = FALSE;\r
- SuppressForQuestion = FALSE;\r
- SuppressForOption = FALSE;\r
- InScopeFormSuppress = FALSE;\r
- mInScopeSuppress = FALSE;\r
- InScopeOptionSuppress = FALSE;\r
- mInScopeGrayOut = FALSE;\r
- mInScopeDisable = FALSE;\r
- DepthOfDisable = 0;\r
- OpCodeDisabled = FALSE;\r
- SingleOpCodeExpression = FALSE;\r
- InScopeDefault = FALSE;\r
- CurrentExpression = NULL;\r
- CurrentDefault = NULL;\r
- CurrentOption = NULL;\r
- OptionSuppressExpression = NULL;\r
- FormSuppressExpression = NULL;\r
- MapScopeDepth = 0;\r
- Link = NULL;\r
- VarStorage = NULL;\r
- MapExpressionList = NULL;\r
- TempVarstoreId = 0;\r
- ConstantFlag = TRUE;\r
- BitFieldStorage = FALSE;\r
-\r
- //\r
- // Get the number of Statements and Expressions\r
- //\r
- CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
-\r
- mStatementIndex = 0;\r
- FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
- if (FormSet->StatementBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- mExpressionOpCodeIndex = 0;\r
- FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
- if (FormSet->ExpressionBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- FormSet->StorageListHead = &mVarListEntry;\r
- InitializeListHead (&FormSet->DefaultStoreListHead);\r
- InitializeListHead (&FormSet->FormListHead);\r
- InitializeListHead (&FormSet->ExpressionListHead);\r
- ResetCurrentExpressionStack ();\r
- ResetMapExpressionListStack ();\r
-\r
- CurrentForm = NULL;\r
- CurrentStatement = NULL;\r
-\r
- ResetScopeStack ();\r
-\r
- OpCodeOffset = 0;\r
- while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
- OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
-\r
- OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
- OpCodeOffset += OpCodeLength;\r
- Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
- Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
-\r
- //\r
- // If scope bit set, push onto scope stack\r
- //\r
- if (Scope != 0) {\r
- PushScope (Operand);\r
- }\r
-\r
- if (OpCodeDisabled) {\r
- //\r
- // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
- // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
- //\r
- if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
- DepthOfDisable++;\r
- } else if (Operand == EFI_IFR_END_OP) {\r
- Status = PopScope (&ScopeOpCode);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
- if (DepthOfDisable == 0) {\r
- mInScopeDisable = FALSE;\r
- OpCodeDisabled = FALSE;\r
- } else {\r
- DepthOfDisable--;\r
- }\r
- }\r
- }\r
- continue;\r
- }\r
-\r
- if (IsExpressionOpCode (Operand)) {\r
- ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
- mExpressionOpCodeIndex++;\r
-\r
- ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
- ExpressionOpCode->Operand = Operand;\r
- Value = &ExpressionOpCode->Value;\r
-\r
- switch (Operand) {\r
- case EFI_IFR_EQ_ID_VAL_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_ID_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
- CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
- CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
- ExpressionOpCode->ValueList = FceAllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
- break;\r
-\r
- case EFI_IFR_TO_STRING_OP:\r
- case EFI_IFR_FIND_OP:\r
- ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF1_OP:\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
- break;\r
-\r
- case EFI_IFR_RULE_REF_OP:\r
- ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
- break;\r
-\r
- case EFI_IFR_SPAN_OP:\r
- ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
- break;\r
-\r
- case EFI_IFR_THIS_OP:\r
- ASSERT (CurrentStatement != NULL);\r
- ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
- break;\r
-\r
- case EFI_IFR_SECURITY_OP:\r
- CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
- break;\r
-\r
- case EFI_IFR_GET_OP:\r
- case EFI_IFR_SET_OP:\r
- CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
- if (TempVarstoreId != 0) {\r
- if (FormSet->StorageListHead->ForwardLink != NULL) {\r
- Link = GetFirstNode (FormSet->StorageListHead);\r
- while (!IsNull (FormSet->StorageListHead, Link)) {\r
- VarStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
- if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {\r
- ExpressionOpCode->VarStorage = VarStorage;\r
- break;\r
- }\r
- Link = GetNextNode (FormSet->StorageListHead, Link);\r
- }\r
- }\r
- if (ExpressionOpCode->VarStorage == NULL) {\r
- //\r
- // VarStorage is not found.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;\r
- switch (ExpressionOpCode->ValueType) {\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- ExpressionOpCode->ValueWidth = 1;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- case EFI_IFR_TYPE_STRING:\r
- ExpressionOpCode->ValueWidth = 2;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- ExpressionOpCode->ValueWidth = 4;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- ExpressionOpCode->ValueWidth = 8;\r
- break;\r
-\r
- case EFI_IFR_TYPE_DATE:\r
- ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);\r
- break;\r
-\r
- case EFI_IFR_TYPE_TIME:\r
- ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);\r
- break;\r
-\r
- case EFI_IFR_TYPE_REF:\r
- ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r
- break;\r
-\r
- case EFI_IFR_TYPE_OTHER:\r
- case EFI_IFR_TYPE_UNDEFINED:\r
- case EFI_IFR_TYPE_ACTION:\r
- case EFI_IFR_TYPE_BUFFER:\r
- default:\r
- //\r
- // Invalid value type for Get/Set opcode.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));\r
- CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r
- if ((ExpressionOpCode->VarStorage != NULL) &&\r
- ((ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE)\r
- || ((ExpressionOpCode->VarStorage->Type == EFI_IFR_VARSTORE_EFI_OP) && !ExpressionOpCode->VarStorage->NewEfiVarstore))\r
- ) {\r
- ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->UnicodeBinary);\r
- if (ExpressionOpCode->ValueName == NULL) {\r
- //\r
- // String ID is invalid.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF1_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
- CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
-\r
- if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
- CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- }\r
- }\r
- break;\r
-\r
- //\r
- // constant\r
- //\r
- case EFI_IFR_TRUE_OP:\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Value->Value.b = TRUE;\r
- break;\r
-\r
- case EFI_IFR_FALSE_OP:\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Value->Value.b = FALSE;\r
- break;\r
-\r
- case EFI_IFR_ONE_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = 1;\r
- break;\r
-\r
- case EFI_IFR_ZERO_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = 0;\r
- break;\r
-\r
- case EFI_IFR_ONES_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = 0xffffffffffffffffULL;\r
- break;\r
-\r
- case EFI_IFR_UINT8_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
- break;\r
-\r
- case EFI_IFR_UINT16_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
- break;\r
-\r
- case EFI_IFR_UINT32_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
- CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
- break;\r
-\r
- case EFI_IFR_UINT64_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
- break;\r
-\r
- case EFI_IFR_UNDEFINED_OP:\r
- Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
- break;\r
-\r
- case EFI_IFR_VERSION_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- //\r
- // Create sub expression nested in MAP opcode\r
- //\r
- if ((CurrentExpression == NULL) && (MapScopeDepth > 0)) {\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- ASSERT (MapExpressionList != NULL);\r
- InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
- if (Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- }\r
- ASSERT (CurrentExpression != NULL);\r
- InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
- if (Operand == EFI_IFR_MAP_OP) {\r
- //\r
- // Store current Map Expression List.\r
- //\r
- if (MapExpressionList != NULL) {\r
- PushMapExpressionList (MapExpressionList);\r
- }\r
- //\r
- // Initialize new Map Expression List.\r
- //\r
- MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
- InitializeListHead (MapExpressionList);\r
- //\r
- // Store current expression.\r
- //\r
- PushCurrentExpression (CurrentExpression);\r
- CurrentExpression = NULL;\r
- MapScopeDepth ++;\r
- } else if (SingleOpCodeExpression) {\r
- //\r
- // There are two cases to indicate the end of an Expression:\r
- // for single OpCode expression: one Expression OpCode\r
- // for expression consists of more than one OpCode: EFI_IFR_END\r
- //\r
- SingleOpCodeExpression = FALSE;\r
-\r
- if (mInScopeDisable && (CurrentForm == NULL)) {\r
- //\r
- // This is DisableIf expression for Form, it should be a constant expression\r
- //\r
- ConstantFlag = TRUE;\r
- Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression, &ConstantFlag);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (!ConstantFlag) {\r
- StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");\r
- }\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
- }\r
-\r
- CurrentExpression = NULL;\r
- }\r
-\r
- continue;\r
- }\r
-\r
- //\r
- // Parse the Opcode\r
- //\r
- switch (Operand) {\r
-\r
- case EFI_IFR_FORM_SET_OP:\r
-\r
- CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
- CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
- CopyMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-\r
- if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
- //\r
- // The formset OpCode contains ClassGuid\r
- //\r
- FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
- CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
- }\r
- FormSet->FormSetOrder = ++mFormSetOrderParse;\r
- break;\r
-\r
- case EFI_IFR_FORM_OP:\r
- case EFI_IFR_FORM_MAP_OP:\r
- //\r
- // Create a new Form for this FormSet\r
- //\r
- CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
- ASSERT (CurrentForm != NULL);\r
- CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
- InitializeListHead (&CurrentForm->ExpressionListHead);\r
- InitializeListHead (&CurrentForm->StatementListHead);\r
-\r
- CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
- CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
- CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
-\r
- if (InScopeFormSuppress) {\r
- //\r
- // Form is inside of suppressif\r
- //\r
- CurrentForm->SuppressExpression = FormSuppressExpression;\r
- }\r
-\r
- if (Scope != 0) {\r
- //\r
- // Enter scope of a Form, suppressif will be used for Question or Option\r
- //\r
- SuppressForQuestion = TRUE;\r
- }\r
-\r
- //\r
- // Insert into Form list of this FormSet\r
- //\r
- InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
- break;\r
- //\r
- // Storage\r
- //\r
- case EFI_IFR_VARSTORE_OP:\r
- //\r
- // Create a buffer Storage for this FormSet\r
- //\r
-\r
- Storage = CreateStorage (FormSet);\r
- Storage->Type = EFI_IFR_VARSTORE_OP;\r
-\r
- CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
-\r
- Storage->Buffer = AllocateZeroPool (Storage->Size);\r
-\r
- AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
- Storage->Name = AllocateZeroPool ((strlen (AsciiString) + 1) * 2);\r
- ASSERT (Storage->Name != NULL);\r
- for (Index = 0; AsciiString[Index] != 0; Index++) {\r
- Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
- }\r
- Storage->FormSetOrder = mFormSetOrderParse;\r
-\r
- //\r
- // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.\r
- // If these two variales have the same Guid name but different size, report an error.\r
- //\r
- if ((TempStorage = NotSameVariableInVarList (FormSet->StorageListHead, Storage)) != NULL) {\r
- if (Storage->Size != TempStorage->Size) {\r
- StringPrint ("Error. Two modules found with VarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but with different sizes %d and %d.\n",\r
- Storage->Name,\r
- Storage->Guid.Data1,\r
- Storage->Guid.Data2,\r
- Storage->Guid.Data3,\r
- Storage->Guid.Data4[0],\r
- Storage->Guid.Data4[1],\r
- Storage->Guid.Data4[2],\r
- Storage->Guid.Data4[3],\r
- Storage->Guid.Data4[4],\r
- Storage->Guid.Data4[5],\r
- Storage->Guid.Data4[6],\r
- Storage->Guid.Data4[7],\r
- Storage->Size,\r
- TempStorage->Size\r
- );\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Update the VarStoreId for current question to get the variable guid and name information\r
- //\r
- TempStorage->VarStoreId = Storage->VarStoreId;\r
- TempStorage->FormSetOrder = Storage->FormSetOrder;\r
- RemoveEntryList (&Storage->Link);\r
- DestroyStorage(Storage);\r
- }\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
- //\r
- // Create a name/value Storage for this FormSet\r
- //\r
- Storage = CreateStorage (FormSet);\r
- Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
-\r
- CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-\r
- Storage->FormSetOrder = mFormSetOrderParse;\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_EFI_OP:\r
- //\r
- // Create a EFI variable Storage for this FormSet\r
- //\r
- Storage = CreateStorage (FormSet);\r
- Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r
- CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
- //\r
- // Check whether the EfiVarStore before UEFI2.31 or not\r
- //\r
- Storage->Size = sizeof (EFI_IFR_VARSTORE_EFI_OLD);\r
- if (((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Header.Length == sizeof (EFI_IFR_VARSTORE_EFI_OLD)) {\r
- Storage->NewEfiVarstore = FALSE;\r
- Storage->Size = 0;\r
- Storage->Buffer = NULL;\r
- Storage->Name = NULL;\r
- Storage->Size = 0;\r
- } else {\r
- //\r
- // EfiVarStore structure for UEFI2.31\r
- //\r
- Storage->NewEfiVarstore = TRUE;\r
- CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));\r
-\r
- Storage->Buffer = AllocateZeroPool (Storage->Size);\r
- AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;\r
- Storage->Name = AllocateZeroPool ((strlen (AsciiString) + 1) * 2);\r
- ASSERT (Storage->Name != NULL);\r
- for (Index = 0; AsciiString[Index] != 0; Index++) {\r
- Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
- }\r
- }\r
- Storage->FormSetOrder = mFormSetOrderParse;\r
- //\r
- // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.\r
- // If these two variales have the same Guid name but different size, report an error.\r
- //\r
- if ((TempStorage = NotSameVariableInVarList (FormSet->StorageListHead, Storage)) != NULL) {\r
- if (Storage->Size != TempStorage->Size) {\r
- StringPrint ("Error. Two modules found with EfiVarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but different sizes %d and %d.\n",\r
- Storage->Name,\r
- Storage->Guid.Data1,\r
- Storage->Guid.Data2,\r
- Storage->Guid.Data3,\r
- Storage->Guid.Data4[0],\r
- Storage->Guid.Data4[1],\r
- Storage->Guid.Data4[2],\r
- Storage->Guid.Data4[3],\r
- Storage->Guid.Data4[4],\r
- Storage->Guid.Data4[5],\r
- Storage->Guid.Data4[6],\r
- Storage->Guid.Data4[7],\r
- Storage->Size,\r
- TempStorage->Size\r
- );\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Update the VarStoreId for current question to get the variable guid and name information\r
- //\r
- TempStorage->VarStoreId = Storage->VarStoreId;\r
- TempStorage->FormSetOrder = Storage->FormSetOrder;\r
- RemoveEntryList (&Storage->Link);\r
- DestroyStorage( Storage);\r
- }\r
- break;\r
-\r
- //\r
- // DefaultStore\r
- //\r
- case EFI_IFR_DEFAULTSTORE_OP:\r
- HaveInserted = FALSE;\r
- DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
- ASSERT (DefaultStore != NULL);\r
- DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
-\r
- CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
- CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
-\r
- //\r
- // Insert it to the DefaultStore list of this Formset with ascending order.\r
- //\r
- if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
- DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
- while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
- PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
- DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
- if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r
- InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r
- HaveInserted = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
- if (!HaveInserted) {\r
- InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
- }\r
- break;\r
-\r
- //\r
- // Statements\r
- //\r
- case EFI_IFR_SUBTITLE_OP:\r
- CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
-\r
- if (Scope != 0) {\r
- mInScopeSubtitle = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_TEXT_OP:\r
- CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
-\r
- CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
- break;\r
-\r
- case EFI_IFR_RESET_BUTTON_OP:\r
- CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
- CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
- break;\r
-\r
- //\r
- // Questions\r
- //\r
- case EFI_IFR_ACTION_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
- //\r
- // No need to deal with the EFI_IFR_ACTION\r
- //\r
- break;\r
-\r
- case EFI_IFR_REF_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
- Value = &CurrentStatement->HiiValue;\r
- Value->Type = EFI_IFR_TYPE_REF;\r
- if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r
- CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
-\r
- if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
- CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
-\r
- if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
- CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
-\r
- if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
- CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
- }\r
- }\r
- }\r
- }\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OP:\r
- case EFI_IFR_NUMERIC_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT(CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
- Value = &CurrentStatement->HiiValue;\r
-\r
- if (BitFieldStorage) {\r
- //\r
- // Get the bit var store info (bit/byte offset, bit/byte offset)\r
- //\r
- CurrentStatement->QuestionReferToBitField = TRUE;\r
- CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
- CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
- CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
- TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
- CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
- //\r
- // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)\r
- //\r
- CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;\r
- CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;\r
- CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;\r
- } else {\r
- switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
- case EFI_IFR_NUMERIC_SIZE_1:\r
- CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
- CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
- CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_SIZE_2:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_SIZE_4:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_SIZE_8:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- if ((Operand == EFI_IFR_ONE_OF_OP) && (Scope != 0)) {\r
- SuppressForOption = TRUE;\r
- }\r
- //\r
- // Get the UQI information\r
- //\r
- PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r
- //\r
- // Exchange the Guid and name information between VarList and Question List\r
- //\r
- Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r
- //\r
- // Remove the question which isn't stored by EfiVarStore or VarStore\r
- //\r
- if (EFI_ERROR (Status)) {\r
- RemoveEntryList (&CurrentStatement->Link);\r
- DestroyStatement (FormSet, CurrentStatement);\r
- }\r
- break;\r
-\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT(CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
- CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
-\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
- CurrentStatement->BufferValue = NULL;\r
- if (Scope != 0) {\r
- SuppressForOption = TRUE;\r
- }\r
- //\r
- // Get the UQI information\r
- //\r
- PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r
- //\r
- // Exchange the Guid and name information between VarList and Question List\r
- //\r
- Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r
- //\r
- // Remove the question which isn't stored by EfiVarStore or VarStore\r
- //\r
- if (EFI_ERROR (Status)) {\r
- RemoveEntryList (&CurrentStatement->Link);\r
- DestroyStatement (FormSet, CurrentStatement);\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_CHECKBOX_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT(CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
-\r
- if (BitFieldStorage) {\r
- //\r
- // Get the bit var store info (bit/byte offset, bit/byte width)\r
- //\r
- CurrentStatement->QuestionReferToBitField = TRUE;\r
- CurrentStatement->BitStorageWidth = 1;\r
- CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
- CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
- TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
- CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
- }\r
- //\r
- // Get the UQI information\r
- //\r
- PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r
- //\r
- // Exchange the Guid and name information between VarList and Question List\r
- //\r
- Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r
- //\r
- // Remove the question which isn't stored by EfiVarStore or VarStore\r
- //\r
- if (EFI_ERROR (Status)) {\r
- RemoveEntryList (&CurrentStatement->Link);\r
- DestroyStatement (FormSet, CurrentStatement);\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_STRING_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
- //\r
- // MinSize is the minimum number of characters that can be accepted for this opcode,\r
- // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
- // The characters are stored as Unicode, so the storage width should multiply 2.\r
- //\r
- CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
- CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
- CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
- CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
-\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
- CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
- //\r
- // Get the UQI information\r
- //\r
- PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r
- //\r
- // Exchange the Guid and name information between VarList and Question List\r
- //\r
- Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r
- //\r
- // Remove the question which isn't stored by EfiVarStore or VarStore\r
- //\r
- if (EFI_ERROR (Status)) {\r
- RemoveEntryList (&CurrentStatement->Link);\r
- DestroyStatement (FormSet, CurrentStatement);\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_PASSWORD_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT (CurrentStatement != NULL);\r
- //\r
- // MinSize is the minimum number of characters that can be accepted for this opcode,\r
- // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
- // The characters are stored as Unicode, so the storage width should multiply 2.\r
- //\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
- CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
-\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
- CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
- break;\r
-\r
- case EFI_IFR_DATE_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT(CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
-\r
- if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
- } else {\r
- //\r
- // Don't assign storage for RTC type of date/time\r
- //\r
- CurrentStatement->Storage = NULL;\r
- CurrentStatement->StorageWidth = 0;\r
- }\r
- break;\r
-\r
- case EFI_IFR_TIME_OP:\r
- CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
- ASSERT(CurrentStatement != NULL);\r
-\r
- CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
- CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
-\r
- if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
- } else {\r
- //\r
- // Don't assign storage for RTC type of date/time\r
- //\r
- CurrentStatement->Storage = NULL;\r
- CurrentStatement->StorageWidth = 0;\r
- }\r
- break;\r
-\r
- //\r
- // Default\r
- //\r
- case EFI_IFR_DEFAULT_OP:\r
- //\r
- // EFI_IFR_DEFAULT appear in scope of a Question,\r
- // It creates a default value for the current question.\r
- // A Question may have more than one Default value which have different default types.\r
- //\r
- CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
- ASSERT (CurrentDefault != NULL);\r
- CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
-\r
- CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
- CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
- if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
- CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF(EFI_IFR_DEFAULT, Value));\r
- CurrentDefault->Value.Buffer = FceAllocateCopyPool(CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *)OpCodeData)->Value);\r
- ASSERT(CurrentDefault->Value.Buffer != NULL);\r
- } else {\r
- CopyMem(&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *)OpCodeData)->Value, OpCodeLength - OFFSET_OF(EFI_IFR_DEFAULT, Value));\r
- ExtendValueToU64(&CurrentDefault->Value);\r
- }\r
-\r
- //\r
- // Insert to Default Value list of current Question\r
- //\r
- InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
-\r
- if (Scope != 0) {\r
- InScopeDefault = TRUE;\r
- }\r
- break;\r
-\r
- //\r
- // Option\r
- //\r
- case EFI_IFR_ONE_OF_OPTION_OP:\r
- ASSERT (CurrentStatement != NULL);\r
- if (CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP &&\r
- ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r
- //\r
- // It's keep the default value for ordered list opcode.\r
- //\r
- CurrentDefault = AllocateZeroPool(sizeof (QUESTION_DEFAULT));\r
- ASSERT(CurrentDefault != NULL);\r
- CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
-\r
- CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r
- if ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
- CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
- } else {\r
- CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
- }\r
-\r
- CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF(EFI_IFR_ONE_OF_OPTION, Value));\r
- CurrentDefault->Value.Buffer = FceAllocateCopyPool(CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Value);\r
- ASSERT(CurrentDefault->Value.Buffer != NULL);\r
-\r
- //\r
- // Insert to Default Value list of current Question\r
- //\r
- InsertTailList(&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
- break;\r
- }\r
- //\r
- // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
- // It create a selection for use in current Question.\r
- //\r
- CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
- ASSERT (CurrentOption != NULL);\r
- CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
-\r
- CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
- CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
- CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
- CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
- ExtendValueToU64 (&CurrentOption->Value);\r
-\r
- if (InScopeOptionSuppress) {\r
- CurrentOption->SuppressExpression = OptionSuppressExpression;\r
- }\r
-\r
- //\r
- // Insert to Option list of current Question\r
- //\r
- InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
-\r
- //\r
- // Now we know the Storage width of nested Ordered List\r
- //\r
- if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
- Width = 1;\r
- switch (CurrentOption->Value.Type) {\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- Width = 1;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- Width = 2;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- Width = 4;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- Width = 8;\r
- break;\r
-\r
- default:\r
- //\r
- // Invalid type for Ordered List\r
- //\r
- break;\r
- }\r
-\r
- CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
- CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
- CurrentStatement->ValueType = CurrentOption->Value.Type;\r
- if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
- CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;\r
- CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;\r
- }\r
- }\r
- break;\r
-\r
- //\r
- // Conditional\r
- //\r
- case EFI_IFR_NO_SUBMIT_IF_OP:\r
- case EFI_IFR_INCONSISTENT_IF_OP:\r
- //\r
- // Create an Expression node\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
-\r
- if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
- InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
- } else {\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
- InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
- }\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_WARNING_IF_OP:\r
- //\r
- // Create an Expression node\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r
- CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r
- InsertTailList (&CurrentStatement->WarningListHead, &CurrentExpression->Link);\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_SUPPRESS_IF_OP:\r
- //\r
- // Question and Option will appear in scope of this OpCode\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
-\r
- if (CurrentForm == NULL) {\r
- InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
- } else {\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
- }\r
-\r
- if (SuppressForOption) {\r
- InScopeOptionSuppress = TRUE;\r
- OptionSuppressExpression = CurrentExpression;\r
- } else if (SuppressForQuestion) {\r
- mInScopeSuppress = TRUE;\r
- mSuppressExpression = CurrentExpression;\r
- } else {\r
- InScopeFormSuppress = TRUE;\r
- FormSuppressExpression = CurrentExpression;\r
- }\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_GRAY_OUT_IF_OP:\r
- //\r
- // Questions will appear in scope of this OpCode\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- mInScopeGrayOut = TRUE;\r
- mGrayOutExpression = CurrentExpression;\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_DISABLE_IF_OP:\r
- //\r
- // The DisableIf expression should only rely on constant, so it could be\r
- // evaluated at initialization and it will not be queued\r
- //\r
- CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
- ASSERT (CurrentExpression != NULL);\r
- CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
- InitializeListHead (&CurrentExpression->OpCodeListHead);\r
-\r
- if (CurrentForm != NULL) {\r
- //\r
- // This is DisableIf for Question, enqueue it to Form expression list\r
- //\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
- }\r
-\r
- mDisableExpression = CurrentExpression;\r
- mInScopeDisable = TRUE;\r
- OpCodeDisabled = FALSE;\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- //\r
- // Expression\r
- //\r
- case EFI_IFR_VALUE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- if (InScopeDefault) {\r
- //\r
- // Used for default (EFI_IFR_DEFAULT)\r
- //\r
- CurrentDefault->ValueExpression = CurrentExpression;\r
- } else {\r
- //\r
- // If used for a question, then the question will be read-only\r
- //\r
- //\r
- // Make sure CurrentStatement is not NULL.\r
- // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
- // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
- //\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->ValueExpression = CurrentExpression;\r
- }\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_RULE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
-\r
- CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_READ_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- //\r
- // Make sure CurrentStatement is not NULL.\r
- // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
- // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
- //\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->ReadExpression = CurrentExpression;\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_WRITE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- //\r
- // Make sure CurrentStatement is not NULL.\r
- // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
- // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
- //\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->WriteExpression = CurrentExpression;\r
-\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
-\r
- //\r
- // Image\r
- //\r
- case EFI_IFR_IMAGE_OP:\r
- //\r
- // Get ScopeOpcode from top of stack\r
- //\r
- PopScope (&ScopeOpCode);\r
- PushScope (ScopeOpCode);\r
-\r
- switch (ScopeOpCode) {\r
- case EFI_IFR_FORM_SET_OP:\r
- break;\r
-\r
- case EFI_IFR_FORM_OP:\r
- case EFI_IFR_FORM_MAP_OP:\r
- ASSERT (CurrentForm != NULL);\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OPTION_OP:\r
- break;\r
-\r
- default:\r
- //\r
- // Make sure CurrentStatement is not NULL.\r
- // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
- // file is wrongly generated by tools such as VFR Compiler.\r
- //\r
- ASSERT (CurrentStatement != NULL);\r
- break;\r
- }\r
- break;\r
-\r
- //\r
- // Refresh\r
- //\r
- case EFI_IFR_REFRESH_OP:\r
- break;\r
-\r
- //\r
- // Refresh guid.\r
- //\r
- case EFI_IFR_REFRESH_ID_OP:\r
- break;\r
-\r
- //\r
- // Modal tag\r
- //\r
- case EFI_IFR_MODAL_TAG_OP:\r
- break;\r
-\r
- //\r
- // Vendor specific\r
- //\r
- case EFI_IFR_GUID_OP:\r
- if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarGuid)==0) {\r
- Scope = 0;\r
- BitFieldStorage = TRUE;\r
- }\r
- break;\r
-\r
- //\r
- // Scope End\r
- //\r
- case EFI_IFR_END_OP:\r
- BitFieldStorage = FALSE;\r
- Status = PopScope (&ScopeOpCode);\r
- if (EFI_ERROR (Status)) {\r
- ResetScopeStack ();\r
- return Status;\r
- }\r
-\r
- switch (ScopeOpCode) {\r
- case EFI_IFR_FORM_SET_OP:\r
- //\r
- // End of FormSet, update FormSet IFR binary length\r
- // to stop parsing substantial OpCodes\r
- //\r
- FormSet->IfrBinaryLength = OpCodeOffset;\r
- break;\r
-\r
- case EFI_IFR_FORM_OP:\r
- case EFI_IFR_FORM_MAP_OP:\r
- //\r
- // End of Form\r
- //\r
- CurrentForm = NULL;\r
- SuppressForQuestion = FALSE;\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OPTION_OP:\r
- //\r
- // End of Option\r
- //\r
- CurrentOption = NULL;\r
- break;\r
-\r
- case EFI_IFR_SUBTITLE_OP:\r
- mInScopeSubtitle = FALSE;\r
- break;\r
-\r
- case EFI_IFR_NO_SUBMIT_IF_OP:\r
- case EFI_IFR_INCONSISTENT_IF_OP:\r
- case EFI_IFR_WARNING_IF_OP:\r
- //\r
- // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
- //\r
- break;\r
-\r
- case EFI_IFR_SUPPRESS_IF_OP:\r
- if (SuppressForOption) {\r
- InScopeOptionSuppress = FALSE;\r
- } else if (SuppressForQuestion) {\r
- mInScopeSuppress = FALSE;\r
- } else {\r
- InScopeFormSuppress = FALSE;\r
- }\r
- break;\r
-\r
- case EFI_IFR_GRAY_OUT_IF_OP:\r
- mInScopeGrayOut = FALSE;\r
- break;\r
-\r
- case EFI_IFR_DISABLE_IF_OP:\r
- mInScopeDisable = FALSE;\r
- OpCodeDisabled = FALSE;\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OP:\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- SuppressForOption = FALSE;\r
- break;\r
-\r
- case EFI_IFR_DEFAULT_OP:\r
- InScopeDefault = FALSE;\r
- break;\r
-\r
- case EFI_IFR_MAP_OP:\r
- //\r
- // Get current Map Expression List.\r
- //\r
- Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
- if (Status == EFI_ACCESS_DENIED) {\r
- MapExpressionList = NULL;\r
- }\r
- //\r
- // Get current expression.\r
- //\r
- Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
- ASSERT (!EFI_ERROR (Status));\r
- ASSERT (MapScopeDepth > 0);\r
- MapScopeDepth --;\r
- break;\r
-\r
- default:\r
- if (IsExpressionOpCode (ScopeOpCode)) {\r
- if (mInScopeDisable && (CurrentForm == NULL)) {\r
- //\r
- // This is DisableIf expression for Form, it should be a constant expression\r
- //\r
- ASSERT (CurrentExpression != NULL);\r
- ConstantFlag = TRUE;\r
- Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression, &ConstantFlag);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (!ConstantFlag) {\r
- StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");\r
- }\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
- //\r
- // DisableIf Expression is only used once and not queued, free it\r
- //\r
- DestroyExpression (CurrentExpression);\r
- }\r
-\r
- //\r
- // End of current Expression\r
- //\r
- CurrentExpression = NULL;\r
- }\r
- break;\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search an Option of a Question by its value.\r
-\r
- @param Question The Question\r
- @param OptionValue Value for Option to be searched.\r
-\r
- @retval Pointer Pointer to the found Option.\r
- @retval NULL Option not found.\r
-\r
-**/\r
-QUESTION_OPTION *\r
-ValueToOption (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN EFI_HII_VALUE *OptionValue\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- QUESTION_OPTION *Option;\r
-\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
-\r
- if (CompareHiiValue (&Option->Value, OptionValue, FormSet) == 0) {\r
- return Option;\r
- }\r
-\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-/**\r
- Set value of a data element in an Array by its Index.\r
-\r
- @param Array The data array.\r
- @param Type Type of the data in this array.\r
- @param Index Zero based index for data in this array.\r
- @param Value The value to be set.\r
-\r
-**/\r
-VOID\r
-SetArrayData (\r
- IN VOID *Array,\r
- IN UINT8 Type,\r
- IN UINTN Index,\r
- IN UINT64 Value\r
- )\r
-{\r
-\r
- ASSERT (Array != NULL);\r
-\r
- switch (Type) {\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-/**\r
- Reset Question of five kinds to its default value.\r
-\r
- @param FormSet The form set.\r
- @param Form The form.\r
- @param Question The question.\r
- @param DefaultId The default Id.\r
- @param DefaultId The platform Id.\r
-\r
- @retval EFI_SUCCESS Question is reset to default value.\r
-\r
-**/\r
-EFI_STATUS\r
-GetQuestionDefault (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- QUESTION_DEFAULT *Default;\r
- QUESTION_OPTION *Option;\r
- EFI_HII_VALUE *HiiValue;\r
- UINT8 Index;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 *VarBuffer;\r
- BOOLEAN ConstantFlag;\r
- UINT16 OriginalDefaultId;\r
- FORMSET_DEFAULTSTORE *DefaultStore;\r
- LIST_ENTRY *DefaultLink;\r
- CHAR16 *VarDefaultName;\r
-\r
- VarDefaultName = NULL;\r
- Status = EFI_SUCCESS;\r
- ConstantFlag = TRUE;\r
- OriginalDefaultId = DefaultId;\r
- DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
-\r
- //\r
- // Statement don't have storage, skip them\r
- //\r
- if (Question->QuestionId == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Return if no any kinds of\r
- //\r
- if ((Question->Operand != EFI_IFR_CHECKBOX_OP)\r
- && (Question->Operand != EFI_IFR_ONE_OF_OP)\r
- && (Question->Operand != EFI_IFR_ORDERED_LIST_OP)\r
- && (Question->Operand != EFI_IFR_NUMERIC_OP)\r
- && (Question->Operand != EFI_IFR_STRING_OP)\r
- ) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Search the variable for this question (Compatible with the old EfiVarStore before UEFI2.31)\r
- //\r
-\r
- //\r
- //VarStoreInfoDepending on the type of variable store selected,\r
- //this contains either a 16-bit Buffer Storage offset (VarOffset)\r
- //or a Name/Value or EFI Variable name (VarName).\r
- //\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- FormSet->StorageListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- //\r
- // There are three ways to specify default value for a Question:\r
- // 1, use nested EFI_IFR_DEFAULT\r
- // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
- // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
- //\r
-ReGetDefault:\r
- HiiValue = &Question->HiiValue;\r
- //\r
- // EFI_IFR_DEFAULT has highest priority\r
- //\r
- if (!IsListEmpty (&Question->DefaultListHead)) {\r
- Link = GetFirstNode (&Question->DefaultListHead);\r
- while (!IsNull (&Question->DefaultListHead, Link)) {\r
- Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
-\r
- if (Default->DefaultId == DefaultId) {\r
- if (Default->ValueExpression != NULL) {\r
- //\r
- // Default is provided by an Expression, evaluate it\r
- //\r
- Status = EvaluateExpression (FormSet, Form, Default->ValueExpression, &ConstantFlag);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
- if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) {\r
- CopyMem(Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);\r
- Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen;\r
- } else {\r
- CopyMem(Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth);\r
- Question->HiiValue.BufferLen = Question->StorageWidth;\r
- }\r
- FreePool(Default->ValueExpression->Result.Buffer);\r
- }\r
- HiiValue->Type = Default->ValueExpression->Result.Type;\r
- CopyMem(&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
- } else {\r
- //\r
- // Default value is embedded in EFI_IFR_DEFAULT\r
- //\r
- if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
- CopyMem(HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen);\r
- } else {\r
- CopyMem(HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
- }\r
- }\r
- if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
- CopyMem(VarBuffer, HiiValue->Buffer, HiiValue->BufferLen);\r
- } else if (HiiValue->Type == EFI_IFR_TYPE_STRING){\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- HiiValue->Value.string,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- if (VarDefaultName == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
- if (Question->StorageWidth > FceStrSize(VarDefaultName)) {\r
- ZeroMem (VarBuffer, Question->StorageWidth);\r
- CopyMem (VarBuffer, VarDefaultName, FceStrSize(VarDefaultName));\r
- } else {\r
- CopyMem (VarBuffer, VarDefaultName, Question->StorageWidth);\r
- }\r
- } else {\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem(VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- if (Default->DefaultId == DefaultId) {\r
- return EFI_SUCCESS;\r
- }\r
- Link = GetNextNode (&Question->DefaultListHead, Link);\r
- }\r
- }\r
-\r
- if (HiiValue->Buffer == NULL) {\r
- ZeroMem (HiiValue, sizeof (EFI_HII_VALUE));\r
- }\r
-\r
- //\r
- // EFI_ONE_OF_OPTION\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
- if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
- //\r
- // OneOfOption could only provide Standard and Manufacturing default\r
- //\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
-\r
- if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r
- ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r
- ) {\r
- CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
- }\r
- }\r
-\r
- //\r
- // EFI_IFR_CHECKBOX - lowest priority\r
- //\r
- if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
- if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
- //\r
- // Checkbox could only provide Standard and Manufacturing default\r
- //\r
- if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||\r
- ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
- ) {\r
- HiiValue->Value.b = TRUE;\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r
- // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r
- // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r
- //\r
- while (!IsNull(&FormSet->DefaultStoreListHead, DefaultLink)) {\r
- DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
- DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead,DefaultLink);\r
- DefaultId = DefaultStore->DefaultId;\r
- if (DefaultId == OriginalDefaultId) {\r
- continue;\r
- }\r
- goto ReGetDefault;\r
- }\r
-\r
- //\r
- // For Questions without default\r
- //\r
- Status = EFI_NOT_FOUND;\r
- switch (Question->Operand) {\r
- case EFI_IFR_CHECKBOX_OP:\r
- HiiValue->Value.b = FALSE;\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
- //\r
- // Take minimum value as numeric default value\r
- //\r
- if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r
- HiiValue->Value.u64 = Question->Minimum;\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OP:\r
- //\r
- // Take first oneof option as oneof's default value\r
- //\r
- if (ValueToOption (FormSet, Question, HiiValue) == NULL) {\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- if (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
- CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
- if (Question->QuestionReferToBitField) {\r
- SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r
- } else {\r
- CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- //\r
- // Take option sequence in IFR as ordered list's default value\r
- //\r
- Index = 0;\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
-\r
- SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r
- SetArrayData (VarBuffer, Question->ValueType, Index, Option->Value.Value.u64);\r
-\r
- Index++;\r
- if (Index >= Question->MaxContainers) {\r
- break;\r
- }\r
-\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Set the value to the variable of platformId question.\r
-\r
- @param PlatformId The form set.\r
-\r
- @retval EFI_SUCCESS Set successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-AssignThePlatformId (\r
- IN UINT64 PlatformId\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORMSET_STORAGE *VarList;\r
- UINT8 *VarBuffer;\r
-\r
- Status = EFI_SUCCESS;\r
- VarBuffer = NULL;\r
- //\r
- // Set the Storage\r
- //\r
- Status = SearchVarStorage (\r
- &mMultiPlatformParam.PlatformIdQuestion,\r
- NULL,\r
- mMultiPlatformParam.PlatformIdQuestion.VarStoreInfo.VarOffset,\r
- &mVarListEntry,\r
- (CHAR8 **)&VarBuffer,\r
- &VarList\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- CopyMem (VarBuffer, &PlatformId, mMultiPlatformParam.PlatformIdWidth);\r
- //\r
- // Set the HIIvalue of this questions\r
- //\r
- CopyMem (&mMultiPlatformParam.Question->HiiValue.Value.u64, &PlatformId, mMultiPlatformParam.PlatformIdWidth);\r
-\r
- switch (mMultiPlatformParam.PlatformIdWidth) {\r
- case sizeof (UINT8):\r
- mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
-\r
- case sizeof (UINT16):\r
- mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
-\r
- case sizeof (UINT32):\r
- mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
- break;\r
-\r
- case sizeof (UINT64):\r
- mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- break;\r
-\r
- default:\r
- mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-/**\r
- Reset Questions to their default value in a Form, Formset or System.\r
-\r
- @param FormSet FormSet data structure.\r
- @param Form Form data structure.\r
- @param DefaultId The default Id\r
- @param PlatformId The platform Id\r
- @param SettingScope Setting Scope for Default action.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
-\r
-**/\r
-EFI_STATUS\r
-ExtractDefault (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId,\r
- IN BROWSER_SETTING_SCOPE SettingScope\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *FormLink;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *FormSetEntryListHead;\r
- FORM_BROWSER_STATEMENT *Question;\r
- //\r
- // Check the supported setting level.\r
- //\r
- if (SettingScope >= MaxLevel) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (SettingScope == FormLevel) {\r
- //\r
- // Extract Form default\r
- //\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- while (!IsNull (&Form->StatementListHead, Link)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
- //\r
- // Re-set the platformId before calcuate the platformId of every question to avoid over-written.\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- Status = AssignThePlatformId (PlatformId);\r
- if (EFI_ERROR (Status)) {\r
- StringPrint ("Error. Failed to assign the platformId.\n");\r
- return Status;\r
- }\r
- }\r
- //\r
- // Reset Question to its default value, and store the default to variable\r
- //\r
- Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, PlatformId);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- }\r
- } else if (SettingScope == FormSetLevel) {\r
- FormLink = GetFirstNode (&FormSet->FormListHead);\r
- while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
- ExtractDefault (FormSet, Form, DefaultId, PlatformId, FormLevel);\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- }\r
- } else if (SettingScope == SystemLevel) {\r
- //\r
- // Parse Fromset one by one\r
- //\r
- FormSetEntryListHead = &mFormSetListEntry;\r
-\r
- FormLink = GetFirstNode (FormSetEntryListHead);\r
- while (!IsNull (FormSetEntryListHead, FormLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormLink);\r
- ExtractDefault (FormSet, NULL, DefaultId, PlatformId, FormSetLevel);\r
- FormLink = GetNextNode (FormSetEntryListHead, FormLink);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check whether existed the UQI in Current Unicode String.\r
-\r
- @param UniPackge A pointer to a Null-terminated Unicode string Array.\r
-\r
- @return TRUE If find the uqi, return TRUE\r
- @return FALSE Otherwise, return FALSE\r
-\r
-**/\r
-static\r
-BOOLEAN\r
-IsUqiOrNot (\r
- IN UINT8 *UniPackge\r
- )\r
-{\r
- CHAR8 *UniBin;\r
- UINTN UniLength;\r
- UINTN Index;\r
- BOOLEAN FindIt;\r
-\r
- UniBin = (CHAR8 *) UniPackge + 4;\r
- Index = 4;\r
- FindIt = FALSE;\r
- UniLength = *(UINT32 *) UniPackge;\r
-\r
- if (((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r
- //\r
- // Search the uqi language\r
- //\r
- while ((Index < UniLength) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS){\r
- if (!strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "uqi")) {\r
- FindIt = TRUE;\r
- break;\r
- }\r
- Index = Index + ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r
- }\r
- }\r
- return FindIt;\r
-}\r
-\r
- /**\r
- Returns Length of UQI string (in CHAR16) (not including null termination).\r
-\r
- @param UniPackge A pointer to a UQI string.\r
-\r
- @return Number Length of UQIL string (in words) or 0\r
-\r
-**/\r
-static\r
-UINT16\r
-GetUqiNum (\r
- IN CHAR16 *UniString\r
- )\r
-{\r
- UINT16 Number;\r
-\r
- if (UniString == NULL) {\r
- return 0;\r
- }\r
- for (Number = 0; UniString[Number] != 0; Number++) {\r
- ;\r
- }\r
- return Number;\r
-}\r
-\r
-/**\r
- Print the formset title information.\r
-\r
- @param FormSet The pointer to the formset.\r
-\r
- @return NULL.\r
-\r
-**/\r
-static\r
-VOID\r
-StringPrintormSetTitle (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- CHAR16 *VarDefaultName;\r
- EFI_STATUS Status;\r
-\r
- VarDefaultName = NULL;\r
-\r
- StringPrint("\n\n// Form Set: ");\r
-\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- FormSet->FormSetTitle,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
-\r
- StringPrint("\n// %s",FORM_SET_GUID_PREFIX);\r
- StringPrint(\r
- EFI_GUID_FORMAT,\r
- FormSet->Guid.Data1, FormSet->Guid.Data2,\r
- FormSet->Guid.Data3, FormSet->Guid.Data4[0],\r
- FormSet->Guid.Data4[1],FormSet->Guid.Data4[2],\r
- FormSet->Guid.Data4[3],FormSet->Guid.Data4[4],\r
- FormSet->Guid.Data4[5],FormSet->Guid.Data4[6],\r
- FormSet->Guid.Data4[7]);\r
- StringPrint("\n");\r
-\r
- if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && FormSet->FormSetTitle != 0) {\r
- free (VarDefaultName);\r
- VarDefaultName = NULL;\r
- }\r
-}\r
-\r
-/**\r
- Print the formset title information.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param Question The pointer to the question of ONE_OF.\r
-\r
- @return NULL.\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-PrintOneOfOptions (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- QUESTION_OPTION *Option;\r
- CHAR16 *VarDefaultName;\r
- EFI_STATUS Status;\r
-\r
- Status = EFI_SUCCESS;\r
- VarDefaultName = NULL;\r
-\r
- if ((Question->Operand != EFI_IFR_ONE_OF_OP)\r
- && (Question->Operand != EFI_IFR_ORDERED_LIST_OP)\r
- ) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Link = GetFirstNode (&Question->OptionListHead);\r
- while (!IsNull (&Question->OptionListHead, Link)) {\r
- Option = QUESTION_OPTION_FROM_LINK (Link);\r
- if (Question->QuestionReferToBitField) {\r
- StringPrint("// %08X = ", Option->Value.Value.u32);\r
- } else {\r
- switch(Option->Value.Type) {\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- StringPrint("// %02X = ", Option->Value.Value.u8);\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- StringPrint("// %04X = ", Option->Value.Value.u16);\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- StringPrint("// %08X = ", Option->Value.Value.u32);\r
- break;\r
-\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- StringPrint("// %016llX = ", Option->Value.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- StringPrint("// %X = ", Option->Value.Value.b);\r
- break;\r
-\r
- case EFI_IFR_TYPE_STRING:\r
- StringPrint("// %X = ", Option->Value.Value.string);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Option->Text,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
-\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && Option->Text != 0) {\r
- free (VarDefaultName);\r
- VarDefaultName = NULL;\r
- }\r
- Link = GetNextNode (&Question->OptionListHead, Link);\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Print the form title information.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param FormSet The pointer to the form.\r
-\r
- @return NULL.\r
-\r
-**/\r
-static\r
-VOID\r
-StringPrintormTitle (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- CHAR16 *VarDefaultName;\r
- EFI_STATUS Status;\r
-\r
- VarDefaultName = NULL;\r
-\r
- StringPrint("\n// Form: ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Form->FormTitle,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
-\r
- if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && Form->FormTitle != 0) {\r
- free (VarDefaultName);\r
- VarDefaultName = NULL;\r
- }\r
-\r
-}\r
-\r
-/**\r
- Print the information of questions.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param FormSet The pointer to the form.\r
- @param Question The pointer to the question.\r
- @param PrintOrNot Decide whether print or not.\r
-\r
- @return NULL.\r
-\r
-**/\r
-static\r
-VOID\r
-PrintQuestion (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN BOOLEAN PrintOrNot\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 *VarDefaultName;\r
- UINT16 UqiStringLength;\r
- BOOLEAN HaveUQIlanguage;\r
-\r
- Status = EFI_SUCCESS;\r
- VarDefaultName = NULL;\r
- UqiStringLength = 0;\r
-\r
- HaveUQIlanguage = IsUqiOrNot (FormSet->UnicodeBinary);\r
-\r
- switch (Question->Operand) {\r
-\r
- case EFI_IFR_SUBTITLE_OP:\r
- if (PrintOrNot) {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- if ((VarDefaultName != NULL) && (FceStrCmp (VarDefaultName, L"") != 0)) {\r
- StringPrint("// Subtitle: ");\r
- StringPrint("// ");\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OP:\r
-\r
- if( HaveUQIlanguage ) {\r
- Status = FindDefaultName (\r
- &(FormSet->UqiStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- UQI,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- } else {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
-\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- }\r
- //\r
- //Record the UQi to the Question\r
- //\r
- Question->Uqi.HexNum = UqiStringLength;\r
- Question->Uqi.Data = VarDefaultName;\r
- Question->Uqi.Type = ONE_OF;\r
-\r
- if (PrintOrNot) {\r
- StringPrint("ONE_OF ");\r
-\r
- LogIfrValue (\r
- FormSet,\r
- Question\r
- );\r
- StringPrint(" // ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- //\r
- // Print ONE_OF_OPTION\r
- //\r
- PrintOneOfOptions (FormSet, Question);\r
- }\r
- break;\r
-\r
- case EFI_IFR_CHECKBOX_OP:\r
-\r
- if( HaveUQIlanguage ) {\r
- Status = FindDefaultName (\r
- &(FormSet->UqiStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- UQI,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- } else {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
-\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- }\r
- //\r
- //Record the UQi to the HiiObjList\r
- //\r
- Question->Uqi.HexNum = UqiStringLength;\r
- Question->Uqi.Data = VarDefaultName;\r
- Question->Uqi.Type = CHECKBOX;\r
- if (PrintOrNot) {\r
- StringPrint("CHECKBOX ");\r
- LogIfrValue (\r
- FormSet,\r
- Question\r
- );\r
- StringPrint(" // ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- StringPrint("// 0 = Unchecked\n");\r
- StringPrint("// 1 = Checked\n");\r
- }\r
- break;\r
-\r
- case EFI_IFR_STRING_OP:\r
- if( HaveUQIlanguage ) {\r
- Status = FindDefaultName (\r
- &(FormSet->UqiStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- UQI,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- } else {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
-\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- }\r
- //\r
- //Record the UQi to the HiiObjList\r
- //\r
- Question->Uqi.HexNum = UqiStringLength;\r
- Question->Uqi.Data = VarDefaultName;\r
- Question->Uqi.Type = STRING;\r
- if (PrintOrNot) {\r
- StringPrint("STRING ");\r
- LogIfrValueStr (\r
- FormSet,\r
- Question\r
- );\r
- StringPrint(" // ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- }\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
-\r
- if( HaveUQIlanguage ) {\r
- Status = FindDefaultName (\r
- &(FormSet->UqiStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- UQI,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- } else {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- }\r
- //\r
- //Record the UQi to the HiiObjList\r
- //\r
- Question->Uqi.HexNum = UqiStringLength;\r
- Question->Uqi.Data = VarDefaultName;\r
- Question->Uqi.Type = NUMERIC;\r
- if (PrintOrNot) {\r
- StringPrint("NUMERIC ");\r
- LogIfrValue (\r
- FormSet,\r
- Question\r
- );\r
- StringPrint(" // ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
-\r
- if (Question->QuestionReferToBitField) {\r
- StringPrint("// Minimum = %08llX \n", Question->Minimum);\r
- StringPrint("// Maximum = %08llX \n", Question->Maximum);\r
- StringPrint("// Step = %08llX \n", Question->Step);\r
- } else {\r
- switch (Question->StorageWidth) {\r
-\r
- case sizeof (UINT8):\r
- StringPrint("// Minimum = %02llX \n", Question->Minimum);\r
- StringPrint("// Maximum = %02llX \n", Question->Maximum);\r
- StringPrint("// Step = %02llX \n", Question->Step);\r
- break;\r
-\r
- case sizeof (UINT16):\r
- StringPrint("// Minimum = %04llX \n", Question->Minimum);\r
- StringPrint("// Maximum = %04llX \n", Question->Maximum);\r
- StringPrint("// Step = %04llX \n", Question->Step);\r
- break;\r
-\r
- case sizeof (UINT32):\r
- StringPrint("// Minimum = %08llX \n", Question->Minimum);\r
- StringPrint("// Maximum = %08llX \n", Question->Maximum);\r
- StringPrint("// Step = %08llX \n", Question->Step);\r
- break;\r
-\r
- case sizeof (UINT64):\r
- StringPrint("// Minimum = %016llX \n", Question->Minimum);\r
- StringPrint("// Maximum = %016llX \n", Question->Maximum);\r
- StringPrint("// Step = %016llX \n", Question->Step);\r
- break;\r
-\r
- default:\r
- StringPrint("0000 // Width > 16 is not supported -- FAILURE");\r
- break;\r
- }\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_ORDERED_LIST_OP:\r
-\r
- if( HaveUQIlanguage ) {\r
- Status = FindDefaultName (\r
- &(FormSet->UqiStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- UQI,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
-\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- } else {\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
-\r
- assert (!EFI_ERROR (Status));\r
-\r
- UqiStringLength = GetUqiNum (VarDefaultName);\r
- if (PrintOrNot) {\r
- if (UqiStringLength > 0) {\r
- StringPrint("\nQ %04X ", UqiStringLength);\r
- LogUqi(VarDefaultName);\r
- } else {\r
- StringPrint("\n// [No UQI] ");\r
- }\r
- }\r
- }\r
- //\r
- //Record the UQi to the HiiObjList\r
- //\r
- Question->Uqi.HexNum = UqiStringLength;\r
- Question->Uqi.Data = VarDefaultName;\r
- Question->Uqi.Type = ORDERED_LIST;\r
-\r
- if (PrintOrNot) {\r
- StringPrint("ORDERED_LIST %04X ", Question->MaxContainers);\r
-\r
- LogIfrValueList (\r
- FormSet,\r
- Question\r
- );\r
- StringPrint(" // ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Prompt,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- }\r
- //\r
- // Print ONE_OF_OPTION\r
- //\r
- PrintOneOfOptions (FormSet, Question);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- if (&(FormSet->EnUsStringList) == NULL &&VarDefaultName != NULL && Question->Prompt != 0) {\r
- free (VarDefaultName);\r
- VarDefaultName = NULL;\r
- }\r
-\r
- if (PrintOrNot && Question->Storage) {\r
- StringPrint("// size = 0x%x", Question->StorageWidth);\r
- StringPrint("\n// offset = 0x%x", Question->VarStoreInfo.VarOffset);\r
- StringPrint("\n// name = ");\r
- LogUnicodeString(Question->VariableName);\r
- StringPrint("\n// guid = ");\r
- StringPrint(\r
- EFI_GUID_FORMAT,\r
- Question->Guid.Data1, Question->Guid.Data2,\r
- Question->Guid.Data3, Question->Guid.Data4[0],\r
- Question->Guid.Data4[1],Question->Guid.Data4[2],\r
- Question->Guid.Data4[3],Question->Guid.Data4[4],\r
- Question->Guid.Data4[5],Question->Guid.Data4[6],\r
- Question->Guid.Data4[7]\r
- );\r
- StringPrint("\n// attribute = 0x%x", Question->Attributes);\r
- StringPrint("\n// help = ");\r
- Status = FindDefaultName (\r
- &(FormSet->EnUsStringList),\r
- FormSet->UnicodeBinary,\r
- Question->Help,\r
- EN_US,\r
- &VarDefaultName\r
- );\r
- assert (!EFI_ERROR (Status));\r
- LogUnicodeString (VarDefaultName);\r
- StringPrint("\n");\r
- if (&(FormSet->EnUsStringList) == NULL &&VarDefaultName != NULL && Question->Help != 0) {\r
- free (VarDefaultName);\r
- VarDefaultName = NULL;\r
- }\r
- }\r
-\r
-}\r
-\r
-/**\r
- Check whether current Formset or Form is NULL. If no valid questions, return FASLE.\r
-\r
- @param FormSet The pointer to the formset.\r
- @param FormSet The pointer to the form.\r
- @param IsFormSet FormSet or Form.\r
-\r
- @retval TRUE\r
- @return FALSE\r
-**/\r
-BOOLEAN\r
-CheckFormSetOrFormNull (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN BOOLEAN IsFormSet\r
- )\r
-{\r
- LIST_ENTRY *FormLink;\r
- FORM_BROWSER_STATEMENT *Question;\r
- LIST_ENTRY *QuestionLink;\r
-\r
- FormLink = NULL;\r
- Question = NULL;\r
- QuestionLink = NULL;\r
-\r
- //\r
- // Parse all forms in formset\r
- //\r
- if (IsFormSet) {\r
- FormLink = GetFirstNode (&FormSet->FormListHead);\r
-\r
- while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r
- //\r
- if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- if (Question->Type == EFI_IFR_VARSTORE_EFI_OP\r
- && Question->NewEfiVarstore\r
- && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- }\r
- //\r
- //If invalid variable type, skip it.\r
- //\r
- if ((Question->Type != EFI_IFR_VARSTORE_EFI_OP)\r
- && (Question->Type != EFI_IFR_VARSTORE_OP)) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- return TRUE;\r
- }\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- }\r
-\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- }\r
- } else {\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- //\r
- // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r
- //\r
- if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- if ((Question->Type == EFI_IFR_VARSTORE_EFI_OP)\r
- && Question->NewEfiVarstore\r
- && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- }\r
- //\r
- //If invalid variable type, skip it.\r
- //\r
- if ((Question->Type != EFI_IFR_VARSTORE_EFI_OP)\r
- && (Question->Type != EFI_IFR_VARSTORE_OP)) {\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- continue;\r
- }\r
- return TRUE;\r
- }\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- }\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Print all ONE_OF ORDER_LIST NUMERIC STRING and CHECKBOX in all fromsets.\r
-\r
- @param Formset The pointer to the entry of the fromset list\r
- @param Formset The pointer to the entry of the storage list\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-PrintInfoInAllFormset (\r
- IN LIST_ENTRY *FormSetEntryListHead,\r
- IN LIST_ENTRY *StorageEntryListHead\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *FormSetLink;\r
- LIST_ENTRY *FormLink;\r
- FORM_BROWSER_FORM *Form;\r
- FORM_BROWSER_STATEMENT *Question;\r
- LIST_ENTRY *QuestionLink;\r
- FORMSET_STORAGE *Storage;\r
- CHAR8 *VarBuffer;\r
- LIST_ENTRY *TempStorageLink;\r
- UINT32 Index;\r
- BOOLEAN Skip;\r
- BOOLEAN ConstantFlag;\r
-\r
- Status = EFI_SUCCESS;\r
- FormSet = NULL;\r
- FormSetLink = NULL;\r
- FormLink = NULL;\r
- Form = NULL;\r
- Question = NULL;\r
- QuestionLink = NULL;\r
- Storage = NULL;\r
- VarBuffer = NULL;\r
- TempStorageLink = NULL;\r
- Index = 0;\r
- Skip = FALSE;\r
- ConstantFlag = TRUE;\r
- //\r
- // Print platformId, defaultId and platformIdUqi\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot) {\r
- StringPrint("\n\n// FCEKEY DEFAULT_ID:");\r
- TempStorageLink = GetFirstNode (StorageEntryListHead);\r
- Storage = FORMSET_STORAGE_FROM_LINK (TempStorageLink);\r
- for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r
- StringPrint (" %4d", Storage->DefaultId[Index]);\r
- }\r
- StringPrint("\n\n//FCEKEY PLATFORM_ID:");\r
- for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r
- StringPrint (" %4lld", Storage->PlatformId[Index]);\r
- }\r
- if (mMultiPlatformParam.Uqi.Data != NULL) {\r
- StringPrint("\n\n//FCEKEY PLATFORM_UQI:");\r
- StringPrint(" %04X ", mMultiPlatformParam.Uqi.HexNum);\r
- LogUqi(mMultiPlatformParam.Uqi.Data);\r
- }\r
- }\r
- FormSetLink = GetFirstNode (FormSetEntryListHead);\r
- while (!IsNull (FormSetEntryListHead, FormSetLink)) {\r
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r
- //\r
- //Assign the new storage list\r
- //\r
- FormSet->StorageListHead = StorageEntryListHead;\r
-\r
- if (CheckFormSetOrFormNull (FormSet, NULL, TRUE)) {\r
- StringPrintormSetTitle (FormSet);\r
- } else {\r
- FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r
- continue;\r
- }\r
- //\r
- // Parse all forms in formset\r
- //\r
- FormLink = GetFirstNode (&FormSet->FormListHead);\r
-\r
- while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
-\r
- if (CheckFormSetOrFormNull (NULL, Form, FALSE)) {\r
- StringPrintormTitle(FormSet,Form);\r
- } else {\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- continue;\r
- }\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- QuestionLink = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
- //\r
- // Parse five kinds of Questions in Form\r
- //\r
- if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r
- || (Question->Operand == EFI_IFR_NUMERIC_OP)\r
- || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r
- || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r
- || (Question->Operand == EFI_IFR_SUBTITLE_OP)\r
- || (Question->Operand == EFI_IFR_STRING_OP)\r
- ) {\r
- Skip = FALSE;\r
-\r
- //\r
- //Only output the questions stored by EFI_IFR_VARSTORE_EFI_OP.\r
- //\r
- if (mMultiPlatformParam.MultiPlatformOrNot\r
- && (Question->Operand != EFI_IFR_SUBTITLE_OP)\r
- ) {\r
- Status = SearchVarStorage (\r
- Question,\r
- NULL,\r
- Question->VarStoreInfo.VarOffset,\r
- StorageEntryListHead,\r
- (CHAR8 **)&VarBuffer,\r
- &Storage\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Skip = TRUE;\r
- }\r
- }\r
- //\r
- // If Question is constant expression and "disabledIf True", don't output it.\r
- //\r
- ConstantFlag = TRUE;\r
- if (!Skip && (Question->DisableExpression != NULL)) {\r
- Status = EvaluateExpression (FormSet, Form, Question->DisableExpression, &ConstantFlag);\r
- if (!EFI_ERROR (Status) && Question->DisableExpression->Result.Value.b && ConstantFlag) {\r
- Skip = TRUE;\r
- }\r
- }\r
-\r
- if (!Skip) {\r
- PrintQuestion(FormSet, Form, Question, TRUE);\r
- }\r
- }\r
- QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
- }\r
-\r
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
- }\r
- FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- Parser for IFR binary encoding.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _IFR_PARSE_H_\r
-#define _IFR_PARSE_H_\r
-\r
-#include "Common.h"\r
-#include <Common/UefiInternalFormRepresentation.h>\r
-#include <Common/MdeModuleHii.h>\r
-\r
-//\r
-// Scope for Browser action. It may be Form, FormSet or System level.\r
-//\r
-typedef enum {\r
- FormLevel,\r
- FormSetLevel,\r
- SystemLevel,\r
- MaxLevel\r
-} BROWSER_SETTING_SCOPE;\r
-\r
-///\r
-///Old EFI_IFR_VARSTORE_EFI structure to complible with UEFI 2.3\r
-///\r
-typedef struct _EFI_IFR_VARSTORE_EFI_OLD {\r
- EFI_IFR_OP_HEADER Header;\r
- EFI_VARSTORE_ID VarStoreId;\r
- EFI_GUID Guid;\r
- UINT32 Attributes;\r
-} EFI_IFR_VARSTORE_EFI_OLD;\r
-\r
-///\r
-/// The languages used in HII DB\r
-///\r
-typedef enum {\r
- UQI,\r
- EN_US,\r
- ENG\r
-} LANGUAGE;\r
-\r
-///\r
-/// Define the structure for the parameters of Uqi and Uqi List\r
-///\r
-typedef struct _FORM_BROWSER_STATEMENT FORM_BROWSER_STATEMENT;\r
-\r
-typedef enum {\r
- ONE_OF,\r
- NUMERIC,\r
- CHECKBOX,\r
- STRING,\r
- ORDERED_LIST\r
-} QUEST_TYPE;\r
-\r
-typedef struct {\r
- UINT16 *DefaultId;\r
- UINT64 *PlatformId;\r
- UINT32 IdNum;\r
- UINT32 HexNum;\r
- QUEST_TYPE Type;\r
- CHAR16 *Data;\r
- UINT8 *Value;\r
- UINT8 *DiffValue;\r
- UINT32 ScriptsLine;\r
- FORM_BROWSER_STATEMENT *Question;\r
-} UQI_HEADER;\r
-\r
-typedef struct _UQI_PARAM_LIST {\r
- struct _UQI_PARAM_LIST *Next;\r
- UQI_HEADER Header;\r
- BOOLEAN ParseOrNot;\r
- BOOLEAN SameOrNot;\r
- BOOLEAN ErrorOrNot;\r
- CHAR8 *Error;\r
-} UQI_PARAM_LIST;\r
-\r
-//\r
-// Incremental size of stack for expression\r
-//\r
-#define EXPRESSION_STACK_SIZE_INCREMENT 0x100\r
-\r
-//\r
-// IFR relative definition\r
-//\r
-#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0\r
-#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1\r
-#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2\r
-#define EFI_HII_EXPRESSION_SUPPRESS_IF 3\r
-#define EFI_HII_EXPRESSION_DISABLE_IF 4\r
-#define EFI_HII_EXPRESSION_VALUE 5\r
-#define EFI_HII_EXPRESSION_RULE 6\r
-#define EFI_HII_EXPRESSION_READ 7\r
-#define EFI_HII_EXPRESSION_WRITE 8\r
-#define EFI_HII_EXPRESSION_WARNING_IF 9\r
-\r
-#define EFI_HII_VARSTORE_BUFFER 0\r
-#define EFI_HII_VARSTORE_NAME_VALUE 1\r
-#define EFI_HII_VARSTORE_EFI_VARIABLE 2\r
-#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3\r
-\r
-#define FORM_INCONSISTENT_VALIDATION 0\r
-#define FORM_NO_SUBMIT_VALIDATION 1\r
-\r
-typedef struct {\r
- //\r
- // HII Data Type\r
- //\r
- UINT8 Type;\r
- //\r
- // Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE_STRING\r
- //\r
- UINT8 *Buffer;\r
- UINT16 BufferLen;\r
- EFI_IFR_TYPE_VALUE Value;\r
-} EFI_HII_VALUE;\r
-\r
-#define NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- CHAR16 *Name;\r
- CHAR16 *Value;\r
- CHAR16 *EditValue;\r
-} NAME_VALUE_NODE;\r
-\r
-#define NAME_VALUE_NODE_FROM_LINK(a) CR (a, NAME_VALUE_NODE, Link, NAME_VALUE_NODE_SIGNATURE)\r
-\r
-#define FORMSET_STORAGE_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'G')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT16 DefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT64 PlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT32 DefaultPlatformIdNum;\r
- UINT32 FormSetOrder;\r
-\r
- BOOLEAN NewEfiVarstore; //EfiVarStore for UEFI 2.31 or not\r
- BOOLEAN Skip; //Flag for sorting out the variables\r
-\r
- UINT8 Type; // Storage type\r
-\r
- UINT16 VarStoreId;\r
- EFI_GUID Guid;\r
-\r
- CHAR16 *Name; // For EFI_IFR_VARSTORE\r
- UINT16 Size;\r
- UINT8 *Buffer;\r
-\r
- LIST_ENTRY NameValueListHead; // List of NAME_VALUE_NODE\r
-\r
- UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute\r
-} FORMSET_STORAGE;\r
-\r
-#define FORMSET_STORAGE_FROM_LINK(a) CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)\r
-\r
-typedef union {\r
- EFI_STRING_ID VarName;\r
- UINT16 VarOffset;\r
-} VAR_STORE_INFO;\r
-\r
-#define EXPRESSION_OPCODE_SIGNATURE SIGNATURE_32 ('E', 'X', 'O', 'P')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT8 Operand;\r
-\r
- UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND\r
- UINT8 Flags; // For EFI_IFR_SPAN\r
- UINT8 RuleId; // For EFI_IFR_RULE_REF\r
-\r
- EFI_HII_VALUE Value; // For EFI_IFR_EQ_ID_VAL, EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_IFR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1\r
-\r
- EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_ID, EFI_IFR_EQ_ID_VAL_LIST, EFI_IFR_QUESTION_REF1\r
- EFI_QUESTION_ID QuestionId2;\r
-\r
- UINT16 ListLength; // For EFI_IFR_EQ_ID_VAL_LIST\r
- UINT16 *ValueList;\r
-\r
- EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_2, EFI_IFR_QUESTION_REF3_3\r
- EFI_GUID Guid;\r
-\r
- FORMSET_STORAGE *VarStorage; // For EFI_IFR_SET, EFI_IFR_GET\r
- VAR_STORE_INFO VarStoreInfo;// For EFI_IFR_SET, EFI_IFR_GET\r
- UINT8 ValueType; // For EFI_IFR_SET, EFI_IFR_GET\r
- UINT8 ValueWidth; // For EFI_IFR_SET, EFI_IFR_GET\r
- CHAR16 *ValueName; // For EFI_IFR_SET, EFI_IFR_GET\r
- LIST_ENTRY MapExpressionList; // nested expressions inside of Map opcode.\r
-} EXPRESSION_OPCODE;\r
-\r
-#define EXPRESSION_OPCODE_FROM_LINK(a) CR (a, EXPRESSION_OPCODE, Link, EXPRESSION_OPCODE_SIGNATURE)\r
-\r
-#define FORM_EXPRESSION_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'P')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT8 Type; // Type for this expression\r
-\r
- UINT8 RuleId; // For EFI_IFR_RULE only\r
- EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR_INCONSISTENT_IF only\r
-\r
- EFI_HII_VALUE Result; // Expression evaluation result\r
- UINT8 TimeOut; // For EFI_IFR_WARNING_IF\r
-\r
- LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE)\r
-} FORM_EXPRESSION;\r
-\r
-#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)\r
-\r
-#define QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT16 DefaultId;\r
- EFI_HII_VALUE Value; // Default value\r
-\r
- FORM_EXPRESSION *ValueExpression; // Not-NULL indicates default value is provided by EFI_IFR_VALUE\r
-} QUESTION_DEFAULT;\r
-\r
-#define QUESTION_DEFAULT_FROM_LINK(a) CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)\r
-\r
-#define QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- EFI_STRING_ID Text;\r
- UINT8 Flags;\r
- EFI_HII_VALUE Value;\r
-\r
- FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf\r
-} QUESTION_OPTION;\r
-\r
-#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)\r
-\r
-#define FORM_BROWSER_STATEMENT_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'A')\r
-\r
-struct _FORM_BROWSER_STATEMENT {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- UINT8 Operand; // The operand (first byte) of this Statement or Question\r
-\r
- UQI_HEADER Uqi;\r
- UINT32 FormSetOrder;\r
- EFI_GUID Guid;\r
- UINT8 Type; // Storage type\r
- BOOLEAN NewEfiVarstore; //EfiVarStore for UEFI 2.31 or not\r
- UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute\r
- BOOLEAN QuestionReferToBitField;// Whether the question is stored in a bit field.\r
- //\r
- // Statement Header\r
- //\r
- EFI_STRING_ID Prompt;\r
- EFI_STRING_ID Help;\r
- EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT\r
-\r
- //\r
- // Question Header\r
- //\r
- EFI_QUESTION_ID QuestionId; // The value of zero is reserved\r
- EFI_VARSTORE_ID VarStoreId; // A value of zero indicates no variable storage\r
- FORMSET_STORAGE *Storage;\r
- VAR_STORE_INFO VarStoreInfo;\r
- UINT16 StorageWidth;\r
- UINT16 BitStorageWidth;\r
- UINT16 BitVarOffset;\r
- UINT8 QuestionFlags;\r
- CHAR16 *VariableName; // Name/Value or EFI Variable name\r
-\r
- EFI_HII_VALUE HiiValue; // Edit copy for checkbox, numberic, oneof\r
- UINT8 *BufferValue; // Edit copy for string, password, orderedlist\r
- UINT8 ValueType; // Data type for orderedlist value array\r
-\r
- //\r
- // OpCode specific members\r
- //\r
- UINT8 Flags; // for EFI_IFR_CHECKBOX, EFI_IFR_DATE, EFI_IFR_NUMERIC, EFI_IFR_ONE_OF,\r
- // EFI_IFR_ORDERED_LIST, EFI_IFR_STRING,EFI_IFR_SUBTITLE,EFI_IFR_TIME, EFI_IFR_BANNER\r
- UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST\r
-\r
- UINT16 BannerLineNumber; // for EFI_IFR_BANNER, 1-based line number\r
-\r
- UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC, it's Min/Max value\r
- UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD, it's Min/Max length\r
- UINT64 Step;\r
-\r
- EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON\r
- EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID\r
-\r
- //\r
- // Get from IFR parsing\r
- //\r
- FORM_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly\r
- LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT list (QUESTION_DEFAULT), provide default values\r
- LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)\r
-\r
- EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE\r
- UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh\r
- BOOLEAN InSubtitle; // nesting inside of EFI_IFR_SUBTITLE\r
-\r
- LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)\r
- LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)\r
- LIST_ENTRY WarningListHead; // nested warning expression list (FORM_EXPRESSION)\r
- FORM_EXPRESSION *GrayOutExpression; // nesting inside of GrayOutIf\r
- FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf\r
- FORM_EXPRESSION *DisableExpression; // nesting inside of DisableIf\r
-\r
- FORM_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, provide this question value by read expression.\r
- FORM_EXPRESSION *WriteExpression; // nested EFI_IFR_WRITE, evaluate write expression after this question value is set.\r
-};\r
-\r
-#define FORM_BROWSER_STATEMENT_FROM_LINK(a) CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)\r
-\r
-#define FORM_BROWSER_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M')\r
-#define STANDARD_MAP_FORM_TYPE 0x01\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT16 FormId; // FormId of normal form or formmap form.\r
- EFI_STRING_ID FormTitle; // FormTile of normal form, or FormMapMethod title of formmap form.\r
- UINT16 FormType; // Specific form type for the different form.\r
-\r
- BOOLEAN ModalForm; // Whether this is a modal form.\r
- LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)\r
- LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
- FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf\r
-} FORM_BROWSER_FORM;\r
-\r
-#define FORM_BROWSER_FORM_FROM_LINK(a) CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)\r
-\r
-#define FORMSET_DEFAULTSTORE_SIGNATURE SIGNATURE_32 ('F', 'D', 'F', 'S')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT16 DefaultId;\r
- EFI_STRING_ID DefaultName;\r
-} FORMSET_DEFAULTSTORE;\r
-\r
-#define STRING_NUMBER 100\r
-\r
-typedef struct {\r
- EFI_STRING_ID StringId;\r
- CHAR16 *String;\r
-} STRING_INFO;\r
-\r
-typedef struct {\r
- EFI_STRING_ID CachedIdNum;\r
- EFI_STRING_ID MaxIdNum;\r
- STRING_INFO *StringInfoList;\r
-} FORMSET_STRING_LIST;\r
-\r
-#define FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)\r
-\r
-#define FORM_BROWSER_FORMSET_SIGNATURE SIGNATURE_32 ('F', 'B', 'F', 'S')\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT32 FormSetOrder;\r
-\r
- UINTN IfrBinaryLength;\r
- UINT8 *IfrBinaryData;\r
- UINT8 *UnicodeBinary;\r
-\r
- EFI_GUID Guid;\r
- EFI_STRING_ID FormSetTitle;\r
- EFI_STRING_ID Help;\r
- UINT8 NumberOfClassGuid;\r
- EFI_GUID ClassGuid[3]; // Up to three ClassGuid\r
- UINT16 Class; // Tiano extended Class code\r
- UINT16 SubClass; // Tiano extended Subclass code\r
-\r
- FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions\r
- EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode\r
-\r
- LIST_ENTRY *StorageListHead; // Storage list (FORMSET_STORAGE)\r
- LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)\r
- LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)\r
- LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)\r
- FORMSET_STRING_LIST EnUsStringList; // Cache EN_US English list\r
- FORMSET_STRING_LIST UqiStringList; // Cache EN_US English list\r
-} FORM_BROWSER_FORMSET;\r
-\r
-#define FORM_BROWSER_FORMSET_FROM_LINK(a) CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)\r
-\r
-///\r
-/// Structure for multi-platform support\r
-///\r
-typedef struct {\r
- UINT16 DefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT16 DefaultIdNum;\r
- UINT64 PlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT16 PlatformIdNum;\r
- UINT16 KeyDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT64 KeyPlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- UINT16 KeyIdNum;\r
- FORM_BROWSER_STATEMENT PlatformIdQuestion;\r
- FORM_BROWSER_STATEMENT *Question;\r
- UINT16 PlatformIdWidth;\r
- UQI_HEADER Uqi;\r
- BOOLEAN MultiPlatformOrNot;\r
- BOOLEAN ExistStorageFfsInBfv;\r
- BOOLEAN SizeOptimized;\r
- BOOLEAN SizeOptimizedParam;\r
-} MULTI_PLATFORM_PARAMETERS;\r
-\r
-/**\r
- Search the variable list according to the variable Guid and name, and return the pointer\r
- of that Node.\r
-\r
- @param HiiObjList The pointer to the Question\r
- @param VarName The EFI variable name need to be updated to VarList\r
- @param Offset The offset of the variable\r
- @param StorageListHead The pointer to the LIST_ENTRY of Storage\r
- @param Vaue The value in that value offset of the variable\r
- @param VarList The dual pointer of Varlist\r
-\r
- @return EFI_SUCCESS\r
-**/\r
-EFI_STATUS\r
-SearchVarStorage (\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN CHAR16* VarName,\r
- IN UINT32 Offset,\r
- IN LIST_ENTRY *StorageListHead,\r
- IN OUT CHAR8 **Value,\r
- IN OUT FORMSET_STORAGE **VarList\r
- );\r
-\r
-/**\r
- Get the string based on the StringId and HII Package List Handle.\r
-\r
- @param Token The String's ID.\r
- @param HiiHandle The package list in the HII database to search for\r
- the specified string.\r
-\r
- @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-GetToken (\r
- IN EFI_STRING_ID Token,\r
- IN UINT8 *UniPackge\r
- );\r
-\r
-/**\r
- Free resources allocated for all Storage in an LIST_ENTRY.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyAllStorage (\r
- IN LIST_ENTRY *StorageEntryListHead\r
- );\r
-\r
-\r
-/**\r
- Free resources allocated for a FormSet.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyFormSet (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- );\r
-\r
-\r
-/**\r
- Free resources allocated for all FormSet in an LIST_ENTRY.\r
-\r
- @param FormSet Pointer of the FormSet\r
-\r
-**/\r
-VOID\r
-DestroyAllFormSet (\r
- IN LIST_ENTRY *FormSetEntryListHead\r
- );\r
-\r
-/**\r
- Parse opcodes in the formset IFR binary.\r
-\r
- @param FormSet Pointer of the FormSet data structure.\r
-\r
- @retval EFI_SUCCESS Opcode parse success.\r
- @retval Other Opcode parse fail.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseOpCodes (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- );\r
-\r
-/**\r
- Set the value to the variable of platformId question.\r
-\r
- @param PlatformId The form set.\r
-\r
- @retval EFI_SUCCESS Set successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-AssignThePlatformId (\r
- IN UINT64 PlatformId\r
- );\r
-\r
-\r
-/**\r
- Reset Questions to their default value in a Form, Formset or System.\r
-\r
- @param FormSet FormSet data structure.\r
- @param Form Form data structure.\r
- @param DefaultId The default Id\r
- @param PlatformId The platform Id\r
- @param SettingScope Setting Scope for Default action.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
-\r
-**/\r
-EFI_STATUS\r
-ExtractDefault (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 DefaultId,\r
- IN UINT64 PlatformId,\r
- IN BROWSER_SETTING_SCOPE SettingScope\r
- );\r
-\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetCurrentExpressionStack (\r
- VOID\r
- );\r
-\r
-\r
-/**\r
- Push current expression onto the Stack\r
-\r
- @param Pointer Pointer to current expression.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushCurrentExpression (\r
- IN VOID *Pointer\r
- );\r
-\r
-\r
-/**\r
- Pop current expression from the Stack\r
-\r
- @param Pointer Pointer to current expression to be pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopCurrentExpression (\r
- OUT VOID **Pointer\r
- );\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetMapExpressionListStack (\r
- VOID\r
- );\r
-\r
-\r
-/**\r
- Push the list of map expression onto the Stack\r
-\r
- @param Pointer Pointer to the list of map expression to be pushed.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushMapExpressionList (\r
- IN VOID *Pointer\r
- );\r
-\r
-\r
-/**\r
- Pop the list of map expression from the Stack\r
-\r
- @param Pointer Pointer to the list of map expression to be pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopMapExpressionList (\r
- OUT VOID **Pointer\r
- );\r
-\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetScopeStack (\r
- VOID\r
- );\r
-\r
-\r
-/**\r
- Push an Operand onto the Stack\r
-\r
- @param Operand Operand to push.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushScope (\r
- IN UINT8 Operand\r
- );\r
-\r
-\r
-/**\r
- Pop an Operand from the Stack\r
-\r
- @param Operand Operand to pop.\r
-\r
- @retval EFI_SUCCESS The value was pushed onto the stack.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopScope (\r
- OUT UINT8 *Operand\r
- );\r
-\r
-\r
-/**\r
- Zero extend integer/boolean/date/time to UINT64 for comparing.\r
-\r
- @param Value HII Value to be converted.\r
-\r
-**/\r
-VOID\r
-ExtendValueToU64 (\r
- IN EFI_HII_VALUE *Value\r
- );\r
-\r
-\r
-/**\r
- Compare two Hii value.\r
-\r
- @param Value1 Expression value to compare on left-hand.\r
- @param Value2 Expression value to compare on right-hand.\r
-\r
- @retval EFI_INVALID_PARAMETER Could not perform compare on two values.\r
- @retval 0 Two operators equal.\r
- @return Positive value if Value1 is greater than Value2.\r
- @retval Negative value if Value1 is less than Value2.\r
-\r
-**/\r
-INTN\r
-CompareHiiValue (\r
- IN EFI_HII_VALUE *Value1,\r
- IN EFI_HII_VALUE *Value2,\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- );\r
-\r
-/**\r
- Evaluate the result of a HII expression.\r
-\r
- If Expression is NULL, then ASSERT.\r
-\r
- @param FormSet FormSet associated with this expression.\r
- @param Form Form associated with this expression.\r
- @param Expression Expression to be evaluated.\r
- @param ConstantExpression The pointer to the flag of constant expression. If constant, will return TRUE.\r
-\r
- @retval EFI_SUCCESS The expression evaluated successfuly\r
- @retval EFI_NOT_FOUND The Question which referenced by a QuestionId\r
- could not be found.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
- @retval EFI_INVALID_PARAMETER Syntax error with the Expression\r
-\r
-**/\r
-EFI_STATUS\r
-EvaluateExpression (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN OUT FORM_EXPRESSION *Expression,\r
- IN OUT BOOLEAN *ConstantExpression\r
- );\r
-\r
-/**\r
- Compare two Uqi parameters\r
-\r
- @param UqiParm1 The pointer to the first Uqi parameter.\r
- @param UqiParm2 The pointer to the second Uqi parameter.\r
-\r
- @retval TRUE If these two Uqi parameters are the same, return TRUE;\r
- @return FALSE Otherwise, return FALSE;\r
-**/\r
-BOOLEAN\r
-CompareUqiHeader (\r
- IN CONST UQI_HEADER *UqiParm1,\r
- IN CONST UQI_HEADER *UqiParm2\r
- );\r
-\r
-\r
-/**\r
- Print all ONE_OF ORDER_LIST NUMERIC STRING and CHECKBOX in all fromsets.\r
-\r
- @param Formset The pointer to the entry of the fromset list\r
- @param Formset The pointer to the entry of the storage list\r
-\r
- @retval EFI_SUCCESS It was complete successfully\r
- @return EFI_ABORTED An error occurred\r
-**/\r
-EFI_STATUS\r
-PrintInfoInAllFormset (\r
- IN LIST_ENTRY *FormSetEntryListHead,\r
- IN LIST_ENTRY *StorageEntryListHead\r
- );\r
-\r
- /**\r
- Get the question value with bit field from the buffer.\r
-\r
- @param Question The question refer to bit field.\r
- @param Buffer The buffer which the question value get from.\r
- @param Value Retun the value.\r
-\r
-**/\r
-VOID\r
-GetBitsQuestionValue(\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN UINT8 *Buffer,\r
- OUT UINT32 *Value\r
- );\r
-\r
-/**\r
- Set the question value with bit field to the buffer.\r
-\r
- @param Question The question refer to bit field.\r
- @param Buffer The buffer which the question value set to.\r
- @param Value The value need to set.\r
-\r
-**/\r
-VOID\r
-SetBitsQuestionValue (\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN UINT8 *Buffer,\r
- IN UINT32 Value\r
- );\r
-\r
-#endif\r
+++ /dev/null
-## @file\r
-#\r
-# Windows makefile for 'FCE' module build.\r
-#\r
-#Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
-#SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.common\r
-\r
-APPNAME = FCE\r
-\r
-LIBS = $(LIB_PATH)\Common.lib\r
-\r
-OBJECTS = Fce.obj Variable.obj TimeBasedVariable.obj MonotonicBasedVariable.obj IfrParse.obj Common.obj BinaryParse.obj BinaryCreate.obj Expression.obj\r
-\r
-!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.app\r
-\r
+++ /dev/null
-/** @file\r
-\r
- Read and edit the authenticated variables.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Fce.h"\r
-#include "MonotonicBasedVariable.h"\r
-\r
-extern LIST_ENTRY mAllVarListEntry;\r
-extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
-extern G_EFI_FD_INFO gEfiFdInfo;\r
-EFI_GUID gEfiAuthenticatedVariableGuid = EFI_AUTHENTICATED_VARIABLE_GUID;\r
-/**\r
-\r
- Gets the pointer to the first variable header in given variable store area.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the first variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetStartPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
-}\r
-\r
-/**\r
-\r
- Gets the pointer to the end of the variable storage area.\r
-\r
- This function gets pointer to the end of the variable storage\r
- area, according to the input variable store header.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the end of the variable storage area.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetEndPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
-}\r
-\r
-\r
-/**\r
-\r
- This code checks if variable header is valid or not.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @retval TRUE Variable header is valid.\r
- @retval FALSE Variable header is not valid.\r
-\r
-**/\r
-static\r
-BOOLEAN\r
-IsValidVariableHeader (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable == NULL) || (Variable->StartId != VARIABLE_DATA)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of name of variable.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return UINTN Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-NameSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->NameSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-DataSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->DataSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable name.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Name which is Unicode encoding.\r
-\r
-**/\r
-static\r
-CHAR16 *\r
-GetVariableNamePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- return (CHAR16 *) (Variable + 1);\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Data.\r
-\r
-**/\r
-static\r
-UINT8 *\r
-GetVariableDataPtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- Value = (UINTN) GetVariableNamePtr (Variable);\r
- Value += NameSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));\r
-\r
- return (UINT8 *) Value;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the next variable header.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to next variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetNextVariablePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- if (!IsValidVariableHeader (Variable)) {\r
- return NULL;\r
- }\r
-\r
- Value = (UINTN) GetVariableDataPtr (Variable);\r
- Value += DataSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
-}\r
-\r
-/**\r
- Search and get a free space in the EFI variable zone\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarListSize The size of a variables needs to be allocated.\r
- @param FreeBeginVar The dual pointer to the free NV space.\r
-\r
- @retval EFI_SUCCESS Return the beginning of a free variable space.\r
- @retval RETURN_BUFFER_TOO_SMALL Failed.\r
-**/\r
-static\r
-EFI_STATUS\r
-GetVariableVar (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN UINT32 VarListSize,\r
- IN OUT CHAR8 **FreeBeginVar\r
-)\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR8 *BeginVar;\r
-\r
- BeginVar = NULL;\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- *FreeBeginVar = NULL;\r
-\r
- if (VariableStoreHeader == NULL) {\r
- *FreeBeginVar = NULL;\r
- return RETURN_INVALID_PARAMETER;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- //Search the beginning of free NV\r
- //\r
- while (Variable != EndOfVariable) {\r
- BeginVar = (CHAR8 *)Variable;\r
- Variable = GetNextVariablePtr (Variable);\r
- if (Variable == NULL) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- }\r
- //\r
- // Check whether the free space is more than what we want\r
- //\r
- if ((CHAR8 *)BeginVar + VarListSize > (CHAR8 *)EndOfVariable) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- //\r
- // If not find the available space, return NULL\r
- //\r
- if (!Flag) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- *FreeBeginVar = BeginVar;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search whether the variable in VarList has existed in current NV.\r
-\r
- Parse the FFS or Fd image, and find the valid variable pointer.\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarList The pointer to the VarList\r
-\r
- @retval address If the variable existed in current NV, return address\r
- @return NULL Otherwise, return NULL\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-FindVariableInNv (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN FORMSET_STORAGE *Storage\r
- )\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR16 *VariableName;\r
-\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- VariableName = NULL;\r
-\r
- if ((VariableStoreHeader == NULL) || (Storage == NULL) || (Storage->Name == NULL)) {\r
- return NULL;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- // Parse and compare the variable in the NV space one by one\r
- //\r
- while ((Variable != EndOfVariable) && (Variable != NULL)) {\r
- VariableName = (CHAR16 *)((CHAR8 *)Variable + sizeof (VARIABLE_HEADER));\r
- if (!CompareGuid (&Variable->VendorGuid, &Storage->Guid) \\r
- && !FceStrCmp (Storage->Name, VariableName) \\r
- && (Variable->State == VAR_ADDED)) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- Variable = GetNextVariablePtr (Variable);\r
- }\r
- if (!Flag) {\r
- return NULL;\r
- }\r
- return Variable;\r
-}\r
-\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
- @retval EFI_INVALID_PARAMETER Invalid variable name.\r
-**/\r
-EFI_STATUS\r
-SynAuthEfiVariable (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- CHAR8 *DataBase;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
-\r
- Status = EFI_SUCCESS;\r
- DataBase = NULL;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if (VarToList) {\r
- //\r
- //Copy the data from NV to the VarList.\r
- //\r
- if (VariableHeader != NULL) {\r
- if (Storage->Buffer == NULL) {\r
- Storage->Buffer = calloc (Storage->Size, sizeof (CHAR8));\r
- ASSERT (Storage->Buffer != NULL);\r
- }\r
- //\r
- // The variable in VarList is CHAR8, but in the EFI variable is CHAR16.\r
- //\r
- DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- Storage->Buffer,\r
- (VOID *) DataBase,\r
- Storage->Size\r
- );\r
- }\r
- } else {\r
- //\r
- //If existed, copy the List data to the variable in NV directly. If not found, create a new one.\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- //\r
- //If this variable has existed in current FD, the data in VarList has\r
- // been updated, and this variable is not authenticated type, then\r
- // update it from VarList to the FD.\r
- //\r
- if ((VariableHeader != NULL) \\r
- && (Storage->Buffer != NULL)\r
- ) {\r
- if (!(VariableHeader->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {\r
- DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- (VOID *) DataBase,\r
- Storage->Buffer,\r
- Storage->Size\r
- );\r
- } else {\r
- printf ("Error. Not support to update authenticated variables.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else if ((VariableHeader == NULL) && (Storage->Buffer != NULL)){\r
- //\r
- //If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.\r
- //\r
- if (Storage->NewEfiVarstore\r
- && ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Try to get the available zone from the efi variables\r
- //\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Create the authenticated variable header\r
- //\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- VariableHeader->MonotonicCount = 0x0;\r
- VariableHeader->PubKeyIndex = 0x0;\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- } else {\r
- printf ("Error. No available space in NV ram.\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveAuthEfiVariable (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
- if (VariableHeader != NULL) {\r
- VariableHeader->State = VAR_DELETED;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check the store variable is Monotonic based authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-\r
-BOOLEAN\r
-CheckMonotonicBasedVarStore (\r
- IN VOID *VariableStoreHeader\r
- )\r
-{\r
- if (!CompareGuid (\r
- &gEfiAuthenticatedVariableGuid,\r
- &((VARIABLE_STORE_HEADER *)VariableStoreHeader)->Signature)\r
- ) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-/**\r
- Copy Monotonic-Based authenticated variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyMonotonicBasedVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
- UINT32 HeaderLength;\r
-\r
- Status = EFI_SUCCESS;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- HeaderLength = 0;\r
- VariableHeader = NULL;\r
- VariableStoreHeader = NULL;\r
-\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return 0;\r
- }\r
- //\r
- // If the first storage under one specified platformId and defaultId, create the variable header\r
- //\r
- if (Index == 0) {\r
- HeaderLength = WriteDefaultAndPlatformId (StorageBeginning, Storage);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength);\r
- //\r
- //Create the Variable Storage header\r
- //\r
- memcpy (&(VariableStoreHeader->Signature), &gEfiAuthenticatedVariableGuid, sizeof (EFI_GUID));\r
- VariableStoreHeader->Format = 0x5A;\r
- VariableStoreHeader->State = 0xFE;\r
- //\r
- //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.\r
- //\r
- VariableStoreHeader->Size = gEfiFdInfo.FdSize;\r
- }\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + *(UINT16 *)StorageBeginning);\r
-\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FAIL;\r
- }\r
- //\r
- // Create the variable header\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- VariableHeader->MonotonicCount = 0x0;\r
- VariableHeader->PubKeyIndex = 0x0;\r
-\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
-\r
-\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning) + Storage->Size);\r
-}\r
-\r
-\r
-/**\r
- Read Monotonic-based authenticated variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadMonotonicBasedVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- VARIABLE_HEADER *EndOfVariable;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- FORMSET_STORAGE *Storage;\r
- BOOLEAN ReadIdHeaderFlag;\r
- UINT32 Length;\r
- EFI_COMMON_SECTION_HEADER *SectionHeader;\r
- UINT8 *DataBase;\r
- static UINT16 PreDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- static UINT64 PrePlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
-\r
- VariableStoreHeader = NULL;\r
- Variable = NULL;\r
- ReadIdHeaderFlag = TRUE;\r
- Length = 0;\r
- SectionHeader = (EFI_COMMON_SECTION_HEADER *)Binary;\r
- DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + *(UINT16 *)DataBase);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
-\r
- for (Variable = GetStartPointer (VariableStoreHeader);\r
- Length < VariableStoreHeader->Size;\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize\r
- ) {\r
- //\r
- // Create the storage\r
- //\r
- Storage = NULL;\r
- Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));\r
- if (Storage == NULL) {\r
- printf ("Allocate memory failed.\n");\r
- return FAIL;\r
- }\r
- //\r
- // If access the first storage, read the platformId and defaultId\r
- //\r
- if (ReadIdHeaderFlag) {\r
- ReadDefaultAndPlatformIdFromBfv (DataBase, Storage);\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize;\r
- ReadIdHeaderFlag = FALSE;\r
- memcpy (PreDefaultId, Storage->DefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (PrePlatformId, Storage->PlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- } else {\r
- //\r
- // Store the DefaultId and PlatformId collected from the header to Storage.\r
- //\r
- memcpy (Storage->DefaultId, PreDefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (Storage->PlatformId, PrePlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- }\r
- Storage->Attributes = Variable->Attributes;\r
- Storage->Size = (UINT16)Variable->DataSize;\r
- Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));\r
- ASSERT (Storage->Name != NULL);\r
- Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));\r
- ASSERT (Storage->Buffer != NULL);\r
- memcpy (\r
- &(Storage->Guid),\r
- &(Variable->VendorGuid),\r
- sizeof (EFI_GUID)\r
- );\r
- memcpy (\r
- Storage->Name,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER),\r
- Variable->NameSize\r
- );\r
- memcpy (\r
- Storage->Buffer,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Assigned the value for comparison in verify mode\r
- //\r
- Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r
- Storage->NewEfiVarstore = TRUE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
-\r
- InsertTailList(StorageListEntry, &Storage->Link);\r
- //\r
- // If the last variable, exit.\r
- //\r
- if (Variable == EndOfVariable) {\r
- break;\r
- }\r
-\r
- Variable = GetNextVariablePtr (Variable);\r
- assert (Variable != NULL);\r
- }\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- Length = FvBufExpand3ByteSize (SectionHeader->Size);\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Check whether exists the valid MonotonicBased variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistMonotonicBasedEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if ((Storage->Buffer == NULL)\r
- || (Storage->Name == NULL)\r
- || (FceStrLen(Storage->Name) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if ((VariableHeader != NULL)) {\r
- return TRUE;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return FALSE;\r
-}\r
-/**\r
- Fix the size of montonic variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixMontonicVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- )\r
-{\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + *(UINT16 *)BinaryBeginning);\r
- VariableStoreHeader->Size = Length - *(UINT16 *)BinaryBeginning;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- The header of MonotonicBasedVariable.c.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __AUTHENTICATED_VARIABLE_FORMAT_H__\r
-#define __AUTHENTICATED_VARIABLE_FORMAT_H__\r
-\r
-#define EFI_AUTHENTICATED_VARIABLE_GUID \\r
- { 0x515fa686, 0xb06e, 0x4550, { 0x91, 0x12, 0x38, 0x2b, 0xf1, 0x6, 0x7b, 0xfb }}\r
-\r
-extern EFI_GUID gEfiAuthenticatedVariableGuid;\r
-\r
-///\r
-/// Alignment of variable name and data, according to the architecture:\r
-/// * For IA-32 and Intel(R) 64 architectures: 1\r
-/// * For IA-64 architecture: 8\r
-///\r
-#if defined (MDE_CPU_IPF)\r
-#define ALIGNMENT 8\r
-#else\r
-#define ALIGNMENT 1\r
-#endif\r
-\r
-///\r
-/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.\r
-///\r
-#if (ALIGNMENT == 1)\r
-#define GET_PAD_SIZE(a) (0)\r
-#else\r
-#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))\r
-#endif\r
-\r
-///\r
-/// Alignment of Variable Data Header in Variable Store region\r
-///\r
-#define HEADER_ALIGNMENT 4\r
-#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))\r
-\r
-///\r
-/// Status of Variable Store Region\r
-///\r
-typedef enum {\r
- EfiRaw,\r
- EfiValid,\r
- EfiInvalid,\r
- EfiUnknown\r
-} VARIABLE_STORE_STATUS;\r
-\r
-#pragma pack(1)\r
-\r
-#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID\r
-\r
-///\r
-/// Variable Store Header Format and State\r
-///\r
-#define VARIABLE_STORE_FORMATTED 0x5a\r
-#define VARIABLE_STORE_HEALTHY 0xfe\r
-\r
-///\r
-/// Variable Store region header\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable store region signature.\r
- ///\r
- EFI_GUID Signature;\r
- ///\r
- /// Size of entire variable store,\r
- /// including size of variable store header but not including the size of FvHeader.\r
- ///\r
- UINT32 Size;\r
- ///\r
- /// Variable region format state.\r
- ///\r
- UINT8 Format;\r
- ///\r
- /// Variable region healthy state.\r
- ///\r
- UINT8 State;\r
- UINT16 Reserved;\r
- UINT32 Reserved1;\r
-} VARIABLE_STORE_HEADER;\r
-\r
-///\r
-/// Variable data start flag.\r
-///\r
-#define VARIABLE_DATA 0x55AA\r
-\r
-///\r
-/// Variable State flags\r
-///\r
-#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition\r
-#define VAR_DELETED 0xfd ///< Variable is obsolete\r
-#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid\r
-#define VAR_ADDED 0x3f ///< Variable has been completely added\r
-\r
-///\r
-/// Single Variable Data Header Structure.\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable Data Start Flag.\r
- ///\r
- UINT16 StartId;\r
- ///\r
- /// Variable State defined above.\r
- ///\r
- UINT8 State;\r
- UINT8 Reserved;\r
- ///\r
- /// Attributes of variable defined in UEFI spec\r
- ///\r
- UINT32 Attributes;\r
- ///\r
- /// Associated monotonic count value against replay attack.\r
- ///\r
- UINT64 MonotonicCount;\r
- ///\r
- /// Index of associated public key in database.\r
- ///\r
- UINT32 PubKeyIndex;\r
- ///\r
- /// Size of variable null-terminated Unicode string name.\r
- ///\r
- UINT32 NameSize;\r
- ///\r
- /// Size of the variable data without this header.\r
- ///\r
- UINT32 DataSize;\r
- ///\r
- /// A unique identifier for the vendor that produces and consumes this varaible.\r
- ///\r
- EFI_GUID VendorGuid;\r
-} VARIABLE_HEADER;\r
-\r
-#pragma pack()\r
-\r
-typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;\r
-\r
-///\r
-/// This structure contains the variable list that is put in EFI system table.\r
-/// The variable driver collects all variables that were used at boot service time and produces this list.\r
-/// This is an optional feature to dump all used variables in shell environment.\r
-///\r
-struct _VARIABLE_INFO_ENTRY {\r
- VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.\r
- EFI_GUID VendorGuid; ///< Guid of Variable.\r
- CHAR16 *Name; ///< Name of Variable.\r
- UINT32 Attributes; ///< Attributes of variable defined in UEFI spec.\r
- UINT32 ReadCount; ///< Number of times to read this variable.\r
- UINT32 WriteCount; ///< Number of times to write this variable.\r
- UINT32 DeleteCount; ///< Number of times to delete this variable.\r
- UINT32 CacheCount; ///< Number of times that cache hits this variable.\r
- BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.\r
-};\r
-\r
-#endif // _EFI_VARIABLE_H_\r
+++ /dev/null
-/** @file\r
-\r
- Read and edit the time-base authenticated variables.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Fce.h"\r
-#include "TimeBasedVariable.h"\r
-\r
-extern LIST_ENTRY mAllVarListEntry;\r
-extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
-extern G_EFI_FD_INFO gEfiFdInfo;\r
-\r
-EFI_GUID gEfiAuthenticatedVariableBasedTimeGuid = EFI_AUTHENTICATED_VARIABLE_BASED_TIME_GUID;\r
-/**\r
-\r
- Gets the pointer to the first variable header in given variable store area.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the first variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetStartPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
-}\r
-\r
-/**\r
-\r
- Gets the pointer to the end of the variable storage area.\r
-\r
- This function gets pointer to the end of the variable storage\r
- area, according to the input variable store header.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the end of the variable storage area.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetEndPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
-}\r
-\r
-\r
-/**\r
-\r
- This code checks if variable header is valid or not.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @retval TRUE Variable header is valid.\r
- @retval FALSE Variable header is not valid.\r
-\r
-**/\r
-static\r
-BOOLEAN\r
-IsValidVariableHeader (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable == NULL) || (Variable->StartId != VARIABLE_DATA)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of name of variable.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return UINTN Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-NameSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->NameSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-DataSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->DataSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable name.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Name which is Unicode encoding.\r
-\r
-**/\r
-static\r
-CHAR16 *\r
-GetVariableNamePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- return (CHAR16 *) (Variable + 1);\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Data.\r
-\r
-**/\r
-static\r
-UINT8 *\r
-GetVariableDataPtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- Value = (UINTN) GetVariableNamePtr (Variable);\r
- Value += NameSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));\r
-\r
- return (UINT8 *) Value;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the next variable header.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to next variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetNextVariablePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- if (!IsValidVariableHeader (Variable)) {\r
- return NULL;\r
- }\r
-\r
- Value = (UINTN) GetVariableDataPtr (Variable);\r
- Value += DataSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
-}\r
-\r
-/**\r
- Search and get a free space in the EFI variable zone\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarListSize The size of a variables needs to be allocated.\r
- @param FreeBeginVar The dual pointer to the free NV space.\r
-\r
- @retval EFI_SUCCESS Return the beginning of a free variable space.\r
- @retval RETURN_BUFFER_TOO_SMALL Failed.\r
-**/\r
-static\r
-EFI_STATUS\r
-GetVariableVar (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN UINT32 VarListSize,\r
- IN OUT CHAR8 **FreeBeginVar\r
-)\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR8 *BeginVar;\r
-\r
- BeginVar = NULL;\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- *FreeBeginVar = NULL;\r
-\r
- if (VariableStoreHeader == NULL) {\r
- *FreeBeginVar = NULL;\r
- return RETURN_INVALID_PARAMETER;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- //Search the beginning of free NV\r
- //\r
- while (Variable != EndOfVariable) {\r
- BeginVar = (CHAR8 *)Variable;\r
- Variable = GetNextVariablePtr (Variable);\r
- if (Variable == NULL) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- }\r
- //\r
- // Check whether the free space is more than what we want\r
- //\r
- if ((CHAR8 *)BeginVar + VarListSize > (CHAR8 *)EndOfVariable) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- //\r
- // If not find the available space, return NULL\r
- //\r
- if (!Flag) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- *FreeBeginVar = BeginVar;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search whether the variable in VarList has existed in current NV.\r
-\r
- Parse the FFS or Fd image, and find the valid variable pointer.\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarList The pointer to the VarList\r
-\r
- @retval address If the variable existed in current NV, return address\r
- @return NULL Otherwise, return NULL\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-FindVariableInNv (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN FORMSET_STORAGE *Storage\r
- )\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR16 *VariableName;\r
-\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- VariableName = NULL;\r
-\r
- if ((VariableStoreHeader == NULL) || (Storage == NULL) || (Storage->Name == NULL)) {\r
- return NULL;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- // Parse and compare the variable in the NV space one by one\r
- //\r
- while ((Variable != EndOfVariable) && (Variable != NULL)) {\r
- VariableName = (CHAR16 *)((CHAR8 *)Variable + sizeof (VARIABLE_HEADER));\r
- if (!CompareGuid (&Variable->VendorGuid, &Storage->Guid) \\r
- && !FceStrCmp (Storage->Name, VariableName) \\r
- && (Variable->State == VAR_ADDED)\r
- ) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- Variable = GetNextVariablePtr (Variable);\r
- }\r
- if (!Flag) {\r
- return NULL;\r
- }\r
- return Variable;\r
-}\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the time stamp authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
- @retval EFI_INVALID_PARAMETER Invalid variable name.\r
-**/\r
-\r
-EFI_STATUS\r
-SynAuthEfiVariableBasedTime (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- CHAR8 *DataBase;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
-\r
- Status = EFI_SUCCESS;\r
- DataBase = NULL;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if (VarToList) {\r
- //\r
- //Copy the data from NV to the VarList.\r
- //\r
- if (VariableHeader != NULL) {\r
- if (Storage->Buffer == NULL) {\r
- Storage->Buffer = calloc (Storage->Size, sizeof (CHAR8));\r
- ASSERT (Storage->Buffer != NULL);\r
- }\r
- //\r
- // The variable in VarList is CHAR8, but in the EFI variable is CHAR16.\r
- //\r
- DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- Storage->Buffer,\r
- (VOID *) DataBase,\r
- Storage->Size\r
- );\r
- }\r
- } else {\r
- //\r
- //If existed, copy the List data to the variable in NV directly. If not found, create a new one.\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- //\r
- //If this variable has existed in current FD, the data in VarList has\r
- // been updated, and this variable is not authenticated type, then\r
- // update it from VarList to the FD.\r
- //\r
- if ((VariableHeader != NULL) \\r
- && (Storage->Buffer != NULL)\r
- ) {\r
- if (!(VariableHeader->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {\r
- DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- (VOID *) DataBase,\r
- Storage->Buffer,\r
- Storage->Size\r
- );\r
- } else {\r
- printf ("Error. Not support to update authenticated variables.\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else if ((VariableHeader == NULL) && (Storage->Buffer != NULL)){\r
- //\r
- //If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.\r
- //\r
- if (Storage->NewEfiVarstore\r
- && ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Try to get the available zone from the efi variables\r
- //\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Create the authenticated variable header\r
- //\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- VariableHeader->MonotonicCount = 0x0;\r
- memset (&(VariableHeader->TimeStamp), 0, sizeof (EFI_TIME));\r
- VariableHeader->PubKeyIndex = 0x0;\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- } else {\r
- printf ("Error. No available space in NV ram.\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveAuthEfiVariableBasedTime (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
- if (VariableHeader != NULL) {\r
- VariableHeader->State = VAR_DELETED;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check the store variable is Time stamp authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-\r
-BOOLEAN\r
-CheckTimeBasedVarStoreOrNot (\r
- IN VOID *VariableStoreHeader\r
- )\r
-{\r
- if (!CompareGuid (\r
- &gEfiAuthenticatedVariableBasedTimeGuid,\r
- &((VARIABLE_STORE_HEADER *)VariableStoreHeader)->Signature)\r
- ) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-/**\r
- Copy time-based authenticated variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyTimeBasedVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
- UINT32 HeaderLength;\r
-\r
- Status = EFI_SUCCESS;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- HeaderLength = 0;\r
- VariableHeader = NULL;\r
- VariableStoreHeader = NULL;\r
-\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return 0;\r
- }\r
- //\r
- // If the first storage under one specified platformId and defaultId, create the variable header\r
- //\r
- if (Index == 0) {\r
- HeaderLength = WriteDefaultAndPlatformId (StorageBeginning, Storage);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength);\r
- //\r
- //Create the Variable Storage header\r
- //\r
- memcpy (&(VariableStoreHeader->Signature), &gEfiAuthenticatedVariableBasedTimeGuid, sizeof (EFI_GUID));\r
- VariableStoreHeader->Format = 0x5A;\r
- VariableStoreHeader->State = 0xFE;\r
- //\r
- //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.\r
- //\r
- VariableStoreHeader->Size = gEfiFdInfo.FdSize;\r
- }\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + *(UINT16 *)StorageBeginning);\r
-\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return FAIL;\r
- }\r
- //\r
- // Create the variable header\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- VariableHeader->MonotonicCount = 0x0;\r
- memset (&(VariableHeader->TimeStamp), 0, sizeof (EFI_TIME));\r
- VariableHeader->PubKeyIndex = 0x0;\r
-\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning) + Storage->Size);\r
-}\r
-\r
-/**\r
- Read time-based authenticated variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadTimeBasedVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- VARIABLE_HEADER *EndOfVariable;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- FORMSET_STORAGE *Storage;\r
- BOOLEAN ReadIdHeaderFlag;\r
- UINT32 Length;\r
- EFI_COMMON_SECTION_HEADER *SectionHeader;\r
- UINT8 *DataBase;\r
- static UINT16 PreDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- static UINT64 PrePlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
-\r
- VariableStoreHeader = NULL;\r
- Variable = NULL;\r
- ReadIdHeaderFlag = TRUE;\r
- Length = 0;\r
- SectionHeader = (EFI_COMMON_SECTION_HEADER *)Binary;\r
- DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + *(UINT16 *)DataBase);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
-\r
- for (Variable = GetStartPointer (VariableStoreHeader);\r
- Length < VariableStoreHeader->Size;\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize\r
- ) {\r
- //\r
- // Create the storage\r
- //\r
- Storage = NULL;\r
- Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));\r
- if (Storage == NULL) {\r
- printf ("Allocate memory failed.\n");\r
- return FAIL;\r
- }\r
- //\r
- // If access the first storage, read the platformId and defaultId\r
- //\r
- if (ReadIdHeaderFlag) {\r
- ReadDefaultAndPlatformIdFromBfv (DataBase, Storage);\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize;\r
- ReadIdHeaderFlag = FALSE;\r
- memcpy (PreDefaultId, Storage->DefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (PrePlatformId, Storage->PlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- } else {\r
- //\r
- // Store the DefaultId and PlatformId collected from the header to Storage.\r
- //\r
- memcpy (Storage->DefaultId, PreDefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (Storage->PlatformId, PrePlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- }\r
- Storage->Attributes = Variable->Attributes;\r
- Storage->Size = (UINT16)Variable->DataSize;\r
- Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));\r
- ASSERT (Storage->Name != NULL);\r
- Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));\r
- ASSERT (Storage->Buffer != NULL);\r
- memcpy (\r
- &(Storage->Guid),\r
- &(Variable->VendorGuid),\r
- sizeof (EFI_GUID)\r
- );\r
- memcpy (\r
- Storage->Name,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER),\r
- Variable->NameSize\r
- );\r
- memcpy (\r
- Storage->Buffer,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Assigned the value for comparison in verify mode\r
- //\r
- Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r
- Storage->NewEfiVarstore = TRUE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
-\r
- InsertTailList(StorageListEntry, &Storage->Link);\r
- //\r
- // If the last variable, exit.\r
- //\r
- if (Variable == EndOfVariable) {\r
- break;\r
- }\r
-\r
- Variable = GetNextVariablePtr (Variable);\r
- assert (Variable != NULL);\r
- }\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- Length = FvBufExpand3ByteSize (SectionHeader->Size);\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Check whether exists the valid time-based variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistTimeBasedEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if ((Storage->Buffer == NULL)\r
- || (Storage->Name == NULL)\r
- || (FceStrLen(Storage->Name) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if ((VariableHeader != NULL)) {\r
- return TRUE;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Fix the size of time-based variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixBasedTimeVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- )\r
-{\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + *(UINT16 *)BinaryBeginning);\r
- VariableStoreHeader->Size = Length - *(UINT16 *)BinaryBeginning;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- The header of TimeBasedVariable.c.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __AUTHENTICATED_VARIABLE_FORMAT_BASED_TIME_H__\r
-#define __AUTHENTICATED_VARIABLE_FORMAT_BASED_TIME_H__\r
-\r
-#define EFI_AUTHENTICATED_VARIABLE_BASED_TIME_GUID \\r
- { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }\r
-\r
-extern EFI_GUID gEfiAuthenticatedVariableBasedTimeGuid;\r
-\r
-///\r
-/// Alignment of variable name and data, according to the architecture:\r
-/// * For IA-32 and Intel(R) 64 architectures: 1\r
-/// * For IA-64 architecture: 8\r
-///\r
-#if defined (MDE_CPU_IPF)\r
-#define ALIGNMENT 8\r
-#else\r
-#define ALIGNMENT 1\r
-#endif\r
-\r
-///\r
-/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.\r
-///\r
-#if (ALIGNMENT == 1)\r
-#define GET_PAD_SIZE(a) (0)\r
-#else\r
-#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))\r
-#endif\r
-\r
-///\r
-/// Alignment of Variable Data Header in Variable Store region\r
-///\r
-#define HEADER_ALIGNMENT 4\r
-#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))\r
-\r
-///\r
-/// Status of Variable Store Region\r
-///\r
-typedef enum {\r
- EfiRaw,\r
- EfiValid,\r
- EfiInvalid,\r
- EfiUnknown\r
-} VARIABLE_STORE_STATUS;\r
-\r
-#pragma pack(1)\r
-\r
-#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID\r
-\r
-///\r
-/// Variable Store Header Format and State\r
-///\r
-#define VARIABLE_STORE_FORMATTED 0x5a\r
-#define VARIABLE_STORE_HEALTHY 0xfe\r
-\r
-///\r
-/// Variable Store region header\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable store region signature.\r
- ///\r
- EFI_GUID Signature;\r
- ///\r
- /// Size of entire variable store,\r
- /// including size of variable store header but not including the size of FvHeader.\r
- ///\r
- UINT32 Size;\r
- ///\r
- /// Variable region format state.\r
- ///\r
- UINT8 Format;\r
- ///\r
- /// Variable region healthy state.\r
- ///\r
- UINT8 State;\r
- UINT16 Reserved;\r
- UINT32 Reserved1;\r
-} VARIABLE_STORE_HEADER;\r
-\r
-///\r
-/// Variable data start flag.\r
-///\r
-#define VARIABLE_DATA 0x55AA\r
-\r
-///\r
-/// Variable State flags\r
-///\r
-#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition\r
-#define VAR_DELETED 0xfd ///< Variable is obsolete\r
-#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid\r
-#define VAR_ADDED 0x3f ///< Variable has been completely added\r
-\r
-///\r
-/// Single Variable Data Header Structure.\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable Data Start Flag.\r
- ///\r
- UINT16 StartId;\r
- ///\r
- /// Variable State defined above.\r
- ///\r
- UINT8 State;\r
- UINT8 Reserved;\r
- ///\r
- /// Attributes of variable defined in UEFI spec\r
- ///\r
- UINT32 Attributes;\r
- ///\r
- /// Associated monotonic count value against replay attack.\r
- ///\r
- UINT64 MonotonicCount;\r
- ///\r
- /// Associated TimeStamp value against replay attack.\r
- ///\r
- EFI_TIME TimeStamp;\r
- ///\r
- /// Index of associated public key in database.\r
- ///\r
- UINT32 PubKeyIndex;\r
- ///\r
- /// Size of variable null-terminated Unicode string name.\r
- ///\r
- UINT32 NameSize;\r
- ///\r
- /// Size of the variable data without this header.\r
- ///\r
- UINT32 DataSize;\r
- ///\r
- /// A unique identifier for the vendor that produces and consumes this varaible.\r
- ///\r
- EFI_GUID VendorGuid;\r
-} VARIABLE_HEADER;\r
-\r
-#pragma pack()\r
-\r
-typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;\r
-\r
-///\r
-/// This structure contains the variable list that is put in EFI system table.\r
-/// The variable driver collects all variables that were used at boot service time and produces this list.\r
-/// This is an optional feature to dump all used variables in shell environment.\r
-///\r
-struct _VARIABLE_INFO_ENTRY {\r
- VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.\r
- EFI_GUID VendorGuid; ///< Guid of Variable.\r
- CHAR16 *Name; ///< Name of Variable.\r
- UINT32 Attributes; ///< Attributes of variable defined in UEFI spec.\r
- UINT32 ReadCount; ///< Number of times to read this variable.\r
- UINT32 WriteCount; ///< Number of times to write this variable.\r
- UINT32 DeleteCount; ///< Number of times to delete this variable.\r
- UINT32 CacheCount; ///< Number of times that cache hits this variable.\r
- BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.\r
-};\r
-\r
-#endif // _EFI_VARIABLE_H_\r
+++ /dev/null
-/** @file\r
-\r
- Read and edit the EFI variable.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Fce.h"\r
-#include "Variable.h"\r
-\r
-extern LIST_ENTRY mAllVarListEntry;\r
-extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
-extern G_EFI_FD_INFO gEfiFdInfo;\r
-\r
-EFI_GUID gEfiVariableGuid = EFI_VARIABLE_GUID;\r
-/**\r
-\r
- Gets the pointer to the first variable header in given variable store area.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the first variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetStartPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
-}\r
-\r
-/**\r
-\r
- Gets the pointer to the end of the variable storage area.\r
-\r
- This function gets pointer to the end of the variable storage\r
- area, according to the input variable store header.\r
-\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
-\r
- @return Pointer to the end of the variable storage area.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetEndPointer (\r
- IN VARIABLE_STORE_HEADER *VarStoreHeader\r
- )\r
-{\r
- //\r
- // The end of variable store\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
-}\r
-\r
-\r
-/**\r
-\r
- This code checks if variable header is valid or not.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @retval TRUE Variable header is valid.\r
- @retval FALSE Variable header is not valid.\r
-\r
-**/\r
-static\r
-BOOLEAN\r
-IsValidVariableHeader (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable == NULL) || (Variable->StartId != VARIABLE_DATA)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of name of variable.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return UINTN Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-NameSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->NameSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the size of variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Size of variable in bytes.\r
-\r
-**/\r
-static\r
-UINTN\r
-DataSizeOfVariable (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- if ((Variable->State == (UINT8) (-1)) ||\r
- (Variable->DataSize == (UINT32) (-1)) ||\r
- (Variable->NameSize == (UINT32) (-1)) ||\r
- (Variable->Attributes == (UINT32) (-1))\r
- ) {\r
- return 0;\r
- }\r
- return (UINTN) Variable->DataSize;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable name.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Name which is Unicode encoding.\r
-\r
-**/\r
-static\r
-CHAR16 *\r
-GetVariableNamePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
-\r
- return (CHAR16 *) (Variable + 1);\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the variable data.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to Variable Data.\r
-\r
-**/\r
-static\r
-UINT8 *\r
-GetVariableDataPtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- Value = (UINTN) GetVariableNamePtr (Variable);\r
- Value += NameSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));\r
-\r
- return (UINT8 *) Value;\r
-}\r
-\r
-/**\r
-\r
- This code gets the pointer to the next variable header.\r
-\r
- @param Variable Pointer to the Variable Header.\r
-\r
- @return Pointer to next variable header.\r
-\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-GetNextVariablePtr (\r
- IN VARIABLE_HEADER *Variable\r
- )\r
-{\r
- UINTN Value;\r
-\r
- if (!IsValidVariableHeader (Variable)) {\r
- return NULL;\r
- }\r
-\r
- Value = (UINTN) GetVariableDataPtr (Variable);\r
- Value += DataSizeOfVariable (Variable);\r
- Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
-\r
- //\r
- // Be careful about pad size for alignment.\r
- //\r
- return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
-}\r
-\r
-/**\r
- Search and get a free space in the EFI variable zone\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarListSize The size of a variables needs to be allocated.\r
- @param FreeBeginVar The dual pointer to the free NV space.\r
-\r
- @retval EFI_SUCCESS Return the beginning of a free variable space.\r
- @retval RETURN_BUFFER_TOO_SMALL Failed.\r
-**/\r
-static\r
-EFI_STATUS\r
-GetVariableVar (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN UINT32 VarListSize,\r
- IN OUT CHAR8 **FreeBeginVar\r
-)\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR8 *BeginVar;\r
-\r
- BeginVar = NULL;\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- *FreeBeginVar = NULL;\r
-\r
- if (VariableStoreHeader == NULL) {\r
- *FreeBeginVar = NULL;\r
- return RETURN_INVALID_PARAMETER;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- //Search the beginning of free NV\r
- //\r
- while (Variable != EndOfVariable) {\r
- BeginVar = (CHAR8 *)Variable;\r
- Variable = GetNextVariablePtr (Variable);\r
- if (Variable == NULL) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- }\r
- //\r
- // Check whether the free space is more than what we want\r
- //\r
- if ((CHAR8 *)BeginVar + VarListSize > (CHAR8 *)EndOfVariable) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- //\r
- // If not find the available space, return NULL\r
- //\r
- if (!Flag) {\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
- *FreeBeginVar = BeginVar;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Search whether the variable in VarList has existed in current NV.\r
-\r
- Parse the FFS or Fd image, and find the valid variable pointer.\r
-\r
- @param VariableStoreHeader The start of a EFI variable zone.\r
- @param VarList The pointer to the VarList\r
-\r
- @retval address If the variable existed in current NV, return address\r
- @return NULL Otherwise, return NULL\r
-**/\r
-static\r
-VARIABLE_HEADER *\r
-FindVariableInNv (\r
- IN VARIABLE_STORE_HEADER *VariableStoreHeader,\r
- IN FORMSET_STORAGE *Storage\r
- )\r
-{\r
- BOOLEAN Flag;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_HEADER *EndOfVariable;\r
- CHAR16 *VariableName;\r
-\r
- Flag = FALSE;\r
- Variable = NULL;\r
- EndOfVariable = NULL;\r
- VariableName = NULL;\r
-\r
- if ((VariableStoreHeader == NULL) || (Storage == NULL) || (Storage->Name == NULL)) {\r
- return NULL;\r
- }\r
- Variable = GetStartPointer (VariableStoreHeader);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
- //\r
- // Parse and compare the variable in the NV space one by one\r
- //\r
- while ((Variable != EndOfVariable) && (Variable != NULL)) {\r
- VariableName = (CHAR16 *)((CHAR8 *)Variable + sizeof (VARIABLE_HEADER));\r
- if (!CompareGuid (&Variable->VendorGuid, &Storage->Guid) \\r
- && !FceStrCmp (Storage->Name, VariableName) \\r
- && (Variable->State == VAR_ADDED)) {\r
- Flag = TRUE;\r
- break;\r
- }\r
- Variable = GetNextVariablePtr (Variable);\r
- }\r
- if (!Flag) {\r
- return NULL;\r
- }\r
- return Variable;\r
-}\r
-/**\r
- Exchange the data between Efi variable and the data of VarList when the\r
- variable use the authenticated variable header\r
-\r
- If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,\r
- update the data from varlist to efi variable.\r
-\r
- @param VarToList The flag to control the direction of exchange.\r
- @param StorageListHead Decide which variale list be updated\r
-\r
- @retval EFI_SUCCESS Get the address successfully.\r
- @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.\r
-**/\r
-\r
-EFI_STATUS\r
-SynEfiVariable (\r
- IN BOOLEAN VarToList,\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- CHAR8 *DataBase;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
-\r
- Status = EFI_SUCCESS;\r
- DataBase = NULL;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if (VarToList) {\r
- //\r
- //Copy the data from NV to the VarList.\r
- //\r
- if (VariableHeader != NULL) {\r
- if (Storage->Buffer == NULL) {\r
- Storage->Buffer = calloc (Storage->Size, sizeof (CHAR8));\r
- ASSERT (Storage->Buffer != NULL);\r
- }\r
- DataBase = (CHAR8*)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- Storage->Buffer,\r
- (VOID *) DataBase,\r
- Storage->Size\r
- );\r
- }\r
- } else {\r
- //\r
- //If existed, copy the List data to the variable in NV directly. If not found, create a new one.\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- //\r
- //If this variable has existed in current FD, the data in VarList has\r
- // been updated, and this variable is not authenticated type, then\r
- // update it from VarList to the FD.\r
- //\r
- if ((VariableHeader != NULL) \\r
- && (Storage->Buffer != NULL)\r
- ) {\r
- DataBase = (CHAR8*)GetVariableDataPtr (VariableHeader);\r
- memcpy (\r
- (VOID *) DataBase,\r
- Storage->Buffer,\r
- Storage->Size\r
- );\r
- } else if ((VariableHeader == NULL) && (Storage->Buffer != NULL)){\r
- //\r
- //If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.\r
- //\r
- if (Storage->NewEfiVarstore\r
- && ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Try to get the available zone from the efi variables\r
- //\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Create the variable header\r
- //\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- } else {\r
- printf ("Error. No available space in NV ram.\n");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return Status;\r
-}\r
-\r
-/**\r
- Remove the variable from Efi variable\r
-\r
- Found the variable with the same name in StorageListHead and remove it.\r
-\r
- @param StorageListHead Decide which variale list be removed.\r
-\r
- @retval EFI_SUCCESS Remove the variables successfully.\r
-**/\r
-EFI_STATUS\r
-RemoveNormalEfiVariable (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if (Storage->Buffer == NULL) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
- if (VariableHeader != NULL) {\r
- VariableHeader->State = VAR_DELETED;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check the store variable is no-authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If no-authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-\r
-BOOLEAN\r
-CheckNormalVarStoreOrNot (\r
- IN VOID *VariableStoreHeader\r
- )\r
-{\r
- if (!CompareGuid (\r
- &gEfiVariableGuid,\r
- &((VARIABLE_STORE_HEADER *)VariableStoreHeader)->Signature)\r
- ) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-/**\r
- Copy variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyVariableToBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
- UINT32 HeaderLength;\r
-\r
- Status = EFI_SUCCESS;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- HeaderLength = 0;\r
- VariableHeader = NULL;\r
- VariableStoreHeader = NULL;\r
-\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return 0;\r
- }\r
- //\r
- // If the first storage under one specified platformId and defaultId, create the variable header\r
- //\r
- if (Index == 0) {\r
- HeaderLength = WriteDefaultAndPlatformId (StorageBeginning, Storage);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength);\r
- //\r
- //Create the Variable Storage header\r
- //\r
- memcpy (&(VariableStoreHeader->Signature), &gEfiVariableGuid, sizeof (EFI_GUID));\r
- VariableStoreHeader->Format = 0x5A;\r
- VariableStoreHeader->State = 0xFE;\r
- //\r
- //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.\r
- //\r
- VariableStoreHeader->Size = gEfiFdInfo.FdSize;\r
- }\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + *(UINT16 *)StorageBeginning);\r
-\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FAIL;\r
- }\r
- //\r
- // Create the variable header\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning) + Storage->Size);\r
-}\r
-/**\r
- Copy variable to binary in multi-platform mode\r
-\r
- @param Storage The pointer to a storage in storage list.\r
- @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId\r
- @param Index The number of the storage. If the Index is 0, record the variable header to\r
- the binary. Or else, only record the storage.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-CopyVariableToNvStoreBinary (\r
- IN FORMSET_STORAGE *Storage,\r
- IN OUT UINT8 *StorageBeginning,\r
- IN UINT32 Index\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 *NewAvailableAddr;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- UINTN VarNameSize;\r
- UINT32 HeaderLength;\r
- PCD_DEFAULT_DATA *PcdDefaultDataHeader;\r
-\r
- Status = EFI_SUCCESS;\r
- NewAvailableAddr = NULL;\r
- VarNameSize = 0;\r
- HeaderLength = 0;\r
- VariableHeader = NULL;\r
- VariableStoreHeader = NULL;\r
-\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- printf ("Error. One variable name is NULL. Its GUID is: ");\r
- PrintGuid(&(Storage->Guid));\r
- return 0;\r
- }\r
- //\r
- // If the first storage under one specified platformId and defaultId, create the variable header\r
- //\r
- if (Index == 0) {\r
- HeaderLength = WriteNvStoreDefaultAndPlatformId (StorageBeginning, Storage);\r
- PcdDefaultDataHeader = (PCD_DEFAULT_DATA *)StorageBeginning;\r
- PcdDefaultDataHeader->HeaderSize = HeaderLength;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength + 4);\r
- //\r
- //Create the Variable Storage header\r
- //\r
- memcpy (&(VariableStoreHeader->Signature), &gEfiVariableGuid, sizeof (EFI_GUID));\r
- VariableStoreHeader->Format = 0x5A;\r
- VariableStoreHeader->State = 0xFE;\r
- //\r
- //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.\r
- //\r
- VariableStoreHeader->Size = gEfiFdInfo.FdSize;\r
- }\r
- PcdDefaultDataHeader = (PCD_DEFAULT_DATA *)StorageBeginning;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + PcdDefaultDataHeader->HeaderSize + 4);\r
- Status = GetVariableVar (\r
- VariableStoreHeader,\r
- Storage->Size + sizeof (VARIABLE_HEADER),\r
- &NewAvailableAddr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FAIL;\r
- }\r
- //\r
- // Create the variable header\r
- //\r
- VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);\r
- VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;\r
- VariableHeader->StartId = VARIABLE_DATA;\r
- VariableHeader->State = VAR_ADDED;\r
- VariableHeader->Reserved = 0x0;\r
- if (Storage->NewEfiVarstore) {\r
- VariableHeader->Attributes = Storage->Attributes;\r
- } else {\r
- VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;\r
- }\r
- VariableHeader->NameSize = VarNameSize;\r
- VariableHeader->DataSize = Storage->Size;\r
- //\r
- //Copy the Guid, variable name, and data in sequence.\r
- //\r
- memcpy (\r
- (VOID *)&(VariableHeader->VendorGuid),\r
- &(Storage->Guid),\r
- sizeof (EFI_GUID)\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Name,\r
- VarNameSize\r
- );\r
-\r
- NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
- memcpy (\r
- (VOID *) NewAvailableAddr,\r
- Storage->Buffer,\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning - PcdDefaultDataHeader->HeaderSize - 4) + Storage->Size);\r
-}\r
-/**\r
- Read variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadNvStoreVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- VARIABLE_HEADER *EndOfVariable;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- FORMSET_STORAGE *Storage;\r
- UINT32 Length;\r
- PCD_DEFAULT_DATA *PcdDefaultData;\r
- UINT8 *DataBase;\r
- static UINT16 PreDefaultId;\r
- static UINT64 PrePlatformId;\r
-\r
- VariableStoreHeader = NULL;\r
- Variable = NULL;\r
- Length = 0;\r
- DataBase = Binary;\r
-\r
- PcdDefaultData = (PCD_DEFAULT_DATA *)DataBase;\r
- PrePlatformId = PcdDefaultData->DefaultInfo[0].SkuId;\r
- PreDefaultId = PcdDefaultData->DefaultInfo[0].DefaultId;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + PcdDefaultData->HeaderSize + 4);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
-\r
- for (Variable = GetStartPointer (VariableStoreHeader);\r
- Length < VariableStoreHeader->Size;\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize\r
- ) {\r
- //\r
- // Create the storage\r
- //\r
- Storage = NULL;\r
- Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));\r
- if (Storage == NULL) {\r
- printf ("Allocate memory failed.\n");\r
- return FAIL;\r
- }\r
- //\r
- // Store the DefaultId and PlatformId collected from the header to Storage.\r
- //\r
- Storage->DefaultId[0] = PreDefaultId;\r
- Storage->PlatformId[0] = PrePlatformId;\r
- Storage->DefaultPlatformIdNum = 0;\r
-\r
- Storage->Attributes = Variable->Attributes;\r
- Storage->Size = (UINT16)Variable->DataSize;\r
- Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));\r
- ASSERT (Storage->Name != NULL);\r
- Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));\r
- ASSERT (Storage->Buffer != NULL);\r
- memcpy (\r
- &(Storage->Guid),\r
- &(Variable->VendorGuid),\r
- sizeof (EFI_GUID)\r
- );\r
- memcpy (\r
- Storage->Name,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER),\r
- Variable->NameSize\r
- );\r
- memcpy (\r
- Storage->Buffer,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Assigned the value for comparison in verify mode\r
- //\r
- Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r
- Storage->NewEfiVarstore = TRUE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
-\r
- InsertTailList(StorageListEntry, &Storage->Link);\r
- //\r
- // If the last variable, exit.\r
- //\r
- if (Variable == EndOfVariable) {\r
- break;\r
- }\r
-\r
- Variable = GetNextVariablePtr (Variable);\r
- assert (Variable != NULL);\r
- if (!IsValidVariableHeader(Variable)) {\r
- break;\r
- }\r
- }\r
-\r
- return Length;\r
-}\r
-/**\r
- Read variable to storage list in multi-platform mode\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param StorageListEntry The pointer to the storage list.\r
-\r
- @return length The length of storage\r
-**/\r
-UINT32\r
-ReadVariableToList (\r
- IN UINT8 *Binary,\r
- IN LIST_ENTRY *StorageListEntry\r
- )\r
-{\r
- VARIABLE_HEADER *EndOfVariable;\r
- VARIABLE_HEADER *Variable;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- FORMSET_STORAGE *Storage;\r
- BOOLEAN ReadIdHeaderFlag;\r
- UINT32 Length;\r
- EFI_COMMON_SECTION_HEADER *SectionHeader;\r
- UINT8 *DataBase;\r
- static UINT16 PreDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
- static UINT64 PrePlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];\r
-\r
- VariableStoreHeader = NULL;\r
- Variable = NULL;\r
- ReadIdHeaderFlag = TRUE;\r
- Length = 0;\r
- SectionHeader = (EFI_COMMON_SECTION_HEADER *)Binary;\r
- DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + *(UINT16 *)DataBase);\r
- EndOfVariable = GetEndPointer(VariableStoreHeader);\r
-\r
- for (Variable = GetStartPointer (VariableStoreHeader);\r
- Length < VariableStoreHeader->Size;\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize\r
- ) {\r
- //\r
- // Create the storage\r
- //\r
- Storage = NULL;\r
- Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));\r
- if (Storage == NULL) {\r
- printf ("Allocate memory failed.\n");\r
- return FAIL;\r
- }\r
- //\r
- // If access the first storage, read the platformId and defaultId\r
- //\r
- if (ReadIdHeaderFlag) {\r
- ReadDefaultAndPlatformIdFromBfv (DataBase, Storage);\r
- Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize;\r
- ReadIdHeaderFlag = FALSE;\r
- memcpy (PreDefaultId, Storage->DefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (PrePlatformId, Storage->PlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- } else {\r
- //\r
- // Store the DefaultId and PlatformId collected from the header to Storage.\r
- //\r
- memcpy (Storage->DefaultId, PreDefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));\r
- memcpy (Storage->PlatformId, PrePlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));\r
- }\r
- Storage->Attributes = Variable->Attributes;\r
- Storage->Size = (UINT16)Variable->DataSize;\r
- Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));\r
- ASSERT (Storage->Name != NULL);\r
- Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));\r
- ASSERT (Storage->Buffer != NULL);\r
- memcpy (\r
- &(Storage->Guid),\r
- &(Variable->VendorGuid),\r
- sizeof (EFI_GUID)\r
- );\r
- memcpy (\r
- Storage->Name,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER),\r
- Variable->NameSize\r
- );\r
- memcpy (\r
- Storage->Buffer,\r
- (UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),\r
- Storage->Size * sizeof (CHAR8)\r
- );\r
- //\r
- // Assigned the value for comparison in verify mode\r
- //\r
- Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r
- Storage->NewEfiVarstore = TRUE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
-\r
- InsertTailList(StorageListEntry, &Storage->Link);\r
- //\r
- // If the last variable, exit.\r
- //\r
- if (Variable == EndOfVariable) {\r
- break;\r
- }\r
-\r
- Variable = GetNextVariablePtr (Variable);\r
- assert (Variable != NULL);\r
- }\r
- //\r
- // Return the length which is from the beginning of Binary\r
- //\r
- Length = FvBufExpand3ByteSize (SectionHeader->Size);\r
-\r
- return Length;\r
-}\r
-\r
-/**\r
- Check whether exists the valid normal variables in NvStorage or not.\r
-\r
- @retval TRUE If existed, return TRUE.\r
- @retval FALSE Others\r
-**/\r
-BOOLEAN\r
-ExistNormalEfiVarOrNot (\r
- IN LIST_ENTRY *StorageListHead\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_HEADER *VarAddr;\r
- LIST_ENTRY *StorageLink;\r
- FORMSET_STORAGE *Storage;\r
- VARIABLE_HEADER *VariableHeader;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableHeader = NULL;\r
- VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);\r
- //\r
- //Parse the variable range, and check whether there is some existed ones.\r
- //\r
- StorageLink = GetFirstNode (StorageListHead);\r
- while (!IsNull (StorageListHead, StorageLink)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
- //\r
- // Ignore the invalid varlist node\r
- //\r
- if ((Storage->Buffer == NULL)\r
- || (Storage->Name == NULL)\r
- || (FceStrLen(Storage->Name) == 0)\r
- ) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- //\r
- // Report error, if the variable name is invalid.\r
- //\r
- if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- continue;\r
- }\r
- VariableHeader = FindVariableInNv (\r
- VariableStoreHeader,\r
- Storage\r
- );\r
-\r
- if ((VariableHeader != NULL)) {\r
- return TRUE;\r
- }\r
- StorageLink = GetNextNode (StorageListHead, StorageLink);\r
- }\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Fix the size of variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- )\r
-{\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
-\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + *(UINT16 *)BinaryBeginning);\r
- VariableStoreHeader->Size = Length - *(UINT16 *)BinaryBeginning;\r
-}\r
-\r
-/**\r
- Fix the size of variable header.\r
-\r
- @param Binary The pointer to the header of storage under specifed platformId and defaultId\r
- @param Length The length of binary.\r
-\r
-**/\r
-VOID\r
-FixNvStoreVariableHeaderSize (\r
- IN UINT8 *BinaryBeginning,\r
- IN UINT32 Length\r
- )\r
-{\r
- VARIABLE_STORE_HEADER *VariableStoreHeader;\r
- PCD_DEFAULT_DATA *PcdDefaultDataHeader;\r
-\r
- PcdDefaultDataHeader = (PCD_DEFAULT_DATA *)(BinaryBeginning);\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + PcdDefaultDataHeader->HeaderSize + 4);\r
- VariableStoreHeader->Size = Length;\r
- PcdDefaultDataHeader->DataSize = VariableStoreHeader->Size + PcdDefaultDataHeader->HeaderSize + 4;\r
-}\r
-\r
+++ /dev/null
-/** @file\r
-\r
- The header of Variable.c.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __VARIABLE_FORMAT_H__\r
-#define __VARIABLE_FORMAT_H__\r
-\r
-#define EFI_VARIABLE_GUID \\r
- { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } }\r
-\r
-extern EFI_GUID gEfiVariableGuid;\r
-\r
-///\r
-/// Alignment of variable name and data, according to the architecture:\r
-/// * For IA-32 and Intel(R) 64 architectures: 1.\r
-/// * For IA-64 architecture: 8.\r
-///\r
-#if defined (MDE_CPU_IPF)\r
-#define ALIGNMENT 8\r
-#else\r
-#define ALIGNMENT 1\r
-#endif\r
-\r
-///\r
-/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.\r
-///\r
-#if (ALIGNMENT == 1)\r
-#define GET_PAD_SIZE(a) (0)\r
-#else\r
-#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))\r
-#endif\r
-\r
-///\r
-/// Alignment of Variable Data Header in Variable Store region.\r
-///\r
-#define HEADER_ALIGNMENT 4\r
-#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))\r
-\r
-///\r
-/// Status of Variable Store Region.\r
-///\r
-typedef enum {\r
- EfiRaw,\r
- EfiValid,\r
- EfiInvalid,\r
- EfiUnknown\r
-} VARIABLE_STORE_STATUS;\r
-\r
-#pragma pack(1)\r
-\r
-#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID\r
-\r
-///\r
-/// Variable Store Header Format and State.\r
-///\r
-#define VARIABLE_STORE_FORMATTED 0x5a\r
-#define VARIABLE_STORE_HEALTHY 0xfe\r
-\r
-///\r
-/// Variable Store region header.\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable store region signature.\r
- ///\r
- EFI_GUID Signature;\r
- ///\r
- /// Size of entire variable store,\r
- /// including size of variable store header but not including the size of FvHeader.\r
- ///\r
- UINT32 Size;\r
- ///\r
- /// Variable region format state.\r
- ///\r
- UINT8 Format;\r
- ///\r
- /// Variable region healthy state.\r
- ///\r
- UINT8 State;\r
- UINT16 Reserved;\r
- UINT32 Reserved1;\r
-} VARIABLE_STORE_HEADER;\r
-\r
-///\r
-/// Variable data start flag.\r
-///\r
-#define VARIABLE_DATA 0x55AA\r
-\r
-///\r
-/// Variable State flags.\r
-///\r
-#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition.\r
-#define VAR_DELETED 0xfd ///< Variable is obsolete.\r
-#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid.\r
-#define VAR_ADDED 0x3f ///< Variable has been completely added.\r
-\r
-///\r
-/// Single Variable Data Header Structure.\r
-///\r
-typedef struct {\r
- ///\r
- /// Variable Data Start Flag.\r
- ///\r
- UINT16 StartId;\r
- ///\r
- /// Variable State defined above.\r
- ///\r
- UINT8 State;\r
- UINT8 Reserved;\r
- ///\r
- /// Attributes of variable defined in UEFI specification.\r
- ///\r
- UINT32 Attributes;\r
- ///\r
- /// Size of variable null-terminated Unicode string name.\r
- ///\r
- UINT32 NameSize;\r
- ///\r
- /// Size of the variable data without this header.\r
- ///\r
- UINT32 DataSize;\r
- ///\r
- /// A unique identifier for the vendor that produces and consumes this varaible.\r
- ///\r
- EFI_GUID VendorGuid;\r
-} VARIABLE_HEADER;\r
-\r
-#pragma pack()\r
-\r
-typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;\r
-\r
-///\r
-/// This structure contains the variable list that is put in EFI system table.\r
-/// The variable driver collects all variables that were used at boot service time and produces this list.\r
-/// This is an optional feature to dump all used variables in shell environment.\r
-///\r
-struct _VARIABLE_INFO_ENTRY {\r
- VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.\r
- EFI_GUID VendorGuid; ///< Guid of Variable.\r
- CHAR16 *Name; ///< Name of Variable.\r
- UINT32 Attributes; ///< Attributes of variable defined in UEFI specification.\r
- UINT32 ReadCount; ///< Number of times to read this variable.\r
- UINT32 WriteCount; ///< Number of times to write this variable.\r
- UINT32 DeleteCount; ///< Number of times to delete this variable.\r
- UINT32 CacheCount; ///< Number of times that cache hits this variable.\r
- BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.\r
-};\r
-\r
-#endif // _EFI_VARIABLE_H_\r
+++ /dev/null
-/** @file\r
-\r
- The header of common Variable.c TimeBasedVariable.c and MonotonicBasedVariable.c.\r
-\r
- Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __VARIABLE_COMMON_H__\r
-#define __VARIABLE_COMMON_H__\r
-\r
-/**\r
- Check the store variable is no-authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If no-authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-\r
-BOOLEAN\r
-CheckNormalVarStoreOrNot (\r
- IN VOID *VariableStoreHeader\r
- );\r
-/**\r
- Check the store variable is Monotonic based authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-\r
-BOOLEAN\r
-CheckMonotonicBasedVarStore (\r
- IN VOID *VariableStoreHeader\r
- );\r
-\r
-/**\r
- Check the store variable is Time stamp authenticated or not\r
-\r
- @param VarToList The pointer to the header of Variable Store.\r
-\r
- @retval TRUE If authenticated, return TRUE.\r
- @retval FALSE Otherwise, return FALSE.\r
-**/\r
-BOOLEAN\r
-CheckTimeBasedVarStoreOrNot (\r
- IN VOID *VariableStoreHeader\r
- );\r
-\r
-\r
-\r
-#endif // _EFI_VARIABLE_COMMON_H_\r
## @file\r
# GNU/Linux makefile for C tools build.\r
#\r
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
VfrCompile \\r
BfmLib \\r
EfiRom \\r
- FCE \\r
GenFfs \\r
GenFv \\r
GenFw \\r
## @file\r
# Windows makefile for C tools build.\r
#\r
-# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
HOST_ARCH = IA32\r
BrotliCompress \\r
BfmLib \\r
EfiRom \\r
- FCE \\r
GenCrc32 \\r
GenFfs \\r
GenFv \\r