diff options
Diffstat (limited to 'BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp')
-rw-r--r-- | BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp | 2879 |
1 files changed, 2879 insertions, 0 deletions
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp new file mode 100644 index 0000000000..df179225d9 --- /dev/null +++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp @@ -0,0 +1,2879 @@ +/** @file
+
+ Vfr common library functions.
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. 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.
+
+**/
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "VfrUtilityLib.h"
+#include "VfrFormPkg.h"
+
+VOID
+CVfrBinaryOutput::WriteLine (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+}
+
+VOID
+CVfrBinaryOutput::WriteEnd (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize - 1; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
+}
+
+SConfigInfo::SConfigInfo (
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT32 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ mNext = NULL;
+ mOffset = Offset;
+ mWidth = (UINT16)Width;
+ mValue = new UINT8[mWidth];
+ if (mValue == NULL) {
+ return;
+ }
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ memcpy (mValue, &Value.u8, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ memcpy (mValue, &Value.u16, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ memcpy (mValue, &Value.u32, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ memcpy (mValue, &Value.u64, mWidth);
+ break;
+ case EFI_IFR_TYPE_BOOLEAN :
+ memcpy (mValue, &Value.b, mWidth);
+ break;
+ case EFI_IFR_TYPE_TIME :
+ memcpy (mValue, &Value.time, mWidth);
+ break;
+ case EFI_IFR_TYPE_DATE :
+ memcpy (mValue, &Value.date, mWidth);
+ break;
+ case EFI_IFR_TYPE_STRING :
+ memcpy (mValue, &Value.string, mWidth);
+ break;
+ case EFI_IFR_TYPE_OTHER :
+ return;
+ }
+}
+
+SConfigInfo::~SConfigInfo (
+ VOID
+ )
+{
+ BUFFER_SAFE_FREE (mValue);
+}
+
+SConfigItem::SConfigItem (
+ IN CHAR8 *Name,
+ IN CHAR8 *Id
+ )
+{
+ mName = NULL;
+ mId = 0;
+ mInfoStrList = NULL;
+ mNext = NULL;
+
+ if (Name != NULL) {
+ if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
+ strcpy (mName, Name);
+ }
+ }
+
+ if (Id != NULL) {
+ if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
+ strcpy (mId, Id);
+ }
+ }
+}
+
+SConfigItem::SConfigItem (
+ IN CHAR8 *Name,
+ IN CHAR8 *Id,
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT16 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ mName = NULL;
+ mId = NULL;
+ mInfoStrList = NULL;
+ mNext = NULL;
+
+ if (Name != NULL) {
+ if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
+ strcpy (mName, Name);
+ }
+ }
+
+ if (Id != NULL) {
+ if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
+ strcpy (mId, Id);
+ }
+ }
+
+ mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
+}
+
+SConfigItem::~SConfigItem (
+ VOID
+ )
+{
+ SConfigInfo *Info;
+
+ BUFFER_SAFE_FREE (mName);
+ BUFFER_SAFE_FREE (mId);
+ while (mInfoStrList != NULL) {
+ Info = mInfoStrList;
+ mInfoStrList = mInfoStrList->mNext;
+
+ BUFFER_SAFE_FREE (Info);
+ }
+}
+
+UINT8
+CVfrBufferConfig::Register (
+ IN CHAR8 *Name,
+ IN CHAR8 *Id
+ )
+{
+ SConfigItem *pNew;
+
+ if (Select (Name) == 0) {
+ return 1;
+ }
+
+ if ((pNew = new SConfigItem (Name, Id)) == NULL) {
+ return 2;
+ }
+ if (mItemListHead == NULL) {
+ mItemListHead = pNew;
+ mItemListTail = pNew;
+ } else {
+ mItemListTail->mNext = pNew;
+ mItemListTail = pNew;
+ }
+ mItemListPos = pNew;
+
+ return 0;
+}
+
+VOID
+CVfrBufferConfig::Open (
+ VOID
+ )
+{
+ mItemListPos = mItemListHead;
+}
+
+BOOLEAN
+CVfrBufferConfig::Eof(
+ VOID
+ )
+{
+ return (mItemListPos == NULL) ? TRUE : FALSE;
+}
+
+UINT8
+CVfrBufferConfig::Select (
+ IN CHAR8 *Name,
+ IN CHAR8 *Id
+ )
+{
+ SConfigItem *p;
+
+ if (Name == NULL) {
+ mItemListPos = mItemListHead;
+ return 0;
+ } else {
+ for (p = mItemListHead; p != NULL; p = p->mNext) {
+ if (strcmp (p->mName, Name) != 0) {
+ continue;
+ }
+
+ if (Id != NULL) {
+ if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
+ continue;
+ }
+ } else if (p->mId != NULL) {
+ continue;
+ }
+
+ mItemListPos = p;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+UINT8
+CVfrBufferConfig::Write (
+ IN CONST CHAR8 Mode,
+ IN CHAR8 *Name,
+ IN CHAR8 *Id,
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT32 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ UINT8 Ret;
+ SConfigItem *pItem;
+ SConfigInfo *pInfo;
+
+ if ((Ret = Select (Name)) != 0) {
+ return Ret;
+ }
+
+ switch (Mode) {
+ case 'a' : // add
+ if (Select (Name, Id) != 0) {
+ if ((pItem = new SConfigItem (Name, Id, Type, Offset, Width, Value)) == NULL) {
+ return 2;
+ }
+ if (mItemListHead == NULL) {
+ mItemListHead = pItem;
+ mItemListTail = pItem;
+ } else {
+ mItemListTail->mNext = pItem;
+ mItemListTail = pItem;
+ }
+ mItemListPos = pItem;
+ } else {
+ // tranverse the list to find out if there's already the value for the same offset
+ for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
+ if (pInfo->mOffset == Offset) {
+ // check if the value and width are the same; return error if not
+ if ((Id != NULL) && (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0)) {
+ return VFR_RETURN_DEFAULT_VALUE_REDEFINED;
+ }
+ return 0;
+ }
+ }
+ if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
+ return 2;
+ }
+ pInfo->mNext = mItemListPos->mInfoStrList;
+ mItemListPos->mInfoStrList = pInfo;
+ }
+ break;
+
+ case 'd' : // delete
+ if (mItemListHead == mItemListPos) {
+ mItemListHead = mItemListPos->mNext;
+ delete mItemListPos;
+ break;
+ }
+
+ for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
+ ;
+
+ pItem->mNext = mItemListPos->mNext;
+ if (mItemListTail == mItemListPos) {
+ mItemListTail = pItem;
+ }
+ delete mItemListPos;
+ mItemListPos = pItem->mNext;
+ break;
+
+ case 'i' : // set info
+ if (mItemListPos->mId != NULL) {
+ delete mItemListPos->mId;
+ }
+ mItemListPos->mId = NULL;
+ if (Id != NULL) {
+ if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
+ return 2;
+ }
+ strcpy (mItemListPos->mId, Id);
+ }
+ break;
+
+ default :
+ return 1;
+ }
+
+ return 0;
+}
+
+
+VOID
+CVfrBufferConfig::Close (
+ VOID
+ )
+{
+ mItemListPos = NULL;
+}
+
+#define BYTES_PRE_LINE 0x10
+
+VOID
+CVfrBufferConfig::OutputCFile (
+ IN FILE *pFile,
+ IN CHAR8 *BaseName
+ )
+{
+ CVfrBinaryOutput Output;
+ SConfigItem *Item;
+ SConfigInfo *Info;
+ UINT32 TotalLen;
+
+ if (pFile == NULL) {
+ return;
+ }
+
+ for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
+ if (Item->mId != NULL || Item->mInfoStrList == NULL) {
+ continue;
+ }
+ fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
+
+ TotalLen = sizeof (UINT32);
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ TotalLen += sizeof (UINT16) * 2;
+ }
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
+
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ fprintf (pFile, "\n");
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
+ }
+ fprintf (pFile, "\n};\n");
+ }
+
+ for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
+ if (Item->mId != NULL && Item->mInfoStrList != NULL) {
+ fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
+
+ TotalLen = sizeof (UINT32);
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ TotalLen += Info->mWidth + sizeof (UINT16) * 2;
+ }
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
+
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ fprintf (pFile, "\n");
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
+ if (Info->mNext == NULL) {
+ Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
+ } else {
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
+ }
+ }
+ fprintf (pFile, "\n};\n");
+ }
+ }
+}
+
+CVfrBufferConfig::CVfrBufferConfig (
+ VOID
+ )
+{
+ mItemListHead = NULL;
+ mItemListTail = NULL;
+ mItemListPos = NULL;
+}
+
+CVfrBufferConfig::~CVfrBufferConfig (
+ VOID
+ )
+{
+ SConfigItem *p;
+
+ while (mItemListHead != NULL) {
+ p = mItemListHead;
+ mItemListHead = mItemListHead->mNext;
+ delete p;
+ }
+
+ mItemListHead = NULL;
+ mItemListTail = NULL;
+ mItemListPos = NULL;
+}
+
+CVfrBufferConfig gCVfrBufferConfig;
+
+static struct {
+ CHAR8 *mTypeName;
+ UINT8 mType;
+ UINT32 mSize;
+ UINT32 mAlign;
+} gInternalTypesTable [] = {
+ {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},
+ {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},
+ {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},
+ {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},
+ {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},
+ {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},
+ {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
+ {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
+ {NULL, EFI_IFR_TYPE_OTHER, 0, 0}
+};
+
+STATIC
+BOOLEAN
+_IS_INTERNAL_TYPE (
+ IN CHAR8 *TypeName
+ )
+{
+ UINT32 Index;
+
+ if (TypeName == NULL) {
+ return FALSE;
+ }
+
+ for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
+ if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+STATIC
+CHAR8 *
+TrimHex (
+ IN CHAR8 *Str,
+ OUT bool *IsHex
+ )
+{
+ *IsHex = FALSE;
+
+ while (*Str && *Str == ' ') {
+ Str++;
+ }
+ while (*Str && *Str == '0') {
+ Str++;
+ }
+ if (*Str && (*Str == 'x' || *Str == 'X')) {
+ Str++;
+ *IsHex = TRUE;
+ }
+
+ return Str;
+}
+
+UINT32
+_STR2U32 (
+ IN CHAR8 *Str
+ )
+{
+ bool IsHex;
+ UINT32 Value;
+ CHAR8 c;
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ //
+ // BUG: does not handle overflow here
+ //
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ }
+
+ return Value;
+}
+
+VOID
+CVfrVarDataTypeDB::RegisterNewType (
+ IN SVfrDataType *New
+ )
+{
+ New->mNext = mDataTypeList;
+ mDataTypeList = New;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::ExtractStructTypeName (
+ IN CHAR8 *&VarStr,
+ OUT CHAR8 *TName
+ )
+{
+ if (TName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ while((*VarStr != '\0') && (*VarStr != '.')) {
+ *TName = *VarStr;
+ VarStr++;
+ TName++;
+ }
+ *TName = '\0';
+ if (*VarStr == '.') {
+ VarStr++;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
+ IN CHAR8 *&VarStr,
+ IN CHAR8 *FName,
+ OUT UINT32 &ArrayIdx
+ )
+{
+ UINT32 Idx;
+ CHAR8 ArrayStr[MAX_NAME_LEN + 1];
+
+ ArrayIdx = INVALID_ARRAY_INDEX;
+
+ if (FName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ while((*VarStr != '\0') &&
+ (*VarStr != '.') &&
+ (*VarStr != '[') &&
+ (*VarStr != ']')) {
+ *FName = *VarStr;
+ VarStr++;
+ FName++;
+ }
+ *FName = '\0';
+
+ switch (*VarStr) {
+ case '.' :
+ VarStr++;
+ case '\0':
+ return VFR_RETURN_SUCCESS;
+ case '[' :
+ VarStr++;
+ for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
+ ArrayStr[Idx] = *VarStr;
+ }
+ ArrayStr[Idx] = '\0';
+
+ if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
+ return VFR_RETURN_DATA_STRING_ERROR;
+ }
+ ArrayIdx = _STR2U32 (ArrayStr);
+ if (*VarStr == ']') {
+ VarStr++;
+ }
+ return VFR_RETURN_SUCCESS;
+ case ']':
+ return VFR_RETURN_DATA_STRING_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetTypeField (
+ IN CHAR8 *FName,
+ IN SVfrDataType *Type,
+ OUT SVfrDataField *&Field
+ )
+{
+ SVfrDataField *pField = NULL;
+
+ if ((FName == NULL) && (Type == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
+ if (strcmp (pField->mFieldName, FName) == 0) {
+ Field = pField;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetFieldOffset (
+ IN SVfrDataField *Field,
+ IN UINT32 ArrayIdx,
+ OUT UINT32 &Offset
+ )
+{
+ if (Field == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ //
+ // Framework Vfr file Array Index is from 1.
+ // But Uefi Vfr file Array Index is from 0.
+ //
+ if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
+ if (ArrayIdx == 0) {
+ return VFR_RETURN_ERROR_ARRARY_NUM;
+ }
+ ArrayIdx = ArrayIdx - 1;
+ }
+
+ if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
+ return VFR_RETURN_ERROR_ARRARY_NUM;
+ }
+
+ //
+ // Be compatible with the current usage
+ // If ArraryIdx is not specified, the first one is used.
+ //
+ // if ArrayNum is larger than zero, ArraryIdx must be specified.
+ //
+ // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
+ // return VFR_RETURN_ERROR_ARRARY_NUM;
+ // }
+ //
+
+ Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
+ return VFR_RETURN_SUCCESS;
+}
+
+UINT8
+CVfrVarDataTypeDB::GetFieldWidth (
+ IN SVfrDataField *Field
+ )
+{
+ if (Field == NULL) {
+ return 0;
+ }
+
+ return Field->mFieldType->mType;
+}
+
+UINT32
+CVfrVarDataTypeDB::GetFieldSize (
+ IN SVfrDataField *Field,
+ IN UINT32 ArrayIdx
+ )
+{
+ if (Field == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
+ return Field->mFieldType->mTotalSize * Field->mArrayNum;
+ } else {
+ return Field->mFieldType->mTotalSize;
+ }
+}
+
+VOID
+CVfrVarDataTypeDB::InternalTypesListInit (
+ VOID
+ )
+{
+ SVfrDataType *New = NULL;
+ UINT32 Index;
+
+ for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
+ New = new SVfrDataType;
+ if (New != NULL) {
+ strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
+ New->mType = gInternalTypesTable[Index].mType;
+ New->mAlign = gInternalTypesTable[Index].mAlign;
+ New->mTotalSize = gInternalTypesTable[Index].mSize;
+ if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
+ SVfrDataField *pYearField = new SVfrDataField;
+ SVfrDataField *pMonthField = new SVfrDataField;
+ SVfrDataField *pDayField = new SVfrDataField;
+
+ strcpy (pYearField->mFieldName, "Year");
+ GetDataType ("UINT8", &pYearField->mFieldType);
+ pYearField->mOffset = 0;
+ pYearField->mNext = pMonthField;
+ pYearField->mArrayNum = 0;
+
+ strcpy (pMonthField->mFieldName, "Month");
+ GetDataType ("UINT8", &pMonthField->mFieldType);
+ pMonthField->mOffset = 1;
+ pMonthField->mNext = pDayField;
+ pMonthField->mArrayNum = 0;
+
+ strcpy (pDayField->mFieldName, "Day");
+ GetDataType ("UINT8", &pDayField->mFieldType);
+ pDayField->mOffset = 2;
+ pDayField->mNext = NULL;
+ pDayField->mArrayNum = 0;
+
+ New->mMembers = pYearField;
+ } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
+ SVfrDataField *pHoursField = new SVfrDataField;
+ SVfrDataField *pMinutesField = new SVfrDataField;
+ SVfrDataField *pSecondsField = new SVfrDataField;
+
+ strcpy (pHoursField->mFieldName, "Hours");
+ GetDataType ("UINT8", &pHoursField->mFieldType);
+ pHoursField->mOffset = 0;
+ pHoursField->mNext = pMinutesField;
+ pHoursField->mArrayNum = 0;
+
+ strcpy (pMinutesField->mFieldName, "Minutes");
+ GetDataType ("UINT8", &pMinutesField->mFieldType);
+ pMinutesField->mOffset = 1;
+ pMinutesField->mNext = pSecondsField;
+ pMinutesField->mArrayNum = 0;
+
+ strcpy (pSecondsField->mFieldName, "Seconds");
+ GetDataType ("UINT8", &pSecondsField->mFieldType);
+ pSecondsField->mOffset = 2;
+ pSecondsField->mNext = NULL;
+ pSecondsField->mArrayNum = 0;
+
+ New->mMembers = pHoursField;
+ } else {
+ New->mMembers = NULL;
+ }
+ New->mNext = NULL;
+ RegisterNewType (New);
+ New = NULL;
+ }
+ }
+}
+
+CVfrVarDataTypeDB::CVfrVarDataTypeDB (
+ VOID
+ )
+{
+ mDataTypeList = NULL;
+ mNewDataType = NULL;
+ mCurrDataField = NULL;
+ mPackAlign = DEFAULT_PACK_ALIGN;
+ mPackStack = NULL;
+ mFirstNewDataTypeName = NULL;
+
+ InternalTypesListInit ();
+}
+
+CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
+ VOID
+ )
+{
+ SVfrDataType *pType;
+ SVfrDataField *pField;
+ SVfrPackStackNode *pPack;
+
+ if (mNewDataType != NULL) {
+ delete mNewDataType;
+ }
+
+ while (mDataTypeList != NULL) {
+ pType = mDataTypeList;
+ mDataTypeList = mDataTypeList->mNext;
+ while(pType->mMembers != NULL) {
+ pField = pType->mMembers;
+ pType->mMembers = pType->mMembers->mNext;
+ delete pField;
+ }
+ delete pType;
+ }
+
+ while (mPackStack != NULL) {
+ pPack = mPackStack;
+ mPackStack = mPackStack->mNext;
+ delete pPack;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::Pack (
+ IN UINT32 LineNum,
+ IN UINT8 Action,
+ IN CHAR8 *Identifier,
+ IN UINT32 Number
+ )
+{
+ UINT32 PackAlign;
+ CHAR8 Msg[MAX_STRING_LEN] = {0, };
+
+ if (Action & VFR_PACK_SHOW) {
+ sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
+ gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);
+ }
+
+ if (Action & VFR_PACK_PUSH) {
+ SVfrPackStackNode *pNew = NULL;
+
+ if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+ pNew->mNext = mPackStack;
+ mPackStack = pNew;
+ }
+
+ if (Action & VFR_PACK_POP) {
+ SVfrPackStackNode *pNode = NULL;
+
+ if (mPackStack == NULL) {
+ gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "#pragma pack(pop...) : more pops than pushes");
+ }
+
+ for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->Match (Identifier) == TRUE) {
+ mPackAlign = pNode->mNumber;
+ mPackStack = pNode->mNext;
+ }
+ }
+ }
+
+ if (Action & VFR_PACK_ASSIGN) {
+ PackAlign = (Number > 1) ? Number + Number % 2 : Number;
+ if ((PackAlign == 0) || (PackAlign > 16)) {
+ gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
+ } else {
+ mPackAlign = PackAlign;
+ }
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrVarDataTypeDB::DeclareDataTypeBegin (
+ VOID
+ )
+{
+ SVfrDataType *pNewType = NULL;
+
+ pNewType = new SVfrDataType;
+ pNewType->mTypeName[0] = '\0';
+ pNewType->mType = EFI_IFR_TYPE_OTHER;
+ pNewType->mAlign = DEFAULT_ALIGN;
+ pNewType->mTotalSize = 0;
+ pNewType->mMembers = NULL;
+ pNewType->mNext = NULL;
+
+ mNewDataType = pNewType;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::SetNewTypeName (
+ IN CHAR8 *TypeName
+ )
+{
+ SVfrDataType *pType;
+
+ if (mNewDataType == NULL) {
+ return VFR_RETURN_ERROR_SKIPED;
+ }
+ if (TypeName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+ if (strlen(TypeName) >= MAX_NAME_LEN) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (strcmp(pType->mTypeName, TypeName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ strcpy(mNewDataType->mTypeName, TypeName);
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::DataTypeAddField (
+ IN CHAR8 *FieldName,
+ IN CHAR8 *TypeName,
+ IN UINT32 ArrayNum
+ )
+{
+ SVfrDataField *pNewField = NULL;
+ SVfrDataType *pFieldType = NULL;
+ SVfrDataField *pTmp;
+ UINT32 Align;
+
+ CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
+
+ if (strlen (FieldName) >= MAX_NAME_LEN) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
+ if (strcmp (pTmp->mFieldName, FieldName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ Align = MIN (mPackAlign, pFieldType->mAlign);
+
+ if ((pNewField = new SVfrDataField) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ strcpy (pNewField->mFieldName, FieldName);
+ pNewField->mFieldType = pFieldType;
+ pNewField->mArrayNum = ArrayNum;
+ if ((mNewDataType->mTotalSize % Align) == 0) {
+ pNewField->mOffset = mNewDataType->mTotalSize;
+ } else {
+ pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
+ }
+ if (mNewDataType->mMembers == NULL) {
+ mNewDataType->mMembers = pNewField;
+ pNewField->mNext = NULL;
+ } else {
+ for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
+ ;
+ pTmp->mNext = pNewField;
+ pNewField->mNext = NULL;
+ }
+
+ mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrVarDataTypeDB::DeclareDataTypeEnd (
+ VOID
+ )
+{
+ if (mNewDataType->mTypeName[0] == '\0') {
+ return;
+ }
+
+ if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
+ mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
+ }
+
+ RegisterNewType (mNewDataType);
+ if (mFirstNewDataTypeName == NULL) {
+ mFirstNewDataTypeName = mNewDataType->mTypeName;
+ }
+
+ mNewDataType = NULL;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataType (
+ IN CHAR8 *TypeName,
+ OUT SVfrDataType **DataType
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (TypeName == NULL) {
+ return VFR_RETURN_ERROR_SKIPED;
+ }
+
+ if (DataType == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *DataType = NULL;
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (strcmp (TypeName, pDataType->mTypeName) == 0) {
+ *DataType = pDataType;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataTypeSize (
+ IN UINT8 DataType,
+ OUT UINT32 *Size
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (Size == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *Size = 0;
+ DataType = DataType & 0x0F;
+
+ //
+ // For user defined data type, the size can't be got by this function.
+ //
+ if (DataType == EFI_IFR_TYPE_OTHER) {
+ return VFR_RETURN_SUCCESS;
+ }
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (DataType == pDataType->mType) {
+ *Size = pDataType->mTotalSize;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataTypeSize (
+ IN CHAR8 *TypeName,
+ OUT UINT32 *Size
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (Size == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *Size = 0;
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (strcmp (TypeName, pDataType->mTypeName) == 0) {
+ *Size = pDataType->mTotalSize;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataFieldInfo (
+ IN CHAR8 *VarStr,
+ OUT UINT16 &Offset,
+ OUT UINT8 &Type,
+ OUT UINT32 &Size
+ )
+{
+ CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
+ UINT32 ArrayIdx, Tmp;
+ SVfrDataType *pType = NULL;
+ SVfrDataField *pField = NULL;
+
+ Offset = 0;
+ Type = EFI_IFR_TYPE_OTHER;
+ Size = 0;
+
+ CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
+
+ //
+ // if it is not struct data type
+ //
+ Type = pType->mType;
+ Size = pType->mTotalSize;
+
+ while (*VarStr != '\0') {
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
+ pType = pField->mFieldType;
+ CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
+ Offset += Tmp;
+ Type = GetFieldWidth (pField);
+ Size = GetFieldSize (pField, ArrayIdx);
+ }
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
+ OUT CHAR8 ***NameList,
+ OUT UINT32 *ListSize
+ )
+{
+ UINT32 Index;
+ SVfrDataType *pType;
+
+ if ((NameList == NULL) || (ListSize == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *NameList = NULL;
+ *ListSize = 0;
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
+ (*ListSize)++;
+ }
+ }
+
+ if (*ListSize == 0) {
+ return VFR_RETURN_SUCCESS;
+ }
+
+ if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
+ *ListSize = 0;
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
+ if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
+ (*NameList)[Index] = pType->mTypeName;
+ }
+ }
+ return VFR_RETURN_SUCCESS;
+}
+
+BOOLEAN
+CVfrVarDataTypeDB::IsTypeNameDefined (
+ IN CHAR8 *TypeName
+ )
+{
+ SVfrDataType *pType;
+
+ if (TypeName == NULL) {
+ return FALSE;
+ }
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (strcmp (pType->mTypeName, TypeName) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+CVfrVarDataTypeDB::Dump (
+ IN FILE *File
+ )
+{
+ SVfrDataType *pTNode;
+ SVfrDataField *pFNode;
+
+ fprintf (File, "\n\n***************************************************************\n");
+ fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
+ for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
+ fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
+ fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
+ for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
+ if (pFNode->mArrayNum > 0) {
+ fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
+ pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
+ } else {
+ fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
+ pFNode->mFieldName, pFNode->mFieldType->mTypeName);
+ }
+ }
+ fprintf (File, "\t\t};\n");
+ fprintf (File, "---------------------------------------------------------------\n");
+ }
+ fprintf (File, "***************************************************************\n");
+}
+
+#ifdef CVFR_VARDATATYPEDB_DEBUG
+VOID
+CVfrVarDataTypeDB::ParserDB (
+ VOID
+ )
+{
+ SVfrDataType *pTNode;
+ SVfrDataField *pFNode;
+
+ printf ("***************************************************************\n");
+ printf ("\t\tmPackAlign = %x\n", mPackAlign);
+ for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
+ printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
+ printf ("\t\tstruct %s {\n", pTNode->mTypeName);
+ for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
+ printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
+ }
+ printf ("\t\t};\n");
+ printf ("---------------------------------------------------------------\n");
+ }
+ printf ("***************************************************************\n");
+}
+#endif
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN EFI_GUID *Guid,
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN EFI_STRING_ID VarName,
+ IN UINT32 VarSize,
+ IN BOOLEAN Flag
+ )
+{
+ if (Guid != NULL) {
+ mGuid = *Guid;
+ } else {
+ memset (&Guid, 0, sizeof (EFI_GUID));
+ }
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ mVarStoreType = EFI_VFR_VARSTORE_EFI;
+ mStorageInfo.mEfiVar.mEfiVarName = VarName;
+ mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
+ mAssignedFlag = Flag;
+}
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN EFI_GUID *Guid,
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN SVfrDataType *DataType,
+ IN BOOLEAN Flag
+ )
+{
+ if (Guid != NULL) {
+ mGuid = *Guid;
+ } else {
+ memset (&Guid, 0, sizeof (EFI_GUID));
+ }
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
+ mStorageInfo.mDataType = DataType;
+ mAssignedFlag = Flag;
+}
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ mVarStoreType = EFI_VFR_VARSTORE_NAME;
+ mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
+ mStorageInfo.mNameSpace.mTableSize = 0;
+}
+
+SVfrVarStorageNode::~SVfrVarStorageNode (
+ VOID
+ )
+{
+ if (mVarStoreName != NULL) {
+ delete mVarStoreName;
+ }
+
+ if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
+ delete mStorageInfo.mNameSpace.mNameTable;
+ }
+}
+
+CVfrDataStorage::CVfrDataStorage (
+ VOID
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
+ mFreeVarStoreIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeVarStoreIdBitMap[0] = 0x80000000;
+
+ mBufferVarStoreList = NULL;
+ mEfiVarStoreList = NULL;
+ mNameVarStoreList = NULL;
+ mCurrVarStorageNode = NULL;
+ mNewVarStorageNode = NULL;
+}
+
+CVfrDataStorage::~CVfrDataStorage (
+ VOID
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ while (mBufferVarStoreList != NULL) {
+ pNode = mBufferVarStoreList;
+ mBufferVarStoreList = mBufferVarStoreList->mNext;
+ delete pNode;
+ }
+ while (mEfiVarStoreList != NULL) {
+ pNode = mEfiVarStoreList;
+ mEfiVarStoreList = mEfiVarStoreList->mNext;
+ delete pNode;
+ }
+ while (mNameVarStoreList != NULL) {
+ pNode = mNameVarStoreList;
+ mNameVarStoreList = mNameVarStoreList->mNext;
+ delete pNode;
+ }
+ if (mNewVarStorageNode != NULL) {
+ delete mNewVarStorageNode;
+ }
+}
+
+EFI_VARSTORE_ID
+CVfrDataStorage::GetFreeVarStoreId (
+ EFI_VFR_VARSTORE_TYPE VarType
+ )
+{
+ UINT32 Index, Mask, Offset;
+
+ //
+ // Assign the different ID range for the different type VarStore to support Framework Vfr
+ //
+ if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
+ Index = 0;
+ } else if (VarType == EFI_VFR_VARSTORE_EFI) {
+ Index = 1;
+ } else if (VarType == EFI_VFR_VARSTORE_NAME) {
+ Index = 2;
+ }
+
+ for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
+ if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
+ break;
+ }
+ }
+
+ for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
+ if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
+ mFreeVarStoreIdBitMap[Index] |= Mask;
+ return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
+ }
+ }
+
+ return EFI_VARSTORE_ID_INVALID;
+}
+
+BOOLEAN
+CVfrDataStorage::ChekVarStoreIdFree (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
+}
+
+VOID
+CVfrDataStorage::MarkVarStoreIdUsed (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
+}
+
+VOID
+CVfrDataStorage::MarkVarStoreIdUnused (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareNameVarStoreBegin (
+ IN CHAR8 *StoreName
+ )
+{
+ SVfrVarStorageNode *pNode = NULL;
+ EFI_VARSTORE_ID VarStoreId;
+
+ if (StoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
+ if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ mNewVarStorageNode = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::NameTableAddItem (
+ IN EFI_STRING_ID Item
+ )
+{
+ EFI_VARSTORE_ID *NewTable, *OldTable;
+ UINT32 TableSize;
+
+ OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
+ TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
+
+ if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
+ if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ memcpy (NewTable, OldTable, TableSize);
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
+ }
+
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareNameVarStoreEnd (
+ IN EFI_GUID *Guid
+ )
+{
+ mNewVarStorageNode->mGuid = *Guid;
+ mNewVarStorageNode->mNext = mNameVarStoreList;
+ mNameVarStoreList = mNewVarStorageNode;
+
+ mNewVarStorageNode = NULL;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareEfiVarStore (
+ IN CHAR8 *StoreName,
+ IN EFI_GUID *Guid,
+ IN EFI_STRING_ID NameStrId,
+ IN UINT32 VarSize,
+ IN BOOLEAN Flag
+ )
+{
+ SVfrVarStorageNode *pNode;
+ EFI_VARSTORE_ID VarStoreId;
+
+ if ((StoreName == NULL) || (Guid == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (VarSize > sizeof (UINT64)) {
+ return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
+ if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNode->mNext = mEfiVarStoreList;
+ mEfiVarStoreList = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareBufferVarStore (
+ IN CHAR8 *StoreName,
+ IN EFI_GUID *Guid,
+ IN CVfrVarDataTypeDB *DataTypeDB,
+ IN CHAR8 *TypeName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN BOOLEAN Flag
+ )
+{
+ SVfrVarStorageNode *pNew = NULL;
+ SVfrDataType *pDataType = NULL;
+
+ if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
+ } else {
+ if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
+ return VFR_RETURN_VARSTOREID_REDEFINED;
+ }
+ MarkVarStoreIdUsed (VarStoreId);
+ }
+
+ if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNew->mNext = mBufferVarStoreList;
+ mBufferVarStoreList = pNew;
+
+ if (gCVfrBufferConfig.Register(StoreName) != 0) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreId (
+ IN CHAR8 *StoreName,
+ OUT EFI_VARSTORE_ID *VarStoreId
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ mCurrVarStorageNode = pNode;
+ *VarStoreId = pNode->mVarStoreId;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ mCurrVarStorageNode = pNode;
+ *VarStoreId = pNode->mVarStoreId;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ mCurrVarStorageNode = pNode;
+ *VarStoreId = pNode->mVarStoreId;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ mCurrVarStorageNode = NULL;
+ *VarStoreId = EFI_VARSTORE_ID_INVALID;
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetBufferVarStoreDataTypeName (
+ IN CHAR8 *StoreName,
+ OUT CHAR8 **DataTypeName
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ if ((StoreName == NULL) || (DataTypeName == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ if (pNode->mStorageInfo.mDataType == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreType (
+ IN CHAR8 *StoreName,
+ OUT EFI_VFR_VARSTORE_TYPE &VarStoreType
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ if (StoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
+ VarStoreType = pNode->mVarStoreType;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
+ VarStoreType = pNode->mVarStoreType;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
+ VarStoreType = pNode->mVarStoreType;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_VARSTORE_TYPE
+CVfrDataStorage::GetVarStoreType (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ SVfrVarStorageNode *pNode;
+ EFI_VFR_VARSTORE_TYPE VarStoreType;
+
+ VarStoreType = EFI_VFR_VARSTORE_INVALID;
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ return VarStoreType;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ return VarStoreType;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreName (
+ IN EFI_VARSTORE_ID VarStoreId,
+ OUT CHAR8 **VarStoreName
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ if (VarStoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ *VarStoreName = NULL;
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetEfiVarStoreInfo (
+ IN OUT EFI_VARSTORE_INFO *Info
+ )
+{
+ if (Info == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (mCurrVarStorageNode == NULL) {
+ return VFR_RETURN_GET_EFIVARSTORE_ERROR;
+ }
+
+ Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
+ Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
+ switch (Info->mVarTotalSize) {
+ case 1:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
+ break;
+ case 2:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
+ break;
+ case 4:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
+ break;
+ case 8:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
+ break;
+ default :
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetNameVarStoreInfo (
+ OUT EFI_VARSTORE_INFO *Info,
+ IN UINT32 Index
+ )
+{
+ if (Info == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (mCurrVarStorageNode == NULL) {
+ return VFR_RETURN_GET_NVVARSTORE_ERROR;
+ }
+
+ //
+ // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
+ //
+ if (VfrCompatibleMode) {
+ if (Index == 0) {
+ return VFR_RETURN_ERROR_ARRARY_NUM;
+ }
+ Index --;
+ }
+
+ Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::BufferVarStoreRequestElementAdd (
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_INFO &Info
+ )
+{
+ CHAR8 NewReqElt[128] = {'\0',};
+ CHAR8 *OldReqElt = NULL;
+ SVfrVarStorageNode *pNode = NULL;
+ EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ gCVfrBufferConfig.Open ();
+ Value.u8 = 0;
+ if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+ gCVfrBufferConfig.Close ();
+
+ return VFR_RETURN_SUCCESS;
+}
+
+SVfrDefaultStoreNode::SVfrDefaultStoreNode (
+ IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId,
+ IN UINT16 DefaultId
+ )
+{
+ mObjBinAddr = ObjBinAddr;
+
+ if (RefName != NULL) {
+ mRefName = new CHAR8[strlen (RefName) + 1];
+ strcpy (mRefName, RefName);
+ } else {
+ mRefName = NULL;
+ }
+
+ mNext = NULL;
+ mDefaultId = DefaultId;
+ mDefaultStoreNameId = DefaultStoreNameId;
+}
+
+SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
+ VOID
+ )
+{
+ if (mRefName != NULL) {
+ delete mRefName;
+ }
+}
+
+CVfrDefaultStore::CVfrDefaultStore (
+ VOID
+ )
+{
+ mDefaultStoreList = NULL;
+}
+
+CVfrDefaultStore::~CVfrDefaultStore (
+ VOID
+ )
+{
+ SVfrDefaultStoreNode *pTmp = NULL;
+
+ while (mDefaultStoreList != NULL) {
+ pTmp = mDefaultStoreList;
+ mDefaultStoreList = mDefaultStoreList->mNext;
+ delete pTmp;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::RegisterDefaultStore (
+ IN CHAR8 *ObjBinAddr,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId,
+ IN UINT16 DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ if (RefName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mRefName, RefName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNode->mNext = mDefaultStoreList;
+ mDefaultStoreList = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+/*
+ * assign new reference name or new default store name id only if
+ * the original is invalid
+ */
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::ReRegisterDefaultStoreById (
+ IN UINT16 DefaultId,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ } else {
+ if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
+ pNode->mDefaultStoreNameId = DefaultStoreNameId;
+ if (pNode->mObjBinAddr != NULL) {
+ pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
+ }
+ } else {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ if (RefName != NULL) {
+ delete pNode->mRefName;
+ pNode->mRefName = new CHAR8[strlen (RefName) + 1];
+ if (pNode->mRefName != NULL) {
+ strcpy (pNode->mRefName, RefName);
+ }
+ }
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+BOOLEAN
+CVfrDefaultStore::DefaultIdRegistered (
+ IN UINT16 DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::GetDefaultId (
+ IN CHAR8 *RefName,
+ OUT UINT16 *DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pTmp = NULL;
+
+ if (DefaultId == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
+ if (strcmp (pTmp->mRefName, RefName) == 0) {
+ *DefaultId = pTmp->mDefaultId;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+STATIC
+EFI_VFR_RETURN_CODE
+AltCfgItemPrintToBuffer (
+ IN CHAR8 *NewAltCfg,
+ IN EFI_VARSTORE_INFO Info,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ UINT32 Index;
+ UINT8 *BufChar = NULL;
+ UINT32 Count = 0;
+
+ if (NewAltCfg != NULL) {
+ Count = sprintf (
+ NewAltCfg,
+ "&OFFSET=%x&WIDTH=%x&VALUE=",
+ Info.mInfo.mVarOffset,
+ Info.mVarTotalSize
+ );
+ NewAltCfg += Count;
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ Count = sprintf (NewAltCfg, "%x", Value.u8);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ Count = sprintf (NewAltCfg, "%x", Value.u16);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ Count = sprintf (NewAltCfg, "%x", Value.u32);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ Count = sprintf (NewAltCfg, "%x", Value.u64);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN :
+ Count = sprintf (NewAltCfg, "%x", Value.b);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_TIME :
+#if 1
+ Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));
+ NewAltCfg += Count;
+#else
+ BufChar = (UINT8 *)&Value.time;
+ for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {
+ Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
+ NewAltCfg += Count;
+ }
+#endif
+ break;
+ case EFI_IFR_TYPE_DATE :
+#if 1
+ Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));
+ NewAltCfg += Count;
+#else
+ BufChar = (UINT8 *)&Value.date;
+ for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {
+ Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
+ NewAltCfg += Count;
+ }
+#endif
+ break;
+ case EFI_IFR_TYPE_STRING :
+ Count = sprintf (NewAltCfg, "%x", Value.string);
+ NewAltCfg += Count;
+ break;
+ case EFI_IFR_TYPE_OTHER :
+ return VFR_RETURN_UNSUPPORTED;
+ }
+ }
+
+ return VFR_RETURN_FATAL_ERROR;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::BufferVarStoreAltConfigAdd (
+ IN EFI_VARSTORE_ID DefaultId,
+ IN EFI_VARSTORE_INFO &Info,
+ IN CHAR8 *VarStoreName,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+ CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
+ INTN Returnvalue = 0;
+
+ if (VarStoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ gCVfrBufferConfig.Open ();
+
+ sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
+ if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {
+ if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
+ goto WriteError;
+ }
+ }
+
+ gCVfrBufferConfig.Close ();
+
+ return VFR_RETURN_SUCCESS;
+
+WriteError:
+ gCVfrBufferConfig.Close ();
+ return (EFI_VFR_RETURN_CODE)Returnvalue;
+}
+
+SVfrRuleNode::SVfrRuleNode (
+ IN CHAR8 *RuleName,
+ IN UINT8 RuleId
+ )
+{
+ if (RuleName != NULL) {
+ mRuleName = new CHAR8[strlen (RuleName) + 1];
+ strcpy (mRuleName, RuleName);
+ } else {
+ mRuleName = NULL;
+ }
+
+ mNext = NULL;
+ mRuleId = RuleId;
+}
+
+SVfrRuleNode::~SVfrRuleNode (
+ VOID
+ )
+{
+ if (mRuleName != NULL) {
+ delete mRuleName;
+ }
+}
+
+CVfrRulesDB::CVfrRulesDB ()
+{
+ mRuleList = NULL;
+ mFreeRuleId = EFI_VARSTORE_ID_START;
+}
+
+CVfrRulesDB::~CVfrRulesDB ()
+{
+ SVfrRuleNode *pNode;
+
+ while(mRuleList != NULL) {
+ pNode = mRuleList;
+ mRuleList = mRuleList->mNext;
+ delete pNode;
+ }
+}
+
+VOID
+CVfrRulesDB::RegisterRule (
+ IN CHAR8 *RuleName
+ )
+{
+ SVfrRuleNode *pNew;
+
+ if (RuleName == NULL) {
+ return ;
+ }
+
+ if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
+ return ;
+ }
+
+ mFreeRuleId++;
+
+ pNew->mNext = mRuleList;
+ mRuleList = pNew;
+}
+
+UINT8
+CVfrRulesDB::GetRuleId (
+ IN CHAR8 *RuleName
+ )
+{
+ SVfrRuleNode *pNode;
+
+ if (RuleName == NULL) {
+ return EFI_RULE_ID_INVALID;
+ }
+
+ for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mRuleName, RuleName) == 0) {
+ return pNode->mRuleId;
+ }
+ }
+
+ return EFI_RULE_ID_INVALID;
+}
+
+CVfrRulesDB gCVfrRulesDB;
+
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
+ VOID
+ )
+{
+ mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ mInfo.mVarName = EFI_STRING_ID_INVALID;
+ mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ mVarType = EFI_IFR_TYPE_OTHER;
+ mVarTotalSize = 0;
+}
+
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
+ IN EFI_VARSTORE_INFO &Info
+ )
+{
+ mVarStoreId = Info.mVarStoreId;
+ mInfo.mVarName = Info.mInfo.mVarName;
+ mInfo.mVarOffset = Info.mInfo.mVarOffset;
+ mVarType = Info.mVarType;
+ mVarTotalSize = Info.mVarTotalSize;
+}
+
+BOOLEAN
+EFI_VARSTORE_INFO::operator == (
+ IN EFI_VARSTORE_INFO *Info
+ )
+{
+ if ((mVarStoreId == Info->mVarStoreId) &&
+ (mInfo.mVarName == Info->mInfo.mVarName) &&
+ (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
+ (mVarType == Info->mVarType) &&
+ (mVarTotalSize == Info->mVarTotalSize)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
+
+EFI_QUESTION_ID
+CVfrQuestionDB::GetFreeQuestionId (
+ VOID
+ )
+{
+ UINT32 Index, Mask, Offset;
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
+ break;
+ }
+ }
+
+ for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
+ if ((mFreeQIdBitMap[Index] & Mask) == 0) {
+ mFreeQIdBitMap[Index] |= Mask;
+ return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
+ }
+ }
+
+ return EFI_QUESTION_ID_INVALID;
+}
+
+BOOLEAN
+CVfrQuestionDB::ChekQuestionIdFree (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
+}
+
+VOID
+CVfrQuestionDB::MarkQuestionIdUsed (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
+}
+
+VOID
+CVfrQuestionDB::MarkQuestionIdUnused (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
+}
+
+SVfrQuestionNode::SVfrQuestionNode (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 BitMask
+ )
+{
+ mName = NULL;
+ mVarIdStr = NULL;
+ mQuestionId = EFI_QUESTION_ID_INVALID;
+ mBitMask = BitMask;
+ mNext = NULL;
+
+ if (Name == NULL) {
+ mName = new CHAR8[strlen ("$DEFAULT") + 1];
+ strcpy (mName, "$DEFAULT");
+ } else {
+ mName = new CHAR8[strlen (Name) + 1];
+ strcpy (mName, Name);
+ }
+
+ if (VarIdStr != NULL) {
+ mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
+ strcpy (mVarIdStr, VarIdStr);
+ } else {
+ mVarIdStr = new CHAR8[strlen ("$") + 1];
+ strcpy (mVarIdStr, "$");
+ }
+}
+
+SVfrQuestionNode::~SVfrQuestionNode (
+ VOID
+ )
+{
+ if (mName != NULL) {
+ delete mName;
+ }
+
+ if (mVarIdStr != NULL) {
+ delete mVarIdStr;
+ }
+}
+
+CVfrQuestionDB::CVfrQuestionDB ()
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ mFreeQIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeQIdBitMap[0] = 0x80000000;
+ mQuestionList = NULL;
+}
+
+CVfrQuestionDB::~CVfrQuestionDB ()
+{
+ SVfrQuestionNode *pNode;
+
+ while (mQuestionList != NULL) {
+ pNode = mQuestionList;
+ mQuestionList = mQuestionList->mNext;
+ delete pNode;
+ }
+}
+
+//
+// Reset to init state
+//
+VOID
+CVfrQuestionDB::ResetInit(
+ IN VOID
+ )
+{
+ UINT32 Index;
+ SVfrQuestionNode *pNode;
+
+ while (mQuestionList != NULL) {
+ pNode = mQuestionList;
+ mQuestionList = mQuestionList->mNext;
+ delete pNode;
+ }
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ mFreeQIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeQIdBitMap[0] = 0x80000000;
+ mQuestionList = NULL;
+}
+
+VOID
+CVfrQuestionDB::PrintAllQuestion (
+ VOID
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::RegisterQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ //
+ // For Framework Vfr, don't check question ID conflict.
+ //
+ if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
+ delete pNode;
+ return VFR_RETURN_QUESTIONID_REDEFINED;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+ pNode->mQuestionId = QuestionId;
+
+ pNode->mNext = mQuestionList;
+ mQuestionList = pNode;
+
+ gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrQuestionDB::RegisterOldDateQuestion (
+ IN CHAR8 *YearVarId,
+ IN CHAR8 *MonthVarId,
+ IN CHAR8 *DayVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Index;
+
+ if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
+ return;
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+ }
+ QuestionId = EFI_QUESTION_ID_INVALID;
+}
+
+VOID
+CVfrQuestionDB::RegisterNewDateQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL) {
+ return;
+ }
+
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".Year");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".Month");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".Day");
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ for (Index = 0; Index < 3; Index++) {
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+}
+
+VOID
+CVfrQuestionDB::RegisterOldTimeQuestion (
+ IN CHAR8 *HourVarId,
+ IN CHAR8 *MinuteVarId,
+ IN CHAR8 *SecondVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Index;
+
+ if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
+ return;
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+ }
+ QuestionId = EFI_QUESTION_ID_INVALID;
+}
+
+VOID
+CVfrQuestionDB::RegisterNewTimeQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL) {
+ return;
+ }
+
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".Hour");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".Minute");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".Second");
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ for (Index = 0; Index < 3; Index++) {
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::UpdateQuestionId (
+ IN EFI_QUESTION_ID QId,
+ IN EFI_QUESTION_ID NewQId
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ if (QId == NewQId) {
+ // don't update
+ return VFR_RETURN_SUCCESS;
+ }
+
+ //
+ // For Framework Vfr, don't check question ID conflict.
+ //
+ if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mQuestionId == QId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ MarkQuestionIdUnused (QId);
+ pNode->mQuestionId = NewQId;
+ MarkQuestionIdUsed (NewQId);
+
+ gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrQuestionDB::GetQuestionId (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ OUT EFI_QUESTION_ID &QuestionId,
+ OUT UINT32 &BitMask
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ QuestionId = EFI_QUESTION_ID_INVALID;
+ BitMask = 0x00000000;
+
+ if ((Name == NULL) && (VarIdStr == NULL)) {
+ return ;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (Name != NULL) {
+ if (strcmp (pNode->mName, Name) != 0) {
+ continue;
+ }
+ }
+
+ if (VarIdStr != NULL) {
+ if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
+ continue;
+ }
+ }
+
+ QuestionId = pNode->mQuestionId;
+ BitMask = pNode->mBitMask;
+ break;
+ }
+
+ return ;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::FindQuestion (
+ IN EFI_QUESTION_ID QuestionId
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mQuestionId == QuestionId) {
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::FindQuestion (
+ IN CHAR8 *Name
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ if (Name == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mName, Name) == 0) {
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+BOOLEAN VfrCompatibleMode = FALSE;
+
+CVfrVarDataTypeDB gCVfrVarDataTypeDB;
+
|