BaseTools/FCE: Add a tool FCE

FCE is a tool to retrieve and change HII configuration data in
Firmware Device(*.fd) files.
https://bugzilla.tianocore.org/show_bug.cgi?id=1848

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
This commit is contained in:
Shenglei Zhang 2019-05-28 16:07:43 +08:00 committed by Liming Gao
parent dc7b0dc8d6
commit 3c59d94637
23 changed files with 23443 additions and 2 deletions

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
dir=$(dirname "$full_cmd")
cmd=${full_cmd##*/}
if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
then
exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
then
if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
then
echo "BaseTools C Tool binary was not found ($cmd)"
echo "You may need to run:"
echo " make -C $EDK_TOOLS_PATH/Source/C"
else
exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
fi
elif [ -e "$dir/../../Source/C/bin/$cmd" ]
then
exec "$dir/../../Source/C/bin/$cmd" "$@"
else
echo "Unable to find the real '$cmd' to run"
echo "This message was printed by"
echo " $0"
exit 127
fi

View File

@ -0,0 +1,216 @@
/** @file
The API to create the binary.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BinaryCreate.h"
#ifndef __GNUC__
#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > NUL"
#else
#define GENSEC_RAW "GenSec -s %s \"%s\" -o \"%s\" > /dev/null"
#endif
//
// The guid is to for FFS of BFV.
//
EFI_GUID gEfiFfsBfvForMultiPlatformGuid = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID;
EFI_GUID gEfiFfsBfvForMultiPlatformGuid2 = EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2;
/**
Convert a GUID to a string.
@param[in] Guid Pointer to GUID to print.
@return The string after convert.
**/
static
CHAR8 *
LibBfmGuidToStr (
IN EFI_GUID *Guid
)
{
CHAR8 * Buffer;
Buffer = NULL;
if (Guid == NULL) {
return NULL;
}
Buffer = (CHAR8 *) malloc (36 + 1);
if (Buffer == NULL) {
return NULL;
}
memset (Buffer, '\0', 36 + 1);
sprintf (
Buffer,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Guid->Data1,
Guid->Data2,
Guid->Data3,
Guid->Data4[0],
Guid->Data4[1],
Guid->Data4[2],
Guid->Data4[3],
Guid->Data4[4],
Guid->Data4[5],
Guid->Data4[6],
Guid->Data4[7]
);
return Buffer;
}
/**
Create the Ras section in FFS
@param[in] InputFilePath .efi file, it's optional unless process PE/TE section.
@param[in] OutputFilePath .te or .pe file
@retval EFI_SUCCESS
**/
EFI_STATUS
CreateRawSection (
IN CHAR8* InputFilePath,
IN CHAR8* OutputFilePath
)
{
INT32 ReturnValue;
CHAR8* SystemCommand;
SystemCommand = NULL;
SystemCommand = malloc (
strlen (GENSEC_RAW) +
strlen ("EFI_SECTION_RAW") +
strlen (InputFilePath) +
strlen (OutputFilePath) +
1
);
if (NULL == SystemCommand) {
return EFI_OUT_OF_RESOURCES;
}
sprintf (
SystemCommand,
GENSEC_RAW,
"EFI_SECTION_RAW",
InputFilePath,
OutputFilePath
);
ReturnValue = system (SystemCommand);
free(SystemCommand);
if (ReturnValue != 0) {
printf ("Error. Call GenSec failed.\n");
return EFI_ABORTED;
}
return EFI_SUCCESS;
}
/**
Create the Ras type of FFS
@param[in] InputFilePath .efi file, it's optional unless process PE/TE section.
@param[in] OutputFilePath .te or .pe file
@retval EFI_SUCCESS
**/
EFI_STATUS
CreateRawFfs (
IN CHAR8** InputFilePaths,
IN CHAR8* OutputFilePath,
IN BOOLEAN SizeOptimized
)
{
INT32 ReturnValue;
CHAR8* SystemCommandFormatString;
CHAR8* SystemCommand;
CHAR8* GuidStr;
CHAR8* FilePathFormatStr;
CHAR8* FilePathStr;
UINT32 Index;
UINT32 StrLen;
UINT32 Size;
SystemCommand = NULL;
GuidStr = NULL;
FilePathStr = NULL;
StrLen = 0;
FilePathFormatStr = " -i \"";
for (Index = 0; InputFilePaths[Index] != NULL; Index++) {
Size = strlen (FilePathFormatStr) + strlen (InputFilePaths[Index]) + 2; // 2 menas "" "
if (FilePathStr == NULL) {
FilePathStr = malloc (Size);
if (NULL == FilePathStr) {
return EFI_OUT_OF_RESOURCES;
}
} else {
FilePathStr = realloc (FilePathStr, StrLen + Size);
if (NULL == FilePathStr) {
return EFI_OUT_OF_RESOURCES;
}
}
memset (FilePathStr + StrLen, ' ', Size);
memcpy (FilePathStr + StrLen, FilePathFormatStr, strlen(FilePathFormatStr));
memcpy(FilePathStr + StrLen + strlen(FilePathFormatStr), InputFilePaths[Index], strlen(InputFilePaths[Index]));
StrLen += Size;
*(FilePathStr + StrLen - 2) = '\"';
}
if (FilePathStr == NULL) {
return EFI_ABORTED;
}
*(FilePathStr + StrLen - 1)= '\0';
if (SizeOptimized) {
GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid2);
} else {
GuidStr = LibBfmGuidToStr(&gEfiFfsBfvForMultiPlatformGuid);
}
if (NULL == GuidStr) {
free (FilePathStr);
return EFI_OUT_OF_RESOURCES;
}
SystemCommandFormatString = "GenFfs -t %s %s -g %s -o \"%s\"";
SystemCommand = malloc (
strlen (SystemCommandFormatString) +
strlen ("EFI_FV_FILETYPE_FREEFORM") +
strlen (FilePathStr) +
strlen (GuidStr) +
strlen (OutputFilePath) +
1
);
if (NULL == SystemCommand) {
free (GuidStr);
free (FilePathStr);
return EFI_OUT_OF_RESOURCES;
}
sprintf (
SystemCommand,
"GenFfs -t %s %s -g %s -o \"%s\"",
"EFI_FV_FILETYPE_FREEFORM",// -t
FilePathStr, // -i
GuidStr, // -g
OutputFilePath // -o
);
ReturnValue = system (SystemCommand);
free(SystemCommand);
free (FilePathStr);
free (GuidStr);
if (ReturnValue != 0) {
printf ("Error. Call GenFfs failed.\n");
return EFI_ABORTED;
}
return EFI_SUCCESS;
}

View File

@ -0,0 +1,157 @@
/** @file
The API to create the binary.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _BINARY_CREATE_H_
#define _BINARY_CREATE_H_ 1
#include <FvLib.h>
#include "Compress.h"
#include "Decompress.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"
#include "FirmwareVolumeBufferLib.h"
#include "OsPath.h"
#include "ParseGuidedSectionTools.h"
#include "StringFuncs.h"
#include "ParseInf.h"
#include <Common/UefiBaseTypes.h>
#include <Common/UefiInternalFormRepresentation.h>
#include <Common/UefiCapsule.h>
#include <Common/PiFirmwareFile.h>
#include <Common/PiFirmwareVolume.h>
#include <Guid/PiFirmwareFileSystem.h>
#include <IndustryStandard/PeImage.h>
#include <Protocol/GuidedSectionExtraction.h>
//1AE42876-008F-4161-B2B7-1C0D15C5EF43
#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID \
{ 0x1ae42876, 0x008f, 0x4161, { 0xb2, 0xb7, 0x1c, 0xd, 0x15, 0xc5, 0xef, 0x43 }}
extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid;
// {003E7B41-98A2-4BE2-B27A-6C30C7655225}
#define EFI_FFS_BFV_FOR_MULTIPLATFORM_GUID2 \
{ 0x3e7b41, 0x98a2, 0x4be2, { 0xb2, 0x7a, 0x6c, 0x30, 0xc7, 0x65, 0x52, 0x25 }}
extern EFI_GUID gEfiFfsBfvForMultiPlatformGuid2;
typedef UINT64 SKU_ID;
typedef struct {
UINT32 Offset:24;
UINT32 Value:8;
} PCD_DATA_DELTA;
typedef struct {
SKU_ID SkuId;
UINT16 DefaultId;
UINT8 Reserved[6];
} PCD_DEFAULT_INFO;
typedef struct {
//
// Full size, it must be at 8 byte alignment.
//
UINT32 DataSize;
//
// HeaderSize includes HeaderSize fields and DefaultInfo arrays
//
UINT32 HeaderSize;
//
// DefaultInfo arrays those have the same default setting.
//
PCD_DEFAULT_INFO DefaultInfo[1];
//
// Default data is stored as variable storage or the array of DATA_DELTA.
//
} PCD_DEFAULT_DATA;
#define PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE SIGNATURE_32('N', 'S', 'D', 'B')
typedef struct {
//
// PCD_NV_STORE_DEFAULT_BUFFER_SIGNATURE
//
UINT32 Signature;
//
// Length of the taken default buffer
//
UINT32 Length;
//
// Length of the total reserved buffer
//
UINT32 MaxLength;
//
// Reserved for 8 byte alignment
//
UINT32 Reserved;
// one or more PCD_DEFAULT_DATA
} PCD_NV_STORE_DEFAULT_BUFFER_HEADER;
//
// NvStoreDefaultValueBuffer layout:
// +-------------------------------------+
// | PCD_NV_STORE_DEFAULT_BUFFER_HEADER |
// +-------------------------------------+
// | PCD_DEFAULT_DATA (DEFAULT, Standard)|
// +-------------------------------------+
// | PCD_DATA_DELTA (DEFAULT, Standard)|
// +-------------------------------------+
// | ...... |
// +-------------------------------------+
// | PCD_DEFAULT_DATA (SKU A, Standard) |
// +-------------------------------------+
// | PCD_DATA_DELTA (SKU A, Standard) |
// +-------------------------------------+
// | ...... |
// +-------------------------------------+
//
#pragma pack(1)
typedef struct {
UINT16 Offset;
UINT8 Value;
} DATA_DELTA;
#pragma pack()
/**
Create the Ras section in FFS
@param[in] InputFilePath The input file path and name.
@param[in] OutputFilePath The output file path and name.
@retval EFI_SUCCESS
**/
EFI_STATUS
CreateRawSection (
IN CHAR8* InputFilePath,
IN CHAR8* OutputFilePath
);
/**
Create the Ras type of FFS
@param[in] InputFilePath .efi file, it's optional unless process PE/TE section.
@param[in] OutputFilePath .te or .pe file
@retval EFI_SUCCESS
**/
EFI_STATUS
CreateRawFfs (
IN CHAR8** InputFilePaths,
IN CHAR8* OutputFilePath,
IN BOOLEAN SizeOptimized
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,187 @@
/** @file
The API to parse the binary.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _BINARY_PARSE_H_
#define _BINARY_PARSE_H_ 1
#include <FvLib.h>
#include "Compress.h"
#include "Decompress.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"
#include "FirmwareVolumeBufferLib.h"
#include "OsPath.h"
#include "ParseGuidedSectionTools.h"
#include "StringFuncs.h"
#include "ParseInf.h"
#include <Common/UefiBaseTypes.h>
#include <Common/UefiInternalFormRepresentation.h>
#include <Common/UefiCapsule.h>
#include <Common/PiFirmwareFile.h>
#include <Common/PiFirmwareVolume.h>
#include <Guid/PiFirmwareFileSystem.h>
#include <IndustryStandard/PeImage.h>
#include <Protocol/GuidedSectionExtraction.h>
#ifdef __GNUC__
#define OS_SEP '/'
#define OS_SEP_STR "/"
#else
#define OS_SEP '\\'
#define OS_SEP_STR "\\"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define TEMP_DIR_NAME "Temp"
#define MAX_FILENAME_LEN 200
#define MAX_MATCH_GUID_NUM 100
#define MAX_EFI_IN_FFS_NUM 100
typedef struct {
VOID *Fd;
UINT32 FdSize;
UINTN EfiVariableAddr;
UINTN Length[MAX_EFI_IN_FFS_NUM];
VOID *FfsArray[MAX_EFI_IN_FFS_NUM];
VOID *StorageFfsInBfv;
VOID *NvStoreDatabase;
BOOLEAN ExistNvStoreDatabase;
} G_EFI_FD_INFO;
///
///Define the structure for th sections
///
typedef struct {
UINTN BufferBase;
UINTN UncompressedBuffer[MAX_EFI_IN_FFS_NUM];
UINTN Length;
UINT8 UnCompressIndex;
} EFI_SECTION_STRUCT;
// {d0bc7cb4-6a47-495f-aa11-710746da06a2}
#define EFI_VFR_ATTRACT_GUID \
{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
// {8913C5E0-33F6-4d86-9BF1-43EF89FC0666}
#define EFI_UNI_STR_ATTRACT_GUID \
{ 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
// {FFF12B8D-7696-4C8B-A985-2747075B4F50}
#define EFI_SYSTEM_NVDATA_FV_GUID \
{ 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
/**
Parses FFS Sections, and remove the FFS headers. Tis function olny handle one efi in this FFS.
@param SectionBuffer The section base address
@param BufferLength The length of FFS.
@param EfiBufferHeader The structure dual pointer to the efi informations
@retval EFI_SUCCESS The application exited normally.
@retval EFI_ABORTED An error occurred.
**/
EFI_STATUS
ParseSection (
IN BOOLEAN IsFfsOrEfi,
IN OUT UINT8 *SectionBuffer,
IN UINT32 BufferLength,
IN OUT EFI_SECTION_STRUCT **EfiBufferHeader
);
/**
Search the VfrBin Base address.
According the known GUID gVfrArrayAttractGuid to get the base address from FFS.
@param Fv the Pointer to the FFS
@param EfiAddr the Pointer to the EFI in FFS
@param Length the length of Fv
@param Offset the Pointer to the Addr (Offset)
@param NumOfMachingOffset the number of Addr (Offset)
@retval EFI_SUCCESS Get the address successfully.
**/
EFI_STATUS
SearchVfrBinInFFS (
IN VOID *Fv,
IN VOID *EfiAddr,
IN UINTN Length,
OUT UINTN **Offset,
OUT UINT8 *NumOfMachingOffset
);
/**
Search the UniBin Base address.
According the known GUID gUniStrArrayAttractGuid to get the base address from FFS.
@param Fv the Pointer to the FFS
@param EfiAddr the Pointer to the EFI in FFS
@param Length the length of Fv
@param Offset the Pointer to the Addr (Offset)
@retval Base address Get the address successfully.
**/
EFI_STATUS
SearchUniBinInFFS (
IN VOID *Fv,
IN VOID *EfiAddr,
IN UINTN Length,
OUT UINTN **Offset
);
/**
Read the file to memory.
@param InputFile The file that contains the FV image.
@param Size The size of the file.
@retval The pointer to the begining position of memory.
**/
VOID *
ReadFileToMemory (
IN CHAR8 *FileName,
OUT UINT32 *Size
);
/**
Search the EFI variables address in Fd.
Open and read the *.fd to the memory, initialize the global structure.
Update the EFI variables addr and the begining position of memory.
@retval EFI_SUCCESS Get the address successfully.
**/
EFI_STATUS
GetEfiVariablesAddr (
BOOLEAN UqiIsSet
);
/**
Pick up the FFS which includes IFR section.
Parse all FFS extracted by BfmLib, and save all which includes IFR
Binary to gEfiFdInfo structure.
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_BUFFER_TOO_SMALL Memory can't be allocated.
@retval EFI_ABORTED Read FFS Failed.
**/
EFI_STATUS
FindFileInFolder (
IN CHAR8 *FolderName,
OUT BOOLEAN *ExistStorageInBfv,
OUT BOOLEAN *SizeOptimized
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,999 @@
/** @file
Common library.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _COMMON_LIB_H_
#define _COMMON_LIB_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#include <unistd.h>
#else
#include <io.h>
#include <direct.h>
#endif
#include <ctype.h>
#include <assert.h>
#include <math.h>
#include "CommonLib.h"
#include <Common/UefiBaseTypes.h>
#define MAX_QUI_PARAM_LEN 2000
#define ERROR_INFO_LENGTH 400
#define MAX_STR_LEN_FOR_PICK_UQI 200
#define MAX_PLATFORM_DEFAULT_ID_NUM 1000
#define _MAX_BUILD_VERSION 100
#define _MAXIMUM_SECTION_FILE_NUM 1000
#ifndef _MAX_PATH
#define _MAX_PATH 500
#endif
///
/// Variable attributes.
///
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
///
/// This attribute is identified by the mnemonic 'HR'
/// elsewhere in this specification.
///
#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
#define VARSTORE_LIST_TYPE 0x0000000000000001ULL
#define EFI_VARSTORE_LIST_TYPE 0x0000000000000002ULL
#define PLATFORM_DEFAULT_ID_TYPE 0x0000000000000004ULL
#define UQI_LIST_TYPE 0x0000000000000008ULL
#define HII_OBJ_LIST_TYPE 0x0000000000000010ULL
///
/// LIST_ENTRY structure definition.
///
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *ForwardLink;
struct _LIST_ENTRY *BackLink;
} LIST_ENTRY;
#define CR(Record, TYPE, Field, TestSignature) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
#define AllocateZeroPool(a) calloc(a, sizeof (CHAR8))
#define FreePool(a) free(a)
#define CopyMem(a, b, c) memcpy(a, b, c)
#define ZeroMem(a, b) memset(a, 0, b)
#define CompareMem(a, b, c) memcmp(a, b, c)
#define AllocatePool(a) malloc(a)
/**
Returns a 16-bit signature built from 2 ASCII characters.
This macro returns a 16-bit value built from the two ASCII characters specified
by A and B.
@param A The first ASCII character.
@param B The second ASCII character.
@return A 16-bit value built from the two ASCII characters specified by A and B.
**/
#define SIGNATURE_16(A, B) ((A) | (B << 8))
/**
Returns a 32-bit signature built from 4 ASCII characters.
This macro returns a 32-bit value built from the four ASCII characters specified
by A, B, C, and D.
@param A The first ASCII character.
@param B The second ASCII character.
@param C The third ASCII character.
@param D The fourth ASCII character.
@return A 32-bit value built from the two ASCII characters specified by A, B,
C and D.
**/
#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
#define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)
/**
Returns an argument of a specified type from a variable argument list and updates
the pointer to the variable argument list to point to the next argument.
This function returns an argument of the type specified by TYPE from the beginning
of the variable argument list specified by Marker. Marker is then updated to point
to the next argument in the variable argument list. The method for computing the
pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.
@param Marker The pointer to the beginning of a variable argument list.
@param TYPE The type of argument to retrieve from the beginning
of the variable argument list.
@return An argument of the type specified by TYPE.
**/
#define BASE_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))
///
/// Define the maximum number of characters that are required to
/// encode with a NULL terminator a decimal, hexadecimal, GUID,
/// or TIME value.
///
/// Maximum Length Decimal String = 28
/// "-9,223,372,036,854,775,808"
/// Maximum Length Hexadecimal String = 17
/// "FFFFFFFFFFFFFFFF"
/// Maximum Length GUID = 37
/// "00000000-0000-0000-0000-000000000000"
/// Maximum Length TIME = 18
/// "12/12/2006 12:12"
///
#define MAXIMUM_VALUE_CHARACTERS 38
///
/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
///
typedef UINTN *BASE_LIST;
/**
Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary.
@param TYPE The date type to determine the size of.
@return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary.
**/
#define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN))
//
// Print primitives
//
#define PREFIX_SIGN BIT1
#define PREFIX_BLANK BIT2
#define LONG_TYPE BIT4
#define OUTPUT_UNICODE BIT6
#define FORMAT_UNICODE BIT8
#define PAD_TO_WIDTH BIT9
#define ARGUMENT_UNICODE BIT10
#define PRECISION BIT11
#define ARGUMENT_REVERSED BIT12
#define COUNT_ONLY_NO_PRINT BIT13
///
/// Flags bitmask values use in UnicodeValueToString() and
/// AsciiValueToString()
///
#define LEFT_JUSTIFY 0x01
#define COMMA_TYPE 0x08
#define PREFIX_ZERO 0x20
#define RADIX_HEX 0x80
//
// Record date and time information
//
typedef struct {
UINT16 Year;
UINT8 Month;
UINT8 Day;
UINT8 Hour;
UINT8 Minute;
UINT8 Second;
UINT8 Pad1;
UINT32 Nanosecond;
INT16 TimeZone;
UINT8 Daylight;
UINT8 Pad2;
} TIME;
/**
Copies one Null-terminated Unicode string to another Null-terminated Unicode
string and returns the new Unicode string.
This function copies the contents of the Unicode string Source to the Unicode
string Destination, and returns Destination. If Source and Destination
overlap, then the results are undefined.
If Destination is NULL, then return NULL.
If Destination is not aligned on a 16-bit boundary, then return NULL.
@param Destination A pointer to a Null-terminated Unicode string.
@param Source A pointer to a Null-terminated Unicode string.
@return Destination.
**/
CHAR16 *
StrCpy (
OUT CHAR16 *Destination,
IN CONST CHAR16 *Source
);
/**
Returns the length of a Null-terminated Unicode string.
This function returns the number of Unicode characters in the Null-terminated
Unicode string specified by String.
If String is NULL, then return 0.
@param String A pointer to a Null-terminated Unicode string.
@return The length of String.
**/
UINTN
FceStrLen (
IN CONST CHAR16 *String
);
/**
Returns the size of a Null-terminated Unicode string in bytes, including the
Null terminator.
This function returns the size, in bytes, of the Null-terminated Unicode string
specified by String.
If String is NULL, then ASSERT().
If String is not aligned on a 16-bit boundary, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
PcdMaximumUnicodeStringLength Unicode characters, not including the
Null-terminator, then ASSERT().
@param String A pointer to a Null-terminated Unicode string.
@return The size of String.
**/
UINTN
FceStrSize (
IN CONST CHAR16 *String
);
/**
Compares two Null-terminated Unicode strings, and returns the difference
between the first mismatched Unicode characters.
This function compares the Null-terminated Unicode string FirstString to the
Null-terminated Unicode string SecondString. If FirstString is identical to
SecondString, then 0 is returned. Otherwise, the value returned is the first
mismatched Unicode character in SecondString subtracted from the first
mismatched Unicode character in FirstString.
@param FirstString A pointer to a Null-terminated Unicode string.
@param SecondString A pointer to a Null-terminated Unicode string.
@retval 0 FirstString is identical to SecondString.
@return others FirstString is not identical to SecondString.
**/
INTN
FceStrCmp (
IN CONST CHAR16 *FirstString,
IN CONST CHAR16 *SecondString
);
/**
Concatenates one Null-terminated Unicode string to another Null-terminated
Unicode string, and returns the concatenated Unicode string.
This function concatenates two Null-terminated Unicode strings. The contents
of Null-terminated Unicode string Source are concatenated to the end of
Null-terminated Unicode string Destination. The Null-terminated concatenated
Unicode String is returned. If Source and Destination overlap, then the
results are undefined.
If Destination is NULL, then ASSERT().
If Destination is not aligned on a 16-bit boundary, then ASSERT().
If Source is NULL, then ASSERT().
If Source is not aligned on a 16-bit boundary, then ASSERT().
If Source and Destination overlap, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
than PcdMaximumUnicodeStringLength Unicode characters, not including the
Null-terminator, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
PcdMaximumUnicodeStringLength Unicode characters, not including the
Null-terminator, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
and Source results in a Unicode string with more than
PcdMaximumUnicodeStringLength Unicode characters, not including the
Null-terminator, then ASSERT().
@param Destination A pointer to a Null-terminated Unicode string.
@param Source A pointer to a Null-terminated Unicode string.
@return Destination.
**/
CHAR16 *
StrCat (
IN OUT CHAR16 *Destination,
IN CONST CHAR16 *Source
);
/**
Returns the first occurrence of a Null-terminated Unicode sub-string
in a Null-terminated Unicode string.
This function scans the contents of the Null-terminated Unicode string
specified by String and returns the first occurrence of SearchString.
If SearchString is not found in String, then NULL is returned. If
the length of SearchString is zero, then String is
returned.
If String is NULL, then ASSERT().
If String is not aligned on a 16-bit boundary, then ASSERT().
If SearchString is NULL, then ASSERT().
If SearchString is not aligned on a 16-bit boundary, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and SearchString
or String contains more than PcdMaximumUnicodeStringLength Unicode
characters, not including the Null-terminator, then ASSERT().
@param String A pointer to a Null-terminated Unicode string.
@param SearchString A pointer to a Null-terminated Unicode string to search for.
@retval NULL If the SearchString does not appear in String.
@return others If there is a match.
**/
CHAR16 *
StrStr (
IN CONST CHAR16 *String,
IN CONST CHAR16 *SearchString
);
/**
Convert a Null-terminated Unicode decimal string to a value of
type UINT64.
This function returns a value of type UINT64 by interpreting the contents
of the Unicode string specified by String as a decimal number. The format
of the input Unicode string String is:
[spaces] [decimal digits].
The valid decimal digit character is in the range [0-9]. The
function will ignore the pad space, which includes spaces or
tab characters, before [decimal digits]. The running zero in the
beginning of [decimal digits] will be ignored. Then, the function
stops at the first character that is a not a valid decimal character
or a Null-terminator, whichever one comes first.
If String is NULL, then ASSERT().
If String is not aligned in a 16-bit boundary, then ASSERT().
If String has only pad spaces, then 0 is returned.
If String has no pad spaces or valid decimal digits,
then 0 is returned.
If the number represented by String overflows according
to the range defined by UINT64, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and String contains
more than PcdMaximumUnicodeStringLength Unicode characters, not including
the Null-terminator, then ASSERT().
@param String A pointer to a Null-terminated Unicode string.
@retval Value translated from String.
**/
UINT64
FceStrDecimalToUint64 (
IN CONST CHAR16 *String
);
/**
Convert one Null-terminated ASCII string to a Null-terminated
Unicode string and returns the Unicode string.
This function converts the contents of the ASCII string Source to the Unicode
string Destination, and returns Destination. The function terminates the
Unicode string Destination by appending a Null-terminator character at the end.
The caller is responsible to make sure Destination points to a buffer with size
equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
@param Source A pointer to a Null-terminated ASCII string.
@param Destination A pointer to a Null-terminated Unicode string.
@return Destination.
@return NULL If Destination or Source is NULL, return NULL.
**/
CHAR16 *
AsciiStrToUnicodeStr (
IN CONST CHAR8 *Source,
OUT CHAR16 *Destination
);
/**
Worker function that produces a Null-terminated string in an output buffer
based on a Null-terminated format string and variable argument list.
VSPrint function to process format and place the results in Buffer. Since a
VA_LIST is used this routine allows the nesting of Vararg routines. Thus
this is the main print working routine
@param StartOfBuffer The character buffer to print the results of the parsing
of Format into.
@param BufferSize The maximum number of characters to put into buffer.
Zero means no limit.
@param Flags Initial flags value.
Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
@param FormatString A Null-terminated format string.
@param ... The variable argument list.
@return The number of characters printed.
**/
UINTN
BasePrintLibSPrint (
OUT CHAR8 *StartOfBuffer,
IN UINTN BufferSize,
IN UINTN Flags,
IN CONST CHAR8 *FormatString,
...
);
/**
Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
Unicode format string and variable argument list.
Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
and BufferSize.
The Unicode string is produced by parsing the format string specified by FormatString.
Arguments are pulled from the variable argument list based on the contents of the format string.
The number of Unicode characters in the produced output buffer is returned not including
the Null-terminator.
If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
If BufferSize > 1 and FormatString is NULL, then ASSERT().
If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
Null-terminator, then ASSERT().
@param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
Unicode string.
@param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
@param FormatString A Null-terminated Unicode format string.
@param ... Variable argument list whose contents are accessed based on the
format string specified by FormatString.
@return The number of Unicode characters in the produced output buffer not including the
Null-terminator.
**/
UINTN
UnicodeSPrint (
OUT CHAR16 *StartOfBuffer,
IN UINTN BufferSize,
IN CONST CHAR16 *FormatString,
...
);
/**
Convert a Null-terminated Unicode string to a Null-terminated
ASCII string and returns the ASCII string.
This function converts the content of the Unicode string Source
to the ASCII string Destination by copying the lower 8 bits of
each Unicode character. It returns Destination. The function terminates
the ASCII string Destination by appending a Null-terminator character
at the end. The caller is responsible to make sure Destination points
to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes.
If Destination is NULL, then ASSERT().
If Source is NULL, then ASSERT().
If Source is not aligned on a 16-bit boundary, then ASSERT().
If Source and Destination overlap, then ASSERT().
If any Unicode characters in Source contain non-zero value in
the upper 8 bits, then ASSERT().
@param Source Pointer to a Null-terminated Unicode string.
@param Destination Pointer to a Null-terminated ASCII string.
@reture Destination
**/
CHAR8 *
UnicodeStrToAsciiStr (
IN CONST CHAR16 *Source,
OUT CHAR8 *Destination
);
/**
Allocate new memory and then copy the Unicode string Source to Destination.
@param Dest Location to copy string
@param Src String to copy
**/
VOID
NewStringCpy (
IN OUT CHAR16 **Dest,
IN CHAR16 *Src
);
/**
Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
This function returns a value of type UINT64 by interpreting the contents
of the Unicode string specified by String as a hexadecimal number.
The format of the input Unicode string String is
[spaces][zeros][x][hexadecimal digits].
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
If "x" appears in the input string, it must be prefixed with at least one 0.
The function will ignore the pad space, which includes spaces or tab characters,
before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
[hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
first valid hexadecimal digit. Then, the function stops at the first character that is
a not a valid hexadecimal character or NULL, whichever one comes first.
If String is NULL, then ASSERT().
If String is not aligned in a 16-bit boundary, then ASSERT().
If String has only pad spaces, then zero is returned.
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
then zero is returned.
If the number represented by String overflows according to the range defined by
UINT64, then ASSERT().
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
then ASSERT().
@param String A pointer to a Null-terminated Unicode string.
@retval Value translated from String.
**/
UINT64
FceStrHexToUint64 (
IN CONST CHAR16 *String
);
CHAR16
ToUpper (
CHAR16 a
);
CHAR16
ToLower (
CHAR16 a
);
/**
Performs a case-insensitive comparison between a Null-terminated
Unicode pattern string and a Null-terminated Unicode string.
@param String - A pointer to a Null-terminated Unicode string.
@param Pattern - A pointer to a Null-terminated Unicode pattern string.
@retval TRUE - Pattern was found in String.
@retval FALSE - Pattern was not found in String.
**/
BOOLEAN
MetaiMatch (
IN CHAR16 *String,
IN CHAR16 *Pattern
);
/**
Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and
generates a 64-bit unsigned result.
This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit
unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
bit unsigned result is returned.
@param Multiplicand A 64-bit unsigned value.
@param Multiplier A 32-bit unsigned value.
@return Multiplicand * Multiplier.
**/
UINT64
MultU64x32 (
IN UINT64 Multiplicand,
IN UINT32 Multiplier
);
/**
Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
a 64-bit unsigned result.
This function divides the 64-bit unsigned value Dividend by the 32-bit
unsigned value Divisor and generates a 64-bit unsigned quotient. This
function returns the 64-bit unsigned quotient.
If Divisor is 0, then ASSERT().
@param Dividend A 64-bit unsigned value.
@param Divisor A 32-bit unsigned value.
@return Dividend / Divisor
**/
UINT64
DivU64x32 (
IN UINT64 Dividend,
IN UINT32 Divisor
);
/**
Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled
with zeros. The shifted value is returned.
This function shifts the 64-bit value Operand to the left by Count bits. The
low Count bits are set to zero. The shifted value is returned.
If Count is greater than 63, then ASSERT().
@param Operand The 64-bit operand to shift left.
@param Count The number of bits to shift left.
@return Operand << Count.
**/
UINT64
LShiftU64 (
IN UINT64 Operand,
IN UINTN Count
);
/**
Shifts a 64-bit integer right between 0 and 63 bits. This high bits are
filled with zeros. The shifted value is returned.
This function shifts the 64-bit value Operand to the right by Count bits. The
high Count bits are set to zero. The shifted value is returned.
If Count is greater than 63, then ASSERT().
@param Operand The 64-bit operand to shift right.
@param Count The number of bits to shift right.
@return Operand >> Count.
**/
UINT64
RShiftU64 (
IN UINT64 Operand,
IN UINTN Count
);
/**
Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
a 64-bit unsigned result and an optional 32-bit unsigned remainder.
This function divides the 64-bit unsigned value Dividend by the 32-bit
unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
This function returns the 64-bit unsigned quotient.
If Divisor is 0, then ASSERT().
@param Dividend A 64-bit unsigned value.
@param Divisor A 32-bit unsigned value.
@param Remainder A pointer to a 32-bit unsigned value. This parameter is
optional and may be NULL.
@return Dividend / Divisor
**/
UINT64
DivU64x32Remainder (
IN UINT64 Dividend,
IN UINT32 Divisor,
OUT UINT32 *Remainder
);
/**
Copies a buffer to an allocated buffer.
Allocates the number bytes specified by AllocationSize, copies allocationSize bytes
from Buffer to the newly allocated buffer, and returns a pointer to the allocated
buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
is not enough memory remaining to satisfy the request, then NULL is returned.
If Buffer is NULL, then ASSERT().
@param AllocationSize The number of bytes to allocate and zero.
@param Buffer The buffer to copy to the allocated buffer.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
FceAllocateCopyPool (
IN UINTN AllocationSize,
IN CONST VOID *Buffer
);
/**
Initializes the head node of a doubly-linked list, and returns the pointer to
the head node of the doubly-linked list.
Initializes the forward and backward links of a new linked list. After
initializing a linked list with this function, the other linked list
functions may be used to add and remove nodes from the linked list. It is up
to the caller of this function to allocate the memory for ListHead.
If ListHead is NULL, then ASSERT().
@param ListHead A pointer to the head node of a new doubly-linked list.
@return ListHead
**/
LIST_ENTRY *
InitializeListHead (
IN OUT LIST_ENTRY *ListHead
);
/**
Adds a node to the beginning of a doubly-linked list, and returns the pointer
to the head node of the doubly-linked list.
Adds the node Entry at the beginning of the doubly-linked list denoted by
ListHead, and returns ListHead.
If ListHead is NULL, then ASSERT().
If Entry is NULL, then ASSERT().
If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
of nodes in ListHead, including the ListHead node, is greater than or
equal to PcdMaximumLinkedListLength, then ASSERT().
@param ListHead A pointer to the head node of a doubly-linked list.
@param Entry A pointer to a node that is to be inserted at the beginning
of a doubly-linked list.
@return ListHead
**/
LIST_ENTRY *
InsertHeadList (
IN OUT LIST_ENTRY *ListHead,
IN OUT LIST_ENTRY *Entry
);
/**
Adds a node to the end of a doubly-linked list, and returns the pointer to
the head node of the doubly-linked list.
Adds the node Entry to the end of the doubly-linked list denoted by ListHead,
and returns ListHead.
If ListHead is NULL, then ASSERT().
If Entry is NULL, then ASSERT().
If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
of nodes in ListHead, including the ListHead node, is greater than or
equal to PcdMaximumLinkedListLength, then ASSERT().
@param ListHead A pointer to the head node of a doubly-linked list.
@param Entry A pointer to a node that is to be added at the end of the
doubly-linked list.
@return ListHead
**/
LIST_ENTRY *
InsertTailList (
IN OUT LIST_ENTRY *ListHead,
IN OUT LIST_ENTRY *Entry
);
/**
Retrieves the first node of a doubly-linked list.
Returns the first node of a doubly-linked list. List must have been
initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is empty, then List is returned.
If List is NULL, then ASSERT().
If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
PcdMaximumLinkedListLength, then ASSERT().
@param List A pointer to the head node of a doubly-linked list.
@return The first node of a doubly-linked list.
@retval NULL The list is empty.
**/
LIST_ENTRY *
GetFirstNode (
IN CONST LIST_ENTRY *List
);
/**
Retrieves the next node of a doubly-linked list.
Returns the node of a doubly-linked list that follows Node.
List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
or InitializeListHead(). If List is empty, then List is returned.
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and List contains more than
PcdMaximumLinkedListLenth nodes, then ASSERT().
If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
@param List A pointer to the head node of a doubly-linked list.
@param Node A pointer to a node in the doubly-linked list.
@return A pointer to the next node if one exists. Otherwise List is returned.
**/
LIST_ENTRY *
GetNextNode (
IN CONST LIST_ENTRY *List,
IN CONST LIST_ENTRY *Node
);
/**
Retrieves the previous node of a doubly-linked list.
Returns the node of a doubly-linked list that precedes Node.
List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
or InitializeListHead(). If List is empty, then List is returned.
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and List contains more than
PcdMaximumLinkedListLenth nodes, then ASSERT().
If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
@param List A pointer to the head node of a doubly-linked list.
@param Node A pointer to a node in the doubly-linked list.
@return A pointer to the previous node if one exists. Otherwise List is returned.
**/
LIST_ENTRY *
GetPreviousNode (
IN CONST LIST_ENTRY *List,
IN CONST LIST_ENTRY *Node
);
/**
Checks to see if a doubly-linked list is empty or not.
Checks to see if the doubly-linked list is empty. If the linked list contains
zero nodes, this function returns TRUE. Otherwise, it returns FALSE.
If ListHead is NULL, then ASSERT().
If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
PcdMaximumLinkedListLength, then ASSERT().
@param ListHead A pointer to the head node of a doubly-linked list.
@retval TRUE The linked list is empty.
@retval FALSE The linked list is not empty.
**/
BOOLEAN
IsListEmpty (
IN CONST LIST_ENTRY *ListHead
);
/**
Determines if a node in a doubly-linked list is the head node of a the same
doubly-linked list. This function is typically used to terminate a loop that
traverses all the nodes in a doubly-linked list starting with the head node.
Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the
nodes in the doubly-linked list specified by List. List must have been
initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),
then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
PcdMaximumLinkedListLength, then ASSERT().
If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not
equal to List, then ASSERT().
@param List A pointer to the head node of a doubly-linked list.
@param Node A pointer to a node in the doubly-linked list.
@retval TRUE Node is the head of the doubly-linked list pointed by List.
@retval FALSE Node is not the head of the doubly-linked list pointed by List.
**/
BOOLEAN
IsNull (
IN CONST LIST_ENTRY *List,
IN CONST LIST_ENTRY *Node
);
/**
Determines if a node the last node in a doubly-linked list.
Returns TRUE if Node is the last node in the doubly-linked list specified by
List. Otherwise, FALSE is returned. List must have been initialized with
INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
If List is NULL, then ASSERT().
If Node is NULL, then ASSERT().
If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
InitializeListHead(), then ASSERT().
If PcdMaximumLinkedListLenth is not zero, and the number of nodes
in List, including the List node, is greater than or equal to
PcdMaximumLinkedListLength, then ASSERT().
If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
@param List A pointer to the head node of a doubly-linked list.
@param Node A pointer to a node in the doubly-linked list.
@retval TRUE Node is the last node in the linked list.
@retval FALSE Node is not the last node in the linked list.
**/
BOOLEAN
IsNodeAtEnd (
IN CONST LIST_ENTRY *List,
IN CONST LIST_ENTRY *Node
);
/**
Removes a node from a doubly-linked list, and returns the node that follows
the removed node.
Removes the node Entry from a doubly-linked list. It is up to the caller of
this function to release the memory used by this node if that is required. On
exit, the node following Entry in the doubly-linked list is returned. If
Entry is the only node in the linked list, then the head node of the linked
list is returned.
If Entry is NULL, then ASSERT().
If Entry is the head node of an empty list, then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
linked list containing Entry, including the Entry node, is greater than
or equal to PcdMaximumLinkedListLength, then ASSERT().
@param Entry A pointer to a node in a linked list.
@return Entry.
**/
LIST_ENTRY *
RemoveEntryList (
IN CONST LIST_ENTRY *Entry
);
#endif

File diff suppressed because it is too large Load Diff

6449
BaseTools/Source/C/FCE/Fce.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,447 @@
/** @file
FCE is a tool which enables developers to retrieve and change HII configuration ("Setup")
data in Firmware Device files (".fd" files).
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _FCE_H_
#define _FCE_H_ 1
//#define NDEBUG
#include "Common.h"
#include "IfrParse.h"
#include "VariableCommon.h"
#include "BinaryParse.h"
#include "BinaryCreate.h"
///
/// Utility global variables
///
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 34
#define UTILITY_NAME "FCE"
#define SUCCESS 0
#define FAIL 1
#define VR_FAIL 2
#define MAX_INPUT_ALLOCATE_SIZE 256
///
/// The type of file input and operations
///
typedef enum {
INFD,
OUTFD,
OUTTXT,
SETUPTXT
} FILETYPE;
typedef enum {
NONE,
READ,
UPDATE,
UPDATE_REMOVE,
UPDATE_IGNORE,
VERIFY,
UPDATEQ
} OPERATION_TYPE;
typedef struct _GUID_SEC_TOOL_ENTRY {
EFI_GUID Guid;
CHAR8* Name;
CHAR8* Path;
struct _GUID_SEC_TOOL_ENTRY *Next;
} GUID_SEC_TOOL_ENTRY;
///
/// The tag for use in identifying UNICODE files.
/// If the file is UNICODE, the first 16 bits of the file will equal this value.
///
enum {
BigUnicodeFileTag = 0xFEFF,
LittleUnicodeFileTag = 0xFFFE
};
typedef enum {
ASCII,
BIG_UCS2,
LITTLE_UCS2
} FILE_TYPE;
/**
Exchange the data between Efi variable and the data of VarList when the
variable use the authenticated variable header
If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
update the data from varlist to efi variable.
@param VarToList The flag to control the direction of exchange.
@param StorageListHead Decide which variale list be updated
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
@retval EFI_INVALID_PARAMETER Invalid variable name.
**/
EFI_STATUS
SynAuthEfiVariable (
IN BOOLEAN VarToList,
IN LIST_ENTRY *StorageListHead
);
/**
Remove the variable from Efi variable
Found the variable with the same name in StorageListHead and remove it.
@param StorageListHead Decide which variale list be removed.
@retval EFI_SUCCESS Remove the variables successfully.
**/
EFI_STATUS
RemoveAuthEfiVariable (
IN LIST_ENTRY *StorageListHead
);
/**
Exchange the data between Efi variable and the data of VarList when the
variable use the time stamp authenticated variable header
If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
update the data from varlist to efi variable.
@param VarToList The flag to control the direction of exchange.
@param StorageListHead Decide which variale list be updated
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
@retval EFI_INVALID_PARAMETER Invalid variable name.
**/
EFI_STATUS
SynAuthEfiVariableBasedTime (
IN BOOLEAN VarToList,
IN LIST_ENTRY *StorageListHead
);
/**
Remove the variable from Efi variable
Found the variable with the same name in StorageListHead and remove it.
@param StorageListHead Decide which variale list be removed.
@retval EFI_SUCCESS Remove the variables successfully.
**/
EFI_STATUS
RemoveAuthEfiVariableBasedTime (
IN LIST_ENTRY *StorageListHead
);
/**
Exchange the data between Efi variable and the data of VarList when the
variable use the authenticated variable header
If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
update the data from varlist to efi variable.
@param VarToList The flag to control the direction of exchange.
@param StorageListHead Decide which variale list be updated
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
**/
EFI_STATUS
SynEfiVariable (
IN BOOLEAN VarToList,
IN LIST_ENTRY *StorageListHead
);
/**
Remove the variable from Efi variable
Found the variable with the same name in StorageListHead and remove it.
@param StorageListHead Decide which variale list be removed.
@retval EFI_SUCCESS Remove the variables successfully.
**/
EFI_STATUS
RemoveNormalEfiVariable (
IN LIST_ENTRY *StorageListHead
);
/**
Read all defaultId and platformId from binary.
@param Binary The pointer to the bianry
@param Storage The pointer to the Storage
**/
VOID
ReadDefaultAndPlatformIdFromBfv (
IN UINT8 *Binary,
IN FORMSET_STORAGE *Storage
);
/**
Store all defaultId and platformId to binary.
@param Binary The pointer to the bianry
@param Storage The pointer to the Storage
@retval Length Return the length of the header
**/
UINT32
WriteDefaultAndPlatformId (
IN UINT8 *Binary,
IN FORMSET_STORAGE *Storage
);
/**
Store all defaultId and platformId to binary.
@param Binary The pointer to the bianry
@param Storage The pointer to the Storage
@retval Length Return the length of the header
**/
UINT32
WriteNvStoreDefaultAndPlatformId (
IN UINT8 *Binary,
IN FORMSET_STORAGE *Storage
);
/**
Copy variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyVariableToBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
);
/**
Copy variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyVariableToNvStoreBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
);
/**
Read variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadNvStoreVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
);
/**
Read variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
);
/**
Check whether exists the valid normal variables in NvStorage or not.
@retval TRUE If existed, return TRUE.
@retval FALSE Others
**/
BOOLEAN
ExistNormalEfiVarOrNot (
IN LIST_ENTRY *StorageListHead
);
/**
Fix the size of variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
);
/**
Fix the size of variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixNvStoreVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
);
/**
Copy time-based authenticated variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyTimeBasedVariableToBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
);
/**
Read time-based authenticated variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadTimeBasedVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
);
/**
Check whether exists the valid time-based variables in NvStorage or not.
@retval TRUE If existed, return TRUE.
@retval FALSE Others
**/
BOOLEAN
ExistTimeBasedEfiVarOrNot (
IN LIST_ENTRY *StorageListHead
);
/**
Fix the size of time-based variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixBasedTimeVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
);
/**
Copy Monotonic-Based authenticated variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyMonotonicBasedVariableToBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
);
/**
Read Monotonic-based authenticated variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadMonotonicBasedVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
);
/**
Check whether exists the valid MonotonicBased variables in NvStorage or not.
@retval TRUE If existed, return TRUE.
@retval FALSE Others
**/
BOOLEAN
ExistMonotonicBasedEfiVarOrNot (
IN LIST_ENTRY *StorageListHead
);
/**
Fix the size of montonic variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixMontonicVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
);
/**
FCE application entry point
@param argc The number of input parameters.
@param *argv[] The array pointer to the parameters.
@retval 0 The application exited normally.
@retval 1 An error occurred.
@retval 2 An error about check occurred.
**/
int
main (
int argc,
char *argv[]
);
#endif

View File

@ -0,0 +1,55 @@
## @file GNUmakefile
#
# GNU makefile for 'FCE' module build.
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
ifndef ARCH
#
# If ARCH is not defined, then we use 'uname -m' to attempt
# try to figure out the appropriate ARCH.
#
uname_m = $(shell uname -m)
$(info Attempting to detect ARCH from 'uname -m': $(uname_m))
ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
ARCH=X64
endif
ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
ARCH=IA32
endif
ifneq (,$(findstring aarch64,$(uname_m)))
ARCH=AARCH64
endif
ifneq (,$(findstring arm,$(uname_m)))
ARCH=ARM
endif
ifndef ARCH
$(info Could not detected ARCH from uname results)
$(error ARCH is not defined!)
endif
$(info Detected ARCH of $(ARCH) using uname.)
endif
export ARCH
export HOST_ARCH=$(ARCH)
MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
APPNAME = FCE
OBJECTS = Fce.o Variable.o TimeBasedVariable.o MonotonicBasedVariable.o IfrParse.o Common.o BinaryParse.o BinaryCreate.o Expression.o
include $(MAKEROOT)/Makefiles/app.makefile
LIBS = -lCommon -lm

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,789 @@
/** @file
Parser for IFR binary encoding.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _IFR_PARSE_H_
#define _IFR_PARSE_H_
#include "Common.h"
#include <Common/UefiInternalFormRepresentation.h>
#include <Common/MdeModuleHii.h>
//
// Scope for Browser action. It may be Form, FormSet or System level.
//
typedef enum {
FormLevel,
FormSetLevel,
SystemLevel,
MaxLevel
} BROWSER_SETTING_SCOPE;
///
///Old EFI_IFR_VARSTORE_EFI structure to complible with UEFI 2.3
///
typedef struct _EFI_IFR_VARSTORE_EFI_OLD {
EFI_IFR_OP_HEADER Header;
EFI_VARSTORE_ID VarStoreId;
EFI_GUID Guid;
UINT32 Attributes;
} EFI_IFR_VARSTORE_EFI_OLD;
///
/// The languages used in HII DB
///
typedef enum {
UQI,
EN_US,
ENG
} LANGUAGE;
///
/// Define the structure for the parameters of Uqi and Uqi List
///
typedef struct _FORM_BROWSER_STATEMENT FORM_BROWSER_STATEMENT;
typedef enum {
ONE_OF,
NUMERIC,
CHECKBOX,
STRING,
ORDERED_LIST
} QUEST_TYPE;
typedef struct {
UINT16 *DefaultId;
UINT64 *PlatformId;
UINT32 IdNum;
UINT32 HexNum;
QUEST_TYPE Type;
CHAR16 *Data;
UINT8 *Value;
UINT8 *DiffValue;
UINT32 ScriptsLine;
FORM_BROWSER_STATEMENT *Question;
} UQI_HEADER;
typedef struct _UQI_PARAM_LIST {
struct _UQI_PARAM_LIST *Next;
UQI_HEADER Header;
BOOLEAN ParseOrNot;
BOOLEAN SameOrNot;
BOOLEAN ErrorOrNot;
CHAR8 *Error;
} UQI_PARAM_LIST;
//
// Incremental size of stack for expression
//
#define EXPRESSION_STACK_SIZE_INCREMENT 0x100
//
// IFR relative definition
//
#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0
#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1
#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2
#define EFI_HII_EXPRESSION_SUPPRESS_IF 3
#define EFI_HII_EXPRESSION_DISABLE_IF 4
#define EFI_HII_EXPRESSION_VALUE 5
#define EFI_HII_EXPRESSION_RULE 6
#define EFI_HII_EXPRESSION_READ 7
#define EFI_HII_EXPRESSION_WRITE 8
#define EFI_HII_EXPRESSION_WARNING_IF 9
#define EFI_HII_VARSTORE_BUFFER 0
#define EFI_HII_VARSTORE_NAME_VALUE 1
#define EFI_HII_VARSTORE_EFI_VARIABLE 2
#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3
#define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1
typedef struct {
//
// HII Data Type
//
UINT8 Type;
//
// Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE_STRING
//
UINT8 *Buffer;
UINT16 BufferLen;
EFI_IFR_TYPE_VALUE Value;
} EFI_HII_VALUE;
#define NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
CHAR16 *Name;
CHAR16 *Value;
CHAR16 *EditValue;
} NAME_VALUE_NODE;
#define NAME_VALUE_NODE_FROM_LINK(a) CR (a, NAME_VALUE_NODE, Link, NAME_VALUE_NODE_SIGNATURE)
#define FORMSET_STORAGE_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'G')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 DefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT64 PlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT32 DefaultPlatformIdNum;
UINT32 FormSetOrder;
BOOLEAN NewEfiVarstore; //EfiVarStore for UEFI 2.31 or not
BOOLEAN Skip; //Flag for sorting out the variables
UINT8 Type; // Storage type
UINT16 VarStoreId;
EFI_GUID Guid;
CHAR16 *Name; // For EFI_IFR_VARSTORE
UINT16 Size;
UINT8 *Buffer;
LIST_ENTRY NameValueListHead; // List of NAME_VALUE_NODE
UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute
} FORMSET_STORAGE;
#define FORMSET_STORAGE_FROM_LINK(a) CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)
typedef union {
EFI_STRING_ID VarName;
UINT16 VarOffset;
} VAR_STORE_INFO;
#define EXPRESSION_OPCODE_SIGNATURE SIGNATURE_32 ('E', 'X', 'O', 'P')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Operand;
UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND
UINT8 Flags; // For EFI_IFR_SPAN
UINT8 RuleId; // For EFI_IFR_RULE_REF
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
EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_ID, EFI_IFR_EQ_ID_VAL_LIST, EFI_IFR_QUESTION_REF1
EFI_QUESTION_ID QuestionId2;
UINT16 ListLength; // For EFI_IFR_EQ_ID_VAL_LIST
UINT16 *ValueList;
EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_2, EFI_IFR_QUESTION_REF3_3
EFI_GUID Guid;
FORMSET_STORAGE *VarStorage; // For EFI_IFR_SET, EFI_IFR_GET
VAR_STORE_INFO VarStoreInfo;// For EFI_IFR_SET, EFI_IFR_GET
UINT8 ValueType; // For EFI_IFR_SET, EFI_IFR_GET
UINT8 ValueWidth; // For EFI_IFR_SET, EFI_IFR_GET
CHAR16 *ValueName; // For EFI_IFR_SET, EFI_IFR_GET
LIST_ENTRY MapExpressionList; // nested expressions inside of Map opcode.
} EXPRESSION_OPCODE;
#define EXPRESSION_OPCODE_FROM_LINK(a) CR (a, EXPRESSION_OPCODE, Link, EXPRESSION_OPCODE_SIGNATURE)
#define FORM_EXPRESSION_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'P')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Type; // Type for this expression
UINT8 RuleId; // For EFI_IFR_RULE only
EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR_INCONSISTENT_IF only
EFI_HII_VALUE Result; // Expression evaluation result
UINT8 TimeOut; // For EFI_IFR_WARNING_IF
LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE)
} FORM_EXPRESSION;
#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)
#define QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 DefaultId;
EFI_HII_VALUE Value; // Default value
FORM_EXPRESSION *ValueExpression; // Not-NULL indicates default value is provided by EFI_IFR_VALUE
} QUESTION_DEFAULT;
#define QUESTION_DEFAULT_FROM_LINK(a) CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)
#define QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
EFI_STRING_ID Text;
UINT8 Flags;
EFI_HII_VALUE Value;
FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf
} QUESTION_OPTION;
#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)
#define FORM_BROWSER_STATEMENT_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'A')
struct _FORM_BROWSER_STATEMENT {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Operand; // The operand (first byte) of this Statement or Question
UQI_HEADER Uqi;
UINT32 FormSetOrder;
EFI_GUID Guid;
UINT8 Type; // Storage type
BOOLEAN NewEfiVarstore; //EfiVarStore for UEFI 2.31 or not
UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute
BOOLEAN QuestionReferToBitField;// Whether the question is stored in a bit field.
//
// Statement Header
//
EFI_STRING_ID Prompt;
EFI_STRING_ID Help;
EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT
//
// Question Header
//
EFI_QUESTION_ID QuestionId; // The value of zero is reserved
EFI_VARSTORE_ID VarStoreId; // A value of zero indicates no variable storage
FORMSET_STORAGE *Storage;
VAR_STORE_INFO VarStoreInfo;
UINT16 StorageWidth;
UINT16 BitStorageWidth;
UINT16 BitVarOffset;
UINT8 QuestionFlags;
CHAR16 *VariableName; // Name/Value or EFI Variable name
EFI_HII_VALUE HiiValue; // Edit copy for checkbox, numberic, oneof
UINT8 *BufferValue; // Edit copy for string, password, orderedlist
UINT8 ValueType; // Data type for orderedlist value array
//
// OpCode specific members
//
UINT8 Flags; // for EFI_IFR_CHECKBOX, EFI_IFR_DATE, EFI_IFR_NUMERIC, EFI_IFR_ONE_OF,
// EFI_IFR_ORDERED_LIST, EFI_IFR_STRING,EFI_IFR_SUBTITLE,EFI_IFR_TIME, EFI_IFR_BANNER
UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST
UINT16 BannerLineNumber; // for EFI_IFR_BANNER, 1-based line number
UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC, it's Min/Max value
UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD, it's Min/Max length
UINT64 Step;
EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID
//
// Get from IFR parsing
//
FORM_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly
LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT list (QUESTION_DEFAULT), provide default values
LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)
EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE
UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh
BOOLEAN InSubtitle; // nesting inside of EFI_IFR_SUBTITLE
LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)
LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)
LIST_ENTRY WarningListHead; // nested warning expression list (FORM_EXPRESSION)
FORM_EXPRESSION *GrayOutExpression; // nesting inside of GrayOutIf
FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf
FORM_EXPRESSION *DisableExpression; // nesting inside of DisableIf
FORM_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, provide this question value by read expression.
FORM_EXPRESSION *WriteExpression; // nested EFI_IFR_WRITE, evaluate write expression after this question value is set.
};
#define FORM_BROWSER_STATEMENT_FROM_LINK(a) CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)
#define FORM_BROWSER_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M')
#define STANDARD_MAP_FORM_TYPE 0x01
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 FormId; // FormId of normal form or formmap form.
EFI_STRING_ID FormTitle; // FormTile of normal form, or FormMapMethod title of formmap form.
UINT16 FormType; // Specific form type for the different form.
BOOLEAN ModalForm; // Whether this is a modal form.
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf
} FORM_BROWSER_FORM;
#define FORM_BROWSER_FORM_FROM_LINK(a) CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)
#define FORMSET_DEFAULTSTORE_SIGNATURE SIGNATURE_32 ('F', 'D', 'F', 'S')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 DefaultId;
EFI_STRING_ID DefaultName;
} FORMSET_DEFAULTSTORE;
#define STRING_NUMBER 100
typedef struct {
EFI_STRING_ID StringId;
CHAR16 *String;
} STRING_INFO;
typedef struct {
EFI_STRING_ID CachedIdNum;
EFI_STRING_ID MaxIdNum;
STRING_INFO *StringInfoList;
} FORMSET_STRING_LIST;
#define FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)
#define FORM_BROWSER_FORMSET_SIGNATURE SIGNATURE_32 ('F', 'B', 'F', 'S')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT32 FormSetOrder;
UINTN IfrBinaryLength;
UINT8 *IfrBinaryData;
UINT8 *UnicodeBinary;
EFI_GUID Guid;
EFI_STRING_ID FormSetTitle;
EFI_STRING_ID Help;
UINT8 NumberOfClassGuid;
EFI_GUID ClassGuid[3]; // Up to three ClassGuid
UINT16 Class; // Tiano extended Class code
UINT16 SubClass; // Tiano extended Subclass code
FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions
EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode
LIST_ENTRY *StorageListHead; // Storage list (FORMSET_STORAGE)
LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)
LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
FORMSET_STRING_LIST EnUsStringList; // Cache EN_US English list
FORMSET_STRING_LIST UqiStringList; // Cache EN_US English list
} FORM_BROWSER_FORMSET;
#define FORM_BROWSER_FORMSET_FROM_LINK(a) CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)
///
/// Structure for multi-platform support
///
typedef struct {
UINT16 DefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT16 DefaultIdNum;
UINT64 PlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT16 PlatformIdNum;
UINT16 KeyDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT64 KeyPlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];
UINT16 KeyIdNum;
FORM_BROWSER_STATEMENT PlatformIdQuestion;
FORM_BROWSER_STATEMENT *Question;
UINT16 PlatformIdWidth;
UQI_HEADER Uqi;
BOOLEAN MultiPlatformOrNot;
BOOLEAN ExistStorageFfsInBfv;
BOOLEAN SizeOptimized;
BOOLEAN SizeOptimizedParam;
} MULTI_PLATFORM_PARAMETERS;
/**
Search the variable list according to the variable Guid and name, and return the pointer
of that Node.
@param HiiObjList The pointer to the Question
@param VarName The EFI variable name need to be updated to VarList
@param Offset The offset of the variable
@param StorageListHead The pointer to the LIST_ENTRY of Storage
@param Vaue The value in that value offset of the variable
@param VarList The dual pointer of Varlist
@return EFI_SUCCESS
**/
EFI_STATUS
SearchVarStorage (
IN FORM_BROWSER_STATEMENT *Question,
IN CHAR16* VarName,
IN UINT32 Offset,
IN LIST_ENTRY *StorageListHead,
IN OUT CHAR8 **Value,
IN OUT FORMSET_STORAGE **VarList
);
/**
Get the string based on the StringId and HII Package List Handle.
@param Token The String's ID.
@param HiiHandle The package list in the HII database to search for
the specified string.
@return The output string.
**/
CHAR16 *
GetToken (
IN EFI_STRING_ID Token,
IN UINT8 *UniPackge
);
/**
Free resources allocated for all Storage in an LIST_ENTRY.
@param FormSet Pointer of the FormSet
**/
VOID
DestroyAllStorage (
IN LIST_ENTRY *StorageEntryListHead
);
/**
Free resources allocated for a FormSet.
@param FormSet Pointer of the FormSet
**/
VOID
DestroyFormSet (
IN FORM_BROWSER_FORMSET *FormSet
);
/**
Free resources allocated for all FormSet in an LIST_ENTRY.
@param FormSet Pointer of the FormSet
**/
VOID
DestroyAllFormSet (
IN LIST_ENTRY *FormSetEntryListHead
);
/**
Parse opcodes in the formset IFR binary.
@param FormSet Pointer of the FormSet data structure.
@retval EFI_SUCCESS Opcode parse success.
@retval Other Opcode parse fail.
**/
EFI_STATUS
ParseOpCodes (
IN FORM_BROWSER_FORMSET *FormSet
);
/**
Set the value to the variable of platformId question.
@param PlatformId The form set.
@retval EFI_SUCCESS Set successfully.
**/
EFI_STATUS
AssignThePlatformId (
IN UINT64 PlatformId
);
/**
Reset Questions to their default value in a Form, Formset or System.
@param FormSet FormSet data structure.
@param Form Form data structure.
@param DefaultId The default Id
@param PlatformId The platform Id
@param SettingScope Setting Scope for Default action.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
ExtractDefault (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
IN UINT16 DefaultId,
IN UINT64 PlatformId,
IN BROWSER_SETTING_SCOPE SettingScope
);
/**
Reset stack pointer to begin of the stack.
**/
VOID
ResetCurrentExpressionStack (
VOID
);
/**
Push current expression onto the Stack
@param Pointer Pointer to current expression.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
**/
EFI_STATUS
PushCurrentExpression (
IN VOID *Pointer
);
/**
Pop current expression from the Stack
@param Pointer Pointer to current expression to be pop.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
**/
EFI_STATUS
PopCurrentExpression (
OUT VOID **Pointer
);
/**
Reset stack pointer to begin of the stack.
**/
VOID
ResetMapExpressionListStack (
VOID
);
/**
Push the list of map expression onto the Stack
@param Pointer Pointer to the list of map expression to be pushed.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
**/
EFI_STATUS
PushMapExpressionList (
IN VOID *Pointer
);
/**
Pop the list of map expression from the Stack
@param Pointer Pointer to the list of map expression to be pop.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
**/
EFI_STATUS
PopMapExpressionList (
OUT VOID **Pointer
);
/**
Reset stack pointer to begin of the stack.
**/
VOID
ResetScopeStack (
VOID
);
/**
Push an Operand onto the Stack
@param Operand Operand to push.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PushScope (
IN UINT8 Operand
);
/**
Pop an Operand from the Stack
@param Operand Operand to pop.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PopScope (
OUT UINT8 *Operand
);
/**
Zero extend integer/boolean/date/time to UINT64 for comparing.
@param Value HII Value to be converted.
**/
VOID
ExtendValueToU64 (
IN EFI_HII_VALUE *Value
);
/**
Compare two Hii value.
@param Value1 Expression value to compare on left-hand.
@param Value2 Expression value to compare on right-hand.
@retval EFI_INVALID_PARAMETER Could not perform compare on two values.
@retval 0 Two operators equal.
@return Positive value if Value1 is greater than Value2.
@retval Negative value if Value1 is less than Value2.
**/
INTN
CompareHiiValue (
IN EFI_HII_VALUE *Value1,
IN EFI_HII_VALUE *Value2,
IN FORM_BROWSER_FORMSET *FormSet
);
/**
Evaluate the result of a HII expression.
If Expression is NULL, then ASSERT.
@param FormSet FormSet associated with this expression.
@param Form Form associated with this expression.
@param Expression Expression to be evaluated.
@param ConstantExpression The pointer to the flag of constant expression. If constant, will return TRUE.
@retval EFI_SUCCESS The expression evaluated successfuly
@retval EFI_NOT_FOUND The Question which referenced by a QuestionId
could not be found.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
@retval EFI_ACCESS_DENIED The pop operation underflowed the stack
@retval EFI_INVALID_PARAMETER Syntax error with the Expression
**/
EFI_STATUS
EvaluateExpression (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
IN OUT FORM_EXPRESSION *Expression,
IN OUT BOOLEAN *ConstantExpression
);
/**
Compare two Uqi parameters
@param UqiParm1 The pointer to the first Uqi parameter.
@param UqiParm2 The pointer to the second Uqi parameter.
@retval TRUE If these two Uqi parameters are the same, return TRUE;
@return FALSE Otherwise, return FALSE;
**/
BOOLEAN
CompareUqiHeader (
IN CONST UQI_HEADER *UqiParm1,
IN CONST UQI_HEADER *UqiParm2
);
/**
Print all ONE_OF ORDER_LIST NUMERIC STRING and CHECKBOX in all fromsets.
@param Formset The pointer to the entry of the fromset list
@param Formset The pointer to the entry of the storage list
@retval EFI_SUCCESS It was complete successfully
@return EFI_ABORTED An error occurred
**/
EFI_STATUS
PrintInfoInAllFormset (
IN LIST_ENTRY *FormSetEntryListHead,
IN LIST_ENTRY *StorageEntryListHead
);
/**
Get the question value with bit field from the buffer.
@param Question The question refer to bit field.
@param Buffer The buffer which the question value get from.
@param Value Retun the value.
**/
VOID
GetBitsQuestionValue(
IN FORM_BROWSER_STATEMENT *Question,
IN UINT8 *Buffer,
OUT UINT32 *Value
);
/**
Set the question value with bit field to the buffer.
@param Question The question refer to bit field.
@param Buffer The buffer which the question value set to.
@param Value The value need to set.
**/
VOID
SetBitsQuestionValue (
IN FORM_BROWSER_STATEMENT *Question,
IN UINT8 *Buffer,
IN UINT32 Value
);
#endif

View File

@ -0,0 +1,19 @@
## @file
#
# Windows makefile for 'FCE' module build.
#
#Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
#SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.common
APPNAME = FCE
LIBS = $(LIB_PATH)\Common.lib
OBJECTS = Fce.obj Variable.obj TimeBasedVariable.obj MonotonicBasedVariable.obj IfrParse.obj Common.obj BinaryParse.obj BinaryCreate.obj Expression.obj
!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.app

View File

@ -0,0 +1,874 @@
/** @file
Read and edit the authenticated variables.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Fce.h"
#include "MonotonicBasedVariable.h"
extern LIST_ENTRY mAllVarListEntry;
extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;
extern G_EFI_FD_INFO gEfiFdInfo;
EFI_GUID gEfiAuthenticatedVariableGuid = EFI_AUTHENTICATED_VARIABLE_GUID;
/**
Gets the pointer to the first variable header in given variable store area.
@param VarStoreHeader Pointer to the Variable Store Header.
@return Pointer to the first variable header.
**/
static
VARIABLE_HEADER *
GetStartPointer (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
{
//
// The end of variable store.
//
return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
}
/**
Gets the pointer to the end of the variable storage area.
This function gets pointer to the end of the variable storage
area, according to the input variable store header.
@param VarStoreHeader Pointer to the Variable Store Header.
@return Pointer to the end of the variable storage area.
**/
static
VARIABLE_HEADER *
GetEndPointer (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
{
//
// The end of variable store
//
return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
}
/**
This code checks if variable header is valid or not.
@param Variable Pointer to the Variable Header.
@retval TRUE Variable header is valid.
@retval FALSE Variable header is not valid.
**/
static
BOOLEAN
IsValidVariableHeader (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable == NULL) || (Variable->StartId != VARIABLE_DATA)) {
return FALSE;
}
return TRUE;
}
/**
This code gets the size of name of variable.
@param Variable Pointer to the Variable Header.
@return UINTN Size of variable in bytes.
**/
static
UINTN
NameSizeOfVariable (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable->State == (UINT8) (-1)) ||
(Variable->DataSize == (UINT32) (-1)) ||
(Variable->NameSize == (UINT32) (-1)) ||
(Variable->Attributes == (UINT32) (-1))
) {
return 0;
}
return (UINTN) Variable->NameSize;
}
/**
This code gets the size of variable data.
@param Variable Pointer to the Variable Header.
@return Size of variable in bytes.
**/
static
UINTN
DataSizeOfVariable (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable->State == (UINT8) (-1)) ||
(Variable->DataSize == (UINT32) (-1)) ||
(Variable->NameSize == (UINT32) (-1)) ||
(Variable->Attributes == (UINT32) (-1))
) {
return 0;
}
return (UINTN) Variable->DataSize;
}
/**
This code gets the pointer to the variable name.
@param Variable Pointer to the Variable Header.
@return Pointer to Variable Name which is Unicode encoding.
**/
static
CHAR16 *
GetVariableNamePtr (
IN VARIABLE_HEADER *Variable
)
{
return (CHAR16 *) (Variable + 1);
}
/**
This code gets the pointer to the variable data.
@param Variable Pointer to the Variable Header.
@return Pointer to Variable Data.
**/
static
UINT8 *
GetVariableDataPtr (
IN VARIABLE_HEADER *Variable
)
{
UINTN Value;
//
// Be careful about pad size for alignment.
//
Value = (UINTN) GetVariableNamePtr (Variable);
Value += NameSizeOfVariable (Variable);
Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
return (UINT8 *) Value;
}
/**
This code gets the pointer to the next variable header.
@param Variable Pointer to the Variable Header.
@return Pointer to next variable header.
**/
static
VARIABLE_HEADER *
GetNextVariablePtr (
IN VARIABLE_HEADER *Variable
)
{
UINTN Value;
if (!IsValidVariableHeader (Variable)) {
return NULL;
}
Value = (UINTN) GetVariableDataPtr (Variable);
Value += DataSizeOfVariable (Variable);
Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
//
// Be careful about pad size for alignment.
//
return (VARIABLE_HEADER *) HEADER_ALIGN (Value);
}
/**
Search and get a free space in the EFI variable zone
@param VariableStoreHeader The start of a EFI variable zone.
@param VarListSize The size of a variables needs to be allocated.
@param FreeBeginVar The dual pointer to the free NV space.
@retval EFI_SUCCESS Return the beginning of a free variable space.
@retval RETURN_BUFFER_TOO_SMALL Failed.
**/
static
EFI_STATUS
GetVariableVar (
IN VARIABLE_STORE_HEADER *VariableStoreHeader,
IN UINT32 VarListSize,
IN OUT CHAR8 **FreeBeginVar
)
{
BOOLEAN Flag;
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *EndOfVariable;
CHAR8 *BeginVar;
BeginVar = NULL;
Flag = FALSE;
Variable = NULL;
EndOfVariable = NULL;
*FreeBeginVar = NULL;
if (VariableStoreHeader == NULL) {
*FreeBeginVar = NULL;
return RETURN_INVALID_PARAMETER;
}
Variable = GetStartPointer (VariableStoreHeader);
EndOfVariable = GetEndPointer(VariableStoreHeader);
//
//Search the beginning of free NV
//
while (Variable != EndOfVariable) {
BeginVar = (CHAR8 *)Variable;
Variable = GetNextVariablePtr (Variable);
if (Variable == NULL) {
Flag = TRUE;
break;
}
}
//
// Check whether the free space is more than what we want
//
if ((CHAR8 *)BeginVar + VarListSize > (CHAR8 *)EndOfVariable) {
return RETURN_BUFFER_TOO_SMALL;
}
//
// If not find the available space, return NULL
//
if (!Flag) {
return RETURN_BUFFER_TOO_SMALL;
}
*FreeBeginVar = BeginVar;
return EFI_SUCCESS;
}
/**
Search whether the variable in VarList has existed in current NV.
Parse the FFS or Fd image, and find the valid variable pointer.
@param VariableStoreHeader The start of a EFI variable zone.
@param VarList The pointer to the VarList
@retval address If the variable existed in current NV, return address
@return NULL Otherwise, return NULL
**/
static
VARIABLE_HEADER *
FindVariableInNv (
IN VARIABLE_STORE_HEADER *VariableStoreHeader,
IN FORMSET_STORAGE *Storage
)
{
BOOLEAN Flag;
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *EndOfVariable;
CHAR16 *VariableName;
Flag = FALSE;
Variable = NULL;
EndOfVariable = NULL;
VariableName = NULL;
if ((VariableStoreHeader == NULL) || (Storage == NULL) || (Storage->Name == NULL)) {
return NULL;
}
Variable = GetStartPointer (VariableStoreHeader);
EndOfVariable = GetEndPointer(VariableStoreHeader);
//
// Parse and compare the variable in the NV space one by one
//
while ((Variable != EndOfVariable) && (Variable != NULL)) {
VariableName = (CHAR16 *)((CHAR8 *)Variable + sizeof (VARIABLE_HEADER));
if (!CompareGuid (&Variable->VendorGuid, &Storage->Guid) \
&& !FceStrCmp (Storage->Name, VariableName) \
&& (Variable->State == VAR_ADDED)) {
Flag = TRUE;
break;
}
Variable = GetNextVariablePtr (Variable);
}
if (!Flag) {
return NULL;
}
return Variable;
}
/**
Exchange the data between Efi variable and the data of VarList when the
variable use the authenticated variable header
If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
update the data from varlist to efi variable.
@param VarToList The flag to control the direction of exchange.
@param StorageListHead Decide which variale list be updated
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
@retval EFI_INVALID_PARAMETER Invalid variable name.
**/
EFI_STATUS
SynAuthEfiVariable (
IN BOOLEAN VarToList,
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
EFI_STATUS Status;
CHAR8 *NewAvailableAddr;
CHAR8 *DataBase;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VarNameSize;
Status = EFI_SUCCESS;
DataBase = NULL;
NewAvailableAddr = NULL;
VarNameSize = 0;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if (Storage->Buffer == NULL) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return EFI_INVALID_PARAMETER;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if (VarToList) {
//
//Copy the data from NV to the VarList.
//
if (VariableHeader != NULL) {
if (Storage->Buffer == NULL) {
Storage->Buffer = calloc (Storage->Size, sizeof (CHAR8));
ASSERT (Storage->Buffer != NULL);
}
//
// The variable in VarList is CHAR8, but in the EFI variable is CHAR16.
//
DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);
memcpy (
Storage->Buffer,
(VOID *) DataBase,
Storage->Size
);
}
} else {
//
//If existed, copy the List data to the variable in NV directly. If not found, create a new one.
//
VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);
//
//If this variable has existed in current FD, the data in VarList has
// been updated, and this variable is not authenticated type, then
// update it from VarList to the FD.
//
if ((VariableHeader != NULL) \
&& (Storage->Buffer != NULL)
) {
if (!(VariableHeader->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {
DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);
memcpy (
(VOID *) DataBase,
Storage->Buffer,
Storage->Size
);
} else {
printf ("Error. Not support to update authenticated variables.\n");
return EFI_INVALID_PARAMETER;
}
} else if ((VariableHeader == NULL) && (Storage->Buffer != NULL)){
//
//If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.
//
if (Storage->NewEfiVarstore
&& ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)
) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Try to get the available zone from the efi variables
//
Status = GetVariableVar (
VariableStoreHeader,
Storage->Size + sizeof (VARIABLE_HEADER),
&NewAvailableAddr
);
if (!EFI_ERROR (Status)) {
//
// Create the authenticated variable header
//
VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;
VariableHeader->StartId = VARIABLE_DATA;
VariableHeader->State = VAR_ADDED;
VariableHeader->Reserved = 0x0;
VariableHeader->MonotonicCount = 0x0;
VariableHeader->PubKeyIndex = 0x0;
if (Storage->NewEfiVarstore) {
VariableHeader->Attributes = Storage->Attributes;
} else {
VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
}
VariableHeader->NameSize = VarNameSize;
VariableHeader->DataSize = Storage->Size;
//
//Copy the Guid, variable name, and data in sequence.
//
memcpy (
(VOID *)&(VariableHeader->VendorGuid),
&(Storage->Guid),
sizeof (EFI_GUID)
);
NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Name,
VarNameSize
);
NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Buffer,
Storage->Size * sizeof (CHAR8)
);
} else {
printf ("Error. No available space in NV ram.\n");
return EFI_OUT_OF_RESOURCES;
}
}
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return Status;
}
/**
Remove the variable from Efi variable
Found the variable with the same name in StorageListHead and remove it.
@param StorageListHead Decide which variale list be removed.
@retval EFI_SUCCESS Remove the variables successfully.
**/
EFI_STATUS
RemoveAuthEfiVariable (
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if (Storage->Buffer == NULL) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return EFI_INVALID_PARAMETER;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if (VariableHeader != NULL) {
VariableHeader->State = VAR_DELETED;
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return EFI_SUCCESS;
}
/**
Check the store variable is Monotonic based authenticated or not
@param VarToList The pointer to the header of Variable Store.
@retval TRUE If authenticated, return TRUE.
@retval FALSE Otherwise, return FALSE.
**/
BOOLEAN
CheckMonotonicBasedVarStore (
IN VOID *VariableStoreHeader
)
{
if (!CompareGuid (
&gEfiAuthenticatedVariableGuid,
&((VARIABLE_STORE_HEADER *)VariableStoreHeader)->Signature)
) {
return TRUE;
} else {
return FALSE;
}
}
/**
Copy Monotonic-Based authenticated variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyMonotonicBasedVariableToBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
)
{
EFI_STATUS Status;
CHAR8 *NewAvailableAddr;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VarNameSize;
UINT32 HeaderLength;
Status = EFI_SUCCESS;
NewAvailableAddr = NULL;
VarNameSize = 0;
HeaderLength = 0;
VariableHeader = NULL;
VariableStoreHeader = NULL;
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return 0;
}
//
// If the first storage under one specified platformId and defaultId, create the variable header
//
if (Index == 0) {
HeaderLength = WriteDefaultAndPlatformId (StorageBeginning, Storage);
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength);
//
//Create the Variable Storage header
//
memcpy (&(VariableStoreHeader->Signature), &gEfiAuthenticatedVariableGuid, sizeof (EFI_GUID));
VariableStoreHeader->Format = 0x5A;
VariableStoreHeader->State = 0xFE;
//
//Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.
//
VariableStoreHeader->Size = gEfiFdInfo.FdSize;
}
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + *(UINT16 *)StorageBeginning);
Status = GetVariableVar (
VariableStoreHeader,
Storage->Size + sizeof (VARIABLE_HEADER),
&NewAvailableAddr
);
if (EFI_ERROR (Status)) {
return FAIL;
}
//
// Create the variable header
//
VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);
VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;
VariableHeader->StartId = VARIABLE_DATA;
VariableHeader->State = VAR_ADDED;
VariableHeader->Reserved = 0x0;
VariableHeader->MonotonicCount = 0x0;
VariableHeader->PubKeyIndex = 0x0;
if (Storage->NewEfiVarstore) {
VariableHeader->Attributes = Storage->Attributes;
} else {
VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
}
VariableHeader->NameSize = VarNameSize;
VariableHeader->DataSize = Storage->Size;
//
//Copy the Guid, variable name, and data in sequence.
//
memcpy (
(VOID *)&(VariableHeader->VendorGuid),
&(Storage->Guid),
sizeof (EFI_GUID)
);
NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Name,
VarNameSize
);
NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Buffer,
Storage->Size * sizeof (CHAR8)
);
//
// Return the length which is from the beginning of Binary
//
return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning) + Storage->Size);
}
/**
Read Monotonic-based authenticated variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadMonotonicBasedVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
)
{
VARIABLE_HEADER *EndOfVariable;
VARIABLE_HEADER *Variable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
FORMSET_STORAGE *Storage;
BOOLEAN ReadIdHeaderFlag;
UINT32 Length;
EFI_COMMON_SECTION_HEADER *SectionHeader;
UINT8 *DataBase;
static UINT16 PreDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];
static UINT64 PrePlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];
VariableStoreHeader = NULL;
Variable = NULL;
ReadIdHeaderFlag = TRUE;
Length = 0;
SectionHeader = (EFI_COMMON_SECTION_HEADER *)Binary;
DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + *(UINT16 *)DataBase);
EndOfVariable = GetEndPointer(VariableStoreHeader);
for (Variable = GetStartPointer (VariableStoreHeader);
Length < VariableStoreHeader->Size;
Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize
) {
//
// Create the storage
//
Storage = NULL;
Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));
if (Storage == NULL) {
printf ("Allocate memory failed.\n");
return FAIL;
}
//
// If access the first storage, read the platformId and defaultId
//
if (ReadIdHeaderFlag) {
ReadDefaultAndPlatformIdFromBfv (DataBase, Storage);
Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize;
ReadIdHeaderFlag = FALSE;
memcpy (PreDefaultId, Storage->DefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));
memcpy (PrePlatformId, Storage->PlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));
} else {
//
// Store the DefaultId and PlatformId collected from the header to Storage.
//
memcpy (Storage->DefaultId, PreDefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));
memcpy (Storage->PlatformId, PrePlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));
}
Storage->Attributes = Variable->Attributes;
Storage->Size = (UINT16)Variable->DataSize;
Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));
ASSERT (Storage->Name != NULL);
Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));
ASSERT (Storage->Buffer != NULL);
memcpy (
&(Storage->Guid),
&(Variable->VendorGuid),
sizeof (EFI_GUID)
);
memcpy (
Storage->Name,
(UINT8 *)Variable + sizeof (VARIABLE_HEADER),
Variable->NameSize
);
memcpy (
Storage->Buffer,
(UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),
Storage->Size * sizeof (CHAR8)
);
//
// Assigned the value for comparison in verify mode
//
Storage->Type = EFI_IFR_VARSTORE_EFI_OP;
Storage->NewEfiVarstore = TRUE;
InitializeListHead (&Storage->NameValueListHead);
InsertTailList(StorageListEntry, &Storage->Link);
//
// If the last variable, exit.
//
if (Variable == EndOfVariable) {
break;
}
Variable = GetNextVariablePtr (Variable);
assert (Variable != NULL);
}
//
// Return the length which is from the beginning of Binary
//
Length = FvBufExpand3ByteSize (SectionHeader->Size);
return Length;
}
/**
Check whether exists the valid MonotonicBased variables in NvStorage or not.
@retval TRUE If existed, return TRUE.
@retval FALSE Others
**/
BOOLEAN
ExistMonotonicBasedEfiVarOrNot (
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if ((Storage->Buffer == NULL)
|| (Storage->Name == NULL)
|| (FceStrLen(Storage->Name) == 0)
) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if ((VariableHeader != NULL)) {
return TRUE;
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return FALSE;
}
/**
Fix the size of montonic variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixMontonicVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
)
{
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + *(UINT16 *)BinaryBeginning);
VariableStoreHeader->Size = Length - *(UINT16 *)BinaryBeginning;
}

View File

@ -0,0 +1,162 @@
/** @file
The header of MonotonicBasedVariable.c.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __AUTHENTICATED_VARIABLE_FORMAT_H__
#define __AUTHENTICATED_VARIABLE_FORMAT_H__
#define EFI_AUTHENTICATED_VARIABLE_GUID \
{ 0x515fa686, 0xb06e, 0x4550, { 0x91, 0x12, 0x38, 0x2b, 0xf1, 0x6, 0x7b, 0xfb }}
extern EFI_GUID gEfiAuthenticatedVariableGuid;
///
/// Alignment of variable name and data, according to the architecture:
/// * For IA-32 and Intel(R) 64 architectures: 1
/// * For IA-64 architecture: 8
///
#if defined (MDE_CPU_IPF)
#define ALIGNMENT 8
#else
#define ALIGNMENT 1
#endif
///
/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
///
#if (ALIGNMENT == 1)
#define GET_PAD_SIZE(a) (0)
#else
#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
#endif
///
/// Alignment of Variable Data Header in Variable Store region
///
#define HEADER_ALIGNMENT 4
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
///
/// Status of Variable Store Region
///
typedef enum {
EfiRaw,
EfiValid,
EfiInvalid,
EfiUnknown
} VARIABLE_STORE_STATUS;
#pragma pack(1)
#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID
///
/// Variable Store Header Format and State
///
#define VARIABLE_STORE_FORMATTED 0x5a
#define VARIABLE_STORE_HEALTHY 0xfe
///
/// Variable Store region header
///
typedef struct {
///
/// Variable store region signature.
///
EFI_GUID Signature;
///
/// Size of entire variable store,
/// including size of variable store header but not including the size of FvHeader.
///
UINT32 Size;
///
/// Variable region format state.
///
UINT8 Format;
///
/// Variable region healthy state.
///
UINT8 State;
UINT16 Reserved;
UINT32 Reserved1;
} VARIABLE_STORE_HEADER;
///
/// Variable data start flag.
///
#define VARIABLE_DATA 0x55AA
///
/// Variable State flags
///
#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition
#define VAR_DELETED 0xfd ///< Variable is obsolete
#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid
#define VAR_ADDED 0x3f ///< Variable has been completely added
///
/// Single Variable Data Header Structure.
///
typedef struct {
///
/// Variable Data Start Flag.
///
UINT16 StartId;
///
/// Variable State defined above.
///
UINT8 State;
UINT8 Reserved;
///
/// Attributes of variable defined in UEFI spec
///
UINT32 Attributes;
///
/// Associated monotonic count value against replay attack.
///
UINT64 MonotonicCount;
///
/// Index of associated public key in database.
///
UINT32 PubKeyIndex;
///
/// Size of variable null-terminated Unicode string name.
///
UINT32 NameSize;
///
/// Size of the variable data without this header.
///
UINT32 DataSize;
///
/// A unique identifier for the vendor that produces and consumes this varaible.
///
EFI_GUID VendorGuid;
} VARIABLE_HEADER;
#pragma pack()
typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;
///
/// This structure contains the variable list that is put in EFI system table.
/// The variable driver collects all variables that were used at boot service time and produces this list.
/// This is an optional feature to dump all used variables in shell environment.
///
struct _VARIABLE_INFO_ENTRY {
VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.
EFI_GUID VendorGuid; ///< Guid of Variable.
CHAR16 *Name; ///< Name of Variable.
UINT32 Attributes; ///< Attributes of variable defined in UEFI spec.
UINT32 ReadCount; ///< Number of times to read this variable.
UINT32 WriteCount; ///< Number of times to write this variable.
UINT32 DeleteCount; ///< Number of times to delete this variable.
UINT32 CacheCount; ///< Number of times that cache hits this variable.
BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.
};
#endif // _EFI_VARIABLE_H_

View File

@ -0,0 +1,878 @@
/** @file
Read and edit the time-base authenticated variables.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Fce.h"
#include "TimeBasedVariable.h"
extern LIST_ENTRY mAllVarListEntry;
extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;
extern G_EFI_FD_INFO gEfiFdInfo;
EFI_GUID gEfiAuthenticatedVariableBasedTimeGuid = EFI_AUTHENTICATED_VARIABLE_BASED_TIME_GUID;
/**
Gets the pointer to the first variable header in given variable store area.
@param VarStoreHeader Pointer to the Variable Store Header.
@return Pointer to the first variable header.
**/
static
VARIABLE_HEADER *
GetStartPointer (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
{
//
// The end of variable store.
//
return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
}
/**
Gets the pointer to the end of the variable storage area.
This function gets pointer to the end of the variable storage
area, according to the input variable store header.
@param VarStoreHeader Pointer to the Variable Store Header.
@return Pointer to the end of the variable storage area.
**/
static
VARIABLE_HEADER *
GetEndPointer (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
{
//
// The end of variable store
//
return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
}
/**
This code checks if variable header is valid or not.
@param Variable Pointer to the Variable Header.
@retval TRUE Variable header is valid.
@retval FALSE Variable header is not valid.
**/
static
BOOLEAN
IsValidVariableHeader (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable == NULL) || (Variable->StartId != VARIABLE_DATA)) {
return FALSE;
}
return TRUE;
}
/**
This code gets the size of name of variable.
@param Variable Pointer to the Variable Header.
@return UINTN Size of variable in bytes.
**/
static
UINTN
NameSizeOfVariable (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable->State == (UINT8) (-1)) ||
(Variable->DataSize == (UINT32) (-1)) ||
(Variable->NameSize == (UINT32) (-1)) ||
(Variable->Attributes == (UINT32) (-1))
) {
return 0;
}
return (UINTN) Variable->NameSize;
}
/**
This code gets the size of variable data.
@param Variable Pointer to the Variable Header.
@return Size of variable in bytes.
**/
static
UINTN
DataSizeOfVariable (
IN VARIABLE_HEADER *Variable
)
{
if ((Variable->State == (UINT8) (-1)) ||
(Variable->DataSize == (UINT32) (-1)) ||
(Variable->NameSize == (UINT32) (-1)) ||
(Variable->Attributes == (UINT32) (-1))
) {
return 0;
}
return (UINTN) Variable->DataSize;
}
/**
This code gets the pointer to the variable name.
@param Variable Pointer to the Variable Header.
@return Pointer to Variable Name which is Unicode encoding.
**/
static
CHAR16 *
GetVariableNamePtr (
IN VARIABLE_HEADER *Variable
)
{
return (CHAR16 *) (Variable + 1);
}
/**
This code gets the pointer to the variable data.
@param Variable Pointer to the Variable Header.
@return Pointer to Variable Data.
**/
static
UINT8 *
GetVariableDataPtr (
IN VARIABLE_HEADER *Variable
)
{
UINTN Value;
//
// Be careful about pad size for alignment.
//
Value = (UINTN) GetVariableNamePtr (Variable);
Value += NameSizeOfVariable (Variable);
Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
return (UINT8 *) Value;
}
/**
This code gets the pointer to the next variable header.
@param Variable Pointer to the Variable Header.
@return Pointer to next variable header.
**/
static
VARIABLE_HEADER *
GetNextVariablePtr (
IN VARIABLE_HEADER *Variable
)
{
UINTN Value;
if (!IsValidVariableHeader (Variable)) {
return NULL;
}
Value = (UINTN) GetVariableDataPtr (Variable);
Value += DataSizeOfVariable (Variable);
Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
//
// Be careful about pad size for alignment.
//
return (VARIABLE_HEADER *) HEADER_ALIGN (Value);
}
/**
Search and get a free space in the EFI variable zone
@param VariableStoreHeader The start of a EFI variable zone.
@param VarListSize The size of a variables needs to be allocated.
@param FreeBeginVar The dual pointer to the free NV space.
@retval EFI_SUCCESS Return the beginning of a free variable space.
@retval RETURN_BUFFER_TOO_SMALL Failed.
**/
static
EFI_STATUS
GetVariableVar (
IN VARIABLE_STORE_HEADER *VariableStoreHeader,
IN UINT32 VarListSize,
IN OUT CHAR8 **FreeBeginVar
)
{
BOOLEAN Flag;
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *EndOfVariable;
CHAR8 *BeginVar;
BeginVar = NULL;
Flag = FALSE;
Variable = NULL;
EndOfVariable = NULL;
*FreeBeginVar = NULL;
if (VariableStoreHeader == NULL) {
*FreeBeginVar = NULL;
return RETURN_INVALID_PARAMETER;
}
Variable = GetStartPointer (VariableStoreHeader);
EndOfVariable = GetEndPointer(VariableStoreHeader);
//
//Search the beginning of free NV
//
while (Variable != EndOfVariable) {
BeginVar = (CHAR8 *)Variable;
Variable = GetNextVariablePtr (Variable);
if (Variable == NULL) {
Flag = TRUE;
break;
}
}
//
// Check whether the free space is more than what we want
//
if ((CHAR8 *)BeginVar + VarListSize > (CHAR8 *)EndOfVariable) {
return RETURN_BUFFER_TOO_SMALL;
}
//
// If not find the available space, return NULL
//
if (!Flag) {
return RETURN_BUFFER_TOO_SMALL;
}
*FreeBeginVar = BeginVar;
return EFI_SUCCESS;
}
/**
Search whether the variable in VarList has existed in current NV.
Parse the FFS or Fd image, and find the valid variable pointer.
@param VariableStoreHeader The start of a EFI variable zone.
@param VarList The pointer to the VarList
@retval address If the variable existed in current NV, return address
@return NULL Otherwise, return NULL
**/
static
VARIABLE_HEADER *
FindVariableInNv (
IN VARIABLE_STORE_HEADER *VariableStoreHeader,
IN FORMSET_STORAGE *Storage
)
{
BOOLEAN Flag;
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *EndOfVariable;
CHAR16 *VariableName;
Flag = FALSE;
Variable = NULL;
EndOfVariable = NULL;
VariableName = NULL;
if ((VariableStoreHeader == NULL) || (Storage == NULL) || (Storage->Name == NULL)) {
return NULL;
}
Variable = GetStartPointer (VariableStoreHeader);
EndOfVariable = GetEndPointer(VariableStoreHeader);
//
// Parse and compare the variable in the NV space one by one
//
while ((Variable != EndOfVariable) && (Variable != NULL)) {
VariableName = (CHAR16 *)((CHAR8 *)Variable + sizeof (VARIABLE_HEADER));
if (!CompareGuid (&Variable->VendorGuid, &Storage->Guid) \
&& !FceStrCmp (Storage->Name, VariableName) \
&& (Variable->State == VAR_ADDED)
) {
Flag = TRUE;
break;
}
Variable = GetNextVariablePtr (Variable);
}
if (!Flag) {
return NULL;
}
return Variable;
}
/**
Exchange the data between Efi variable and the data of VarList when the
variable use the time stamp authenticated variable header
If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
update the data from varlist to efi variable.
@param VarToList The flag to control the direction of exchange.
@param StorageListHead Decide which variale list be updated
@retval EFI_SUCCESS Get the address successfully.
@retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
@retval EFI_INVALID_PARAMETER Invalid variable name.
**/
EFI_STATUS
SynAuthEfiVariableBasedTime (
IN BOOLEAN VarToList,
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
EFI_STATUS Status;
CHAR8 *NewAvailableAddr;
CHAR8 *DataBase;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VarNameSize;
Status = EFI_SUCCESS;
DataBase = NULL;
NewAvailableAddr = NULL;
VarNameSize = 0;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if (Storage->Buffer == NULL) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return EFI_INVALID_PARAMETER;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if (VarToList) {
//
//Copy the data from NV to the VarList.
//
if (VariableHeader != NULL) {
if (Storage->Buffer == NULL) {
Storage->Buffer = calloc (Storage->Size, sizeof (CHAR8));
ASSERT (Storage->Buffer != NULL);
}
//
// The variable in VarList is CHAR8, but in the EFI variable is CHAR16.
//
DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);
memcpy (
Storage->Buffer,
(VOID *) DataBase,
Storage->Size
);
}
} else {
//
//If existed, copy the List data to the variable in NV directly. If not found, create a new one.
//
VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);
//
//If this variable has existed in current FD, the data in VarList has
// been updated, and this variable is not authenticated type, then
// update it from VarList to the FD.
//
if ((VariableHeader != NULL) \
&& (Storage->Buffer != NULL)
) {
if (!(VariableHeader->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {
DataBase = (CHAR8 *)GetVariableDataPtr (VariableHeader);
memcpy (
(VOID *) DataBase,
Storage->Buffer,
Storage->Size
);
} else {
printf ("Error. Not support to update authenticated variables.\n");
return EFI_INVALID_PARAMETER;
}
} else if ((VariableHeader == NULL) && (Storage->Buffer != NULL)){
//
//If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.
//
if (Storage->NewEfiVarstore
&& ((Storage->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)
) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Try to get the available zone from the efi variables
//
Status = GetVariableVar (
VariableStoreHeader,
Storage->Size + sizeof (VARIABLE_HEADER),
&NewAvailableAddr
);
if (!EFI_ERROR (Status)) {
//
// Create the authenticated variable header
//
VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;
VariableHeader->StartId = VARIABLE_DATA;
VariableHeader->State = VAR_ADDED;
VariableHeader->Reserved = 0x0;
VariableHeader->MonotonicCount = 0x0;
memset (&(VariableHeader->TimeStamp), 0, sizeof (EFI_TIME));
VariableHeader->PubKeyIndex = 0x0;
if (Storage->NewEfiVarstore) {
VariableHeader->Attributes = Storage->Attributes;
} else {
VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
}
VariableHeader->NameSize = VarNameSize;
VariableHeader->DataSize = Storage->Size;
//
//Copy the Guid, variable name, and data in sequence.
//
memcpy (
(VOID *)&(VariableHeader->VendorGuid),
&(Storage->Guid),
sizeof (EFI_GUID)
);
NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Name,
VarNameSize
);
NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Buffer,
Storage->Size * sizeof (CHAR8)
);
} else {
printf ("Error. No available space in NV ram.\n");
return EFI_OUT_OF_RESOURCES;
}
}
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return Status;
}
/**
Remove the variable from Efi variable
Found the variable with the same name in StorageListHead and remove it.
@param StorageListHead Decide which variale list be removed.
@retval EFI_SUCCESS Remove the variables successfully.
**/
EFI_STATUS
RemoveAuthEfiVariableBasedTime (
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if (Storage->Buffer == NULL) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return EFI_INVALID_PARAMETER;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if (VariableHeader != NULL) {
VariableHeader->State = VAR_DELETED;
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return EFI_SUCCESS;
}
/**
Check the store variable is Time stamp authenticated or not
@param VarToList The pointer to the header of Variable Store.
@retval TRUE If authenticated, return TRUE.
@retval FALSE Otherwise, return FALSE.
**/
BOOLEAN
CheckTimeBasedVarStoreOrNot (
IN VOID *VariableStoreHeader
)
{
if (!CompareGuid (
&gEfiAuthenticatedVariableBasedTimeGuid,
&((VARIABLE_STORE_HEADER *)VariableStoreHeader)->Signature)
) {
return TRUE;
} else {
return FALSE;
}
}
/**
Copy time-based authenticated variable to binary in multi-platform mode
@param Storage The pointer to a storage in storage list.
@param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
@param Index The number of the storage. If the Index is 0, record the variable header to
the binary. Or else, only record the storage.
@return length The length of storage
**/
UINT32
CopyTimeBasedVariableToBinary (
IN FORMSET_STORAGE *Storage,
IN OUT UINT8 *StorageBeginning,
IN UINT32 Index
)
{
EFI_STATUS Status;
CHAR8 *NewAvailableAddr;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VarNameSize;
UINT32 HeaderLength;
Status = EFI_SUCCESS;
NewAvailableAddr = NULL;
VarNameSize = 0;
HeaderLength = 0;
VariableHeader = NULL;
VariableStoreHeader = NULL;
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
printf ("Error. One variable name is NULL. Its GUID is: ");
PrintGuid(&(Storage->Guid));
return 0;
}
//
// If the first storage under one specified platformId and defaultId, create the variable header
//
if (Index == 0) {
HeaderLength = WriteDefaultAndPlatformId (StorageBeginning, Storage);
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + HeaderLength);
//
//Create the Variable Storage header
//
memcpy (&(VariableStoreHeader->Signature), &gEfiAuthenticatedVariableBasedTimeGuid, sizeof (EFI_GUID));
VariableStoreHeader->Format = 0x5A;
VariableStoreHeader->State = 0xFE;
//
//Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.
//
VariableStoreHeader->Size = gEfiFdInfo.FdSize;
}
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (StorageBeginning + *(UINT16 *)StorageBeginning);
Status = GetVariableVar (
VariableStoreHeader,
Storage->Size + sizeof (VARIABLE_HEADER),
&NewAvailableAddr
);
if (EFI_ERROR (Status)) {
return FAIL;
}
//
// Create the variable header
//
VarNameSize = 2 * (FceStrLen (Storage->Name) + 1);
VariableHeader = (VARIABLE_HEADER *) NewAvailableAddr;
VariableHeader->StartId = VARIABLE_DATA;
VariableHeader->State = VAR_ADDED;
VariableHeader->Reserved = 0x0;
VariableHeader->MonotonicCount = 0x0;
memset (&(VariableHeader->TimeStamp), 0, sizeof (EFI_TIME));
VariableHeader->PubKeyIndex = 0x0;
if (Storage->NewEfiVarstore) {
VariableHeader->Attributes = Storage->Attributes;
} else {
VariableHeader->Attributes = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
}
VariableHeader->NameSize = VarNameSize;
VariableHeader->DataSize = Storage->Size;
//
//Copy the Guid, variable name, and data in sequence.
//
memcpy (
(VOID *)&(VariableHeader->VendorGuid),
&(Storage->Guid),
sizeof (EFI_GUID)
);
NewAvailableAddr = NewAvailableAddr + sizeof (VARIABLE_HEADER);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Name,
VarNameSize
);
NewAvailableAddr = NewAvailableAddr + VarNameSize + GET_PAD_SIZE (VarNameSize);
memcpy (
(VOID *) NewAvailableAddr,
Storage->Buffer,
Storage->Size * sizeof (CHAR8)
);
//
// Return the length which is from the beginning of Binary
//
return ((UINT32) ((UINT8*)NewAvailableAddr - StorageBeginning) + Storage->Size);
}
/**
Read time-based authenticated variable to storage list in multi-platform mode
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param StorageListEntry The pointer to the storage list.
@return length The length of storage
**/
UINT32
ReadTimeBasedVariableToList (
IN UINT8 *Binary,
IN LIST_ENTRY *StorageListEntry
)
{
VARIABLE_HEADER *EndOfVariable;
VARIABLE_HEADER *Variable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
FORMSET_STORAGE *Storage;
BOOLEAN ReadIdHeaderFlag;
UINT32 Length;
EFI_COMMON_SECTION_HEADER *SectionHeader;
UINT8 *DataBase;
static UINT16 PreDefaultId[MAX_PLATFORM_DEFAULT_ID_NUM];
static UINT64 PrePlatformId[MAX_PLATFORM_DEFAULT_ID_NUM];
VariableStoreHeader = NULL;
Variable = NULL;
ReadIdHeaderFlag = TRUE;
Length = 0;
SectionHeader = (EFI_COMMON_SECTION_HEADER *)Binary;
DataBase = Binary + sizeof (EFI_COMMON_SECTION_HEADER);
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (DataBase + *(UINT16 *)DataBase);
EndOfVariable = GetEndPointer(VariableStoreHeader);
for (Variable = GetStartPointer (VariableStoreHeader);
Length < VariableStoreHeader->Size;
Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize
) {
//
// Create the storage
//
Storage = NULL;
Storage = calloc (sizeof (FORMSET_STORAGE), sizeof (CHAR8));
if (Storage == NULL) {
printf ("Allocate memory failed.\n");
return FAIL;
}
//
// If access the first storage, read the platformId and defaultId
//
if (ReadIdHeaderFlag) {
ReadDefaultAndPlatformIdFromBfv (DataBase, Storage);
Length += sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize;
ReadIdHeaderFlag = FALSE;
memcpy (PreDefaultId, Storage->DefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));
memcpy (PrePlatformId, Storage->PlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));
} else {
//
// Store the DefaultId and PlatformId collected from the header to Storage.
//
memcpy (Storage->DefaultId, PreDefaultId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT16));
memcpy (Storage->PlatformId, PrePlatformId, MAX_PLATFORM_DEFAULT_ID_NUM * sizeof (UINT64));
}
Storage->Attributes = Variable->Attributes;
Storage->Size = (UINT16)Variable->DataSize;
Storage->Name = calloc (Variable->NameSize, sizeof (UINT8));
ASSERT (Storage->Name != NULL);
Storage->Buffer = calloc (Variable->DataSize, sizeof (UINT8));
ASSERT (Storage->Buffer != NULL);
memcpy (
&(Storage->Guid),
&(Variable->VendorGuid),
sizeof (EFI_GUID)
);
memcpy (
Storage->Name,
(UINT8 *)Variable + sizeof (VARIABLE_HEADER),
Variable->NameSize
);
memcpy (
Storage->Buffer,
(UINT8 *)Variable + sizeof (VARIABLE_HEADER) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize),
Storage->Size * sizeof (CHAR8)
);
//
// Assigned the value for comparison in verify mode
//
Storage->Type = EFI_IFR_VARSTORE_EFI_OP;
Storage->NewEfiVarstore = TRUE;
InitializeListHead (&Storage->NameValueListHead);
InsertTailList(StorageListEntry, &Storage->Link);
//
// If the last variable, exit.
//
if (Variable == EndOfVariable) {
break;
}
Variable = GetNextVariablePtr (Variable);
assert (Variable != NULL);
}
//
// Return the length which is from the beginning of Binary
//
Length = FvBufExpand3ByteSize (SectionHeader->Size);
return Length;
}
/**
Check whether exists the valid time-based variables in NvStorage or not.
@retval TRUE If existed, return TRUE.
@retval FALSE Others
**/
BOOLEAN
ExistTimeBasedEfiVarOrNot (
IN LIST_ENTRY *StorageListHead
)
{
EFI_FIRMWARE_VOLUME_HEADER *VarAddr;
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
VARIABLE_HEADER *VariableHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableHeader = NULL;
VarAddr = (EFI_FIRMWARE_VOLUME_HEADER *) gEfiFdInfo.EfiVariableAddr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((CHAR8 *)VarAddr + VarAddr->HeaderLength);
//
//Parse the variable range, and check whether there is some existed ones.
//
StorageLink = GetFirstNode (StorageListHead);
while (!IsNull (StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageLink);
//
// Ignore the invalid varlist node
//
if ((Storage->Buffer == NULL)
|| (Storage->Name == NULL)
|| (FceStrLen(Storage->Name) == 0)
) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
//
// Report error, if the variable name is invalid.
//
if ((Storage->Name == NULL) || (FceStrLen(Storage->Name) == 0)) {
StorageLink = GetNextNode (StorageListHead, StorageLink);
continue;
}
VariableHeader = FindVariableInNv (
VariableStoreHeader,
Storage
);
if ((VariableHeader != NULL)) {
return TRUE;
}
StorageLink = GetNextNode (StorageListHead, StorageLink);
}
return FALSE;
}
/**
Fix the size of time-based variable header.
@param Binary The pointer to the header of storage under specifed platformId and defaultId
@param Length The length of binary.
**/
VOID
FixBasedTimeVariableHeaderSize (
IN UINT8 *BinaryBeginning,
IN UINT32 Length
)
{
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (BinaryBeginning + *(UINT16 *)BinaryBeginning);
VariableStoreHeader->Size = Length - *(UINT16 *)BinaryBeginning;
}

View File

@ -0,0 +1,166 @@
/** @file
The header of TimeBasedVariable.c.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __AUTHENTICATED_VARIABLE_FORMAT_BASED_TIME_H__
#define __AUTHENTICATED_VARIABLE_FORMAT_BASED_TIME_H__
#define EFI_AUTHENTICATED_VARIABLE_BASED_TIME_GUID \
{ 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
extern EFI_GUID gEfiAuthenticatedVariableBasedTimeGuid;
///
/// Alignment of variable name and data, according to the architecture:
/// * For IA-32 and Intel(R) 64 architectures: 1
/// * For IA-64 architecture: 8
///
#if defined (MDE_CPU_IPF)
#define ALIGNMENT 8
#else
#define ALIGNMENT 1
#endif
///
/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
///
#if (ALIGNMENT == 1)
#define GET_PAD_SIZE(a) (0)
#else
#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
#endif
///
/// Alignment of Variable Data Header in Variable Store region
///
#define HEADER_ALIGNMENT 4
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
///
/// Status of Variable Store Region
///
typedef enum {
EfiRaw,
EfiValid,
EfiInvalid,
EfiUnknown
} VARIABLE_STORE_STATUS;
#pragma pack(1)
#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID
///
/// Variable Store Header Format and State
///
#define VARIABLE_STORE_FORMATTED 0x5a
#define VARIABLE_STORE_HEALTHY 0xfe
///
/// Variable Store region header
///
typedef struct {
///
/// Variable store region signature.
///
EFI_GUID Signature;
///
/// Size of entire variable store,
/// including size of variable store header but not including the size of FvHeader.
///
UINT32 Size;
///
/// Variable region format state.
///
UINT8 Format;
///
/// Variable region healthy state.
///
UINT8 State;
UINT16 Reserved;
UINT32 Reserved1;
} VARIABLE_STORE_HEADER;
///
/// Variable data start flag.
///
#define VARIABLE_DATA 0x55AA
///
/// Variable State flags
///
#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition
#define VAR_DELETED 0xfd ///< Variable is obsolete
#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid
#define VAR_ADDED 0x3f ///< Variable has been completely added
///
/// Single Variable Data Header Structure.
///
typedef struct {
///
/// Variable Data Start Flag.
///
UINT16 StartId;
///
/// Variable State defined above.
///
UINT8 State;
UINT8 Reserved;
///
/// Attributes of variable defined in UEFI spec
///
UINT32 Attributes;
///
/// Associated monotonic count value against replay attack.
///
UINT64 MonotonicCount;
///
/// Associated TimeStamp value against replay attack.
///
EFI_TIME TimeStamp;
///
/// Index of associated public key in database.
///
UINT32 PubKeyIndex;
///
/// Size of variable null-terminated Unicode string name.
///
UINT32 NameSize;
///
/// Size of the variable data without this header.
///
UINT32 DataSize;
///
/// A unique identifier for the vendor that produces and consumes this varaible.
///
EFI_GUID VendorGuid;
} VARIABLE_HEADER;
#pragma pack()
typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;
///
/// This structure contains the variable list that is put in EFI system table.
/// The variable driver collects all variables that were used at boot service time and produces this list.
/// This is an optional feature to dump all used variables in shell environment.
///
struct _VARIABLE_INFO_ENTRY {
VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.
EFI_GUID VendorGuid; ///< Guid of Variable.
CHAR16 *Name; ///< Name of Variable.
UINT32 Attributes; ///< Attributes of variable defined in UEFI spec.
UINT32 ReadCount; ///< Number of times to read this variable.
UINT32 WriteCount; ///< Number of times to write this variable.
UINT32 DeleteCount; ///< Number of times to delete this variable.
UINT32 CacheCount; ///< Number of times that cache hits this variable.
BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.
};
#endif // _EFI_VARIABLE_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
/** @file
The header of Variable.c.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __VARIABLE_FORMAT_H__
#define __VARIABLE_FORMAT_H__
#define EFI_VARIABLE_GUID \
{ 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } }
extern EFI_GUID gEfiVariableGuid;
///
/// Alignment of variable name and data, according to the architecture:
/// * For IA-32 and Intel(R) 64 architectures: 1.
/// * For IA-64 architecture: 8.
///
#if defined (MDE_CPU_IPF)
#define ALIGNMENT 8
#else
#define ALIGNMENT 1
#endif
///
/// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
///
#if (ALIGNMENT == 1)
#define GET_PAD_SIZE(a) (0)
#else
#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
#endif
///
/// Alignment of Variable Data Header in Variable Store region.
///
#define HEADER_ALIGNMENT 4
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
///
/// Status of Variable Store Region.
///
typedef enum {
EfiRaw,
EfiValid,
EfiInvalid,
EfiUnknown
} VARIABLE_STORE_STATUS;
#pragma pack(1)
#define VARIABLE_STORE_SIGNATURE EFI_VARIABLE_GUID
///
/// Variable Store Header Format and State.
///
#define VARIABLE_STORE_FORMATTED 0x5a
#define VARIABLE_STORE_HEALTHY 0xfe
///
/// Variable Store region header.
///
typedef struct {
///
/// Variable store region signature.
///
EFI_GUID Signature;
///
/// Size of entire variable store,
/// including size of variable store header but not including the size of FvHeader.
///
UINT32 Size;
///
/// Variable region format state.
///
UINT8 Format;
///
/// Variable region healthy state.
///
UINT8 State;
UINT16 Reserved;
UINT32 Reserved1;
} VARIABLE_STORE_HEADER;
///
/// Variable data start flag.
///
#define VARIABLE_DATA 0x55AA
///
/// Variable State flags.
///
#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition.
#define VAR_DELETED 0xfd ///< Variable is obsolete.
#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid.
#define VAR_ADDED 0x3f ///< Variable has been completely added.
///
/// Single Variable Data Header Structure.
///
typedef struct {
///
/// Variable Data Start Flag.
///
UINT16 StartId;
///
/// Variable State defined above.
///
UINT8 State;
UINT8 Reserved;
///
/// Attributes of variable defined in UEFI specification.
///
UINT32 Attributes;
///
/// Size of variable null-terminated Unicode string name.
///
UINT32 NameSize;
///
/// Size of the variable data without this header.
///
UINT32 DataSize;
///
/// A unique identifier for the vendor that produces and consumes this varaible.
///
EFI_GUID VendorGuid;
} VARIABLE_HEADER;
#pragma pack()
typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;
///
/// This structure contains the variable list that is put in EFI system table.
/// The variable driver collects all variables that were used at boot service time and produces this list.
/// This is an optional feature to dump all used variables in shell environment.
///
struct _VARIABLE_INFO_ENTRY {
VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.
EFI_GUID VendorGuid; ///< Guid of Variable.
CHAR16 *Name; ///< Name of Variable.
UINT32 Attributes; ///< Attributes of variable defined in UEFI specification.
UINT32 ReadCount; ///< Number of times to read this variable.
UINT32 WriteCount; ///< Number of times to write this variable.
UINT32 DeleteCount; ///< Number of times to delete this variable.
UINT32 CacheCount; ///< Number of times that cache hits this variable.
BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.
};
#endif // _EFI_VARIABLE_H_

View File

@ -0,0 +1,55 @@
/** @file
The header of common Variable.c TimeBasedVariable.c and MonotonicBasedVariable.c.
Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __VARIABLE_COMMON_H__
#define __VARIABLE_COMMON_H__
/**
Check the store variable is no-authenticated or not
@param VarToList The pointer to the header of Variable Store.
@retval TRUE If no-authenticated, return TRUE.
@retval FALSE Otherwise, return FALSE.
**/
BOOLEAN
CheckNormalVarStoreOrNot (
IN VOID *VariableStoreHeader
);
/**
Check the store variable is Monotonic based authenticated or not
@param VarToList The pointer to the header of Variable Store.
@retval TRUE If authenticated, return TRUE.
@retval FALSE Otherwise, return FALSE.
**/
BOOLEAN
CheckMonotonicBasedVarStore (
IN VOID *VariableStoreHeader
);
/**
Check the store variable is Time stamp authenticated or not
@param VarToList The pointer to the header of Variable Store.
@retval TRUE If authenticated, return TRUE.
@retval FALSE Otherwise, return FALSE.
**/
BOOLEAN
CheckTimeBasedVarStoreOrNot (
IN VOID *VariableStoreHeader
);
#endif // _EFI_VARIABLE_COMMON_H_

View File

@ -1,7 +1,7 @@
## @file
# GNU/Linux makefile for C tools build.
#
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -49,6 +49,7 @@ APPLICATIONS = \
VfrCompile \
BfmLib \
EfiRom \
FCE \
GenFfs \
GenFv \
GenFw \

View File

@ -1,7 +1,7 @@
## @file
# Windows makefile for C tools build.
#
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
HOST_ARCH = IA32
@ -14,6 +14,7 @@ APPLICATIONS = \
BrotliCompress \
BfmLib \
EfiRom \
FCE \
GenCrc32 \
GenFfs \
GenFv \