audk/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrUtilityLib.cpp

2696 lines
63 KiB
C++

#include "stdio.h"
#include "stdlib.h"
#include "VfrUtilityLib.h"
#include "VfrFormPkg.h"
VOID
CVfrBinaryOutput::WriteLine (
IN FILE *pFile,
IN UINT32 LineBytes,
IN INT8 *LineHeader,
IN INT8 *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 INT8 *LineHeader,
IN INT8 *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
)
{
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 INT8 *Id,
IN INT8 *Info
)
{
mId = NULL;
mInfo = NULL;
mInfoStrList = NULL;
mNext = NULL;
if (Id != NULL) {
if ((mId = new INT8[strlen (Id) + 1]) != NULL) {
strcpy (mId, Id);
}
}
if (Info != NULL) {
if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {
strcpy (mInfo, Info);
}
}
}
SConfigItem::SConfigItem (
IN INT8 *Id,
IN INT8 *Info,
IN UINT8 Type,
IN UINT16 Offset,
IN UINT16 Width,
IN EFI_IFR_TYPE_VALUE Value
)
{
mId = NULL;
mInfo = NULL;
mInfoStrList = NULL;
mNext = NULL;
if (Id != NULL) {
if ((mId = new INT8[strlen (Id) + 1]) != NULL) {
strcpy (mId, Id);
}
}
if (Info != NULL) {
if ((mInfo = new INT8[strlen (Info) + 1]) != NULL) {
strcpy (mInfo, Info);
}
}
mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
}
SConfigItem::~SConfigItem (
VOID
)
{
SConfigInfo *Info;
BUFFER_SAFE_FREE (mId);
BUFFER_SAFE_FREE (mInfo);
while (mInfoStrList != NULL) {
Info = mInfoStrList;
mInfoStrList = mInfoStrList->mNext;
BUFFER_SAFE_FREE (Info);
}
}
UINT8
CVfrBufferConfig::Register (
IN INT8 *Id,
IN INT8 *Info
)
{
SConfigItem *pNew;
if (Select (Id) == 0) {
return 1;
}
if ((pNew = new SConfigItem (Id, Info)) == 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 INT8 *Id,
IN INT8 *Info
)
{
SConfigItem *p;
if (Id == NULL) {
mItemListPos = mItemListHead;
return 0;
} else {
for (p = mItemListHead; p != NULL; p = p->mNext) {
if (strcmp (p->mId, Id) != 0) {
continue;
}
if ((p->mInfo != NULL) && (Info != NULL)) {
if (strcmp (p->mInfo, Info) != 0) {
continue;
}
}
mItemListPos = p;
return 0;
}
}
return 1;
}
UINT8
CVfrBufferConfig::Write (
IN CONST CHAR8 Mode,
IN INT8 *Id,
IN INT8 *Info,
IN UINT8 Type,
IN UINT16 Offset,
IN UINT32 Width,
IN EFI_IFR_TYPE_VALUE Value
)
{
UINT8 Ret;
SConfigItem *pItem;
SConfigInfo *pInfo;
switch (Mode) {
case 'a' : // add
if (Select (Id) == 0) {
if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
return 2;
}
pInfo->mNext = mItemListPos->mInfoStrList;
mItemListPos->mInfoStrList = pInfo;
} else {
if ((pItem = new SConfigItem (Id, Info, Type, Offset, Width, Value)) == NULL) {
return 2;
}
if (mItemListHead == NULL) {
mItemListHead = pItem;
mItemListTail = pItem;
} else {
mItemListTail->mNext = pItem;
mItemListTail = pItem;
}
mItemListPos = pItem;
}
break;
case 'd' : // delete
if ((Ret = Select (Id)) != 0) {
return Ret;
}
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 ((Ret = Select (Id)) != 0) {
return Ret;
}
if (mItemListPos->mInfo != NULL) {
delete mItemListPos->mInfo;
}
mItemListPos->mInfo = NULL;
if (Info != NULL) {
if ((mItemListPos->mInfo = new INT8[strlen (Info) + 1]) == NULL) {
return 2;
}
strcpy (mItemListPos->mInfo, Info);
}
break;
default :
return 1;
}
return 0;
}
#if 0
UINT8
CVfrBufferConfig::ReadId (
OUT INT8 **Id,
OUT INT8 **Info
)
{
if (mInfoStrItemListPos == NULL) {
return 1; // end read or some error occur
}
if (Id != NULL) {
*Id = new INT8 (strlen (mInfoStrItemListPos->mId + 1));
strcpy (*Id, mInfoStrItemListPos->mId);
}
if (Info != NULL) {
*Info = new INT8 (strlen (mInfoStrItemListPos->mInfo + 1));
strcpy (*Info, mInfoStrItemListPos->mInfo);
}
return 0;
}
UINT8
CVfrBufferConfig::ReadInfo (
IN INT8 *Id,
IN UINT32 Index,
IN OUT UINT32 &Number,
OUT INT8 *Offset,
OUT INT8 *Width,
OUT INT8 *Value
)
{
UINT8 ret;
SConfigInfo *p;
UINT32 idx;
UINT32 num;
if (Id != NULL) {
if ((ret = Select (Id)) != 0) {
return ret;
}
}
if (mInfoStrItemListPos == NULL) {
return 1; // end read or some error occur
}
p = mInfoStrItemListPos->mInfoStrList;
for (idx = 0; (idx < Index) && (p != NULL); idx++) {
p = p->mNext;
}
if (p == NULL) {
return 1;
}
if (Offset != NULL) {
Offset[0] = '\0';
}
if (Width != NULL) {
Width[0] = '\0';
}
if (Value != NULL) {
Value[0] = '\0';
}
while (num < Number) {
if (Offset != NULL) {
strcat (Offset, p->mOffset);
}
if (Width != NULL) {
strcat (Width, p->mWidth);
}
if (Value != NULL) {
strcat (Value, p->mValue);
}
num++;
if ((p = p->mNext) == NULL) {
break;
}
}
Number = num;
return 0;
}
VOID
CVfrBufferConfig::ReadNext (
VOID
)
{
if (mItemListPos != NULL) {
mItemListPos = mItemListPos->mNext;
}
}
#endif
VOID
CVfrBufferConfig::Close (
VOID
)
{
mItemListPos = NULL;
}
#define BYTES_PRE_LINE 0x10
VOID
CVfrBufferConfig::OutputCFile (
IN FILE *pFile,
IN INT8 *BaseName
)
{
CVfrBinaryOutput Output;
SConfigItem *Item;
SConfigInfo *Info;
UINT32 TotalLen;
if (pFile == NULL) {
return;
}
for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
if (Item->mInfoStrList != NULL) {
fprintf (pFile, "\nunsigned char %s%sDefault%04x[] = {", BaseName, Item->mId, Item->mInfo);
TotalLen = sizeof (UINT32);
for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
TotalLen += Info->mWidth + sizeof (UINT16) * 2;
}
Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&TotalLen, sizeof (UINT32));
for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mOffset, sizeof (UINT16));
Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)&Info->mWidth, sizeof (UINT16));
if (Info->mNext == NULL) {
Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth);
} else {
Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (INT8 *)Info->mValue, Info->mWidth);
}
fprintf (pFile, "\n");
}
fprintf (pFile, "};\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 {
INT8 *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 (UINT8)},
{"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 INT8 *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
INT8 *
TrimHex (
IN INT8 *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 INT8 *Str
)
{
bool IsHex;
UINT32 Value;
INT8 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 INT8 *&VarStr,
OUT INT8 *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 INT8 *&VarStr,
IN INT8 *FName,
OUT UINT32 &ArrayIdx
)
{
UINT32 Idx;
INT8 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 INT8 *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;
}
if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
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;
InternalTypesListInit ();
}
CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
VOID
)
{
SVfrDataType *pType;
SVfrDataField *pField;
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;
}
}
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::Pack (
IN UINT32 Align
)
{
if (Align == 0) {
return VFR_RETURN_INVALID_PARAMETER;
} else if (Align > 1) {
mPackAlign = Align + Align % 2;
} else {
mPackAlign = Align;
}
return VFR_RETURN_SUCCESS;
}
VOID
CVfrVarDataTypeDB::UnPack (
VOID
)
{
mPackAlign = DEFAULT_PACK_ALIGN;
}
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 INT8 *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 INT8 *FieldName,
IN INT8 *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);
mNewDataType = NULL;
}
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::GetDataType (
IN INT8 *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 INT8 *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 INT8 *VarStr,
OUT UINT16 &Offset,
OUT UINT8 &Type,
OUT UINT32 &Size
)
{
INT8 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 INT8 ***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 INT8*[*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 INT8 *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;
}
#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 INT8 *StoreName,
IN EFI_VARSTORE_ID VarStoreId,
IN EFI_STRING_ID VarName,
IN UINT32 VarSize
)
{
if (Guid != NULL) {
mGuid = *Guid;
} else {
memset (&Guid, 0, sizeof (EFI_GUID));
}
if (StoreName != NULL) {
mVarStoreName = new INT8[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;
}
SVfrVarStorageNode::SVfrVarStorageNode (
IN EFI_GUID *Guid,
IN INT8 *StoreName,
IN EFI_VARSTORE_ID VarStoreId,
IN SVfrDataType *DataType
)
{
if (Guid != NULL) {
mGuid = *Guid;
} else {
memset (&Guid, 0, sizeof (EFI_GUID));
}
if (StoreName != NULL) {
mVarStoreName = new INT8[strlen(StoreName) + 1];
strcpy (mVarStoreName, StoreName);
} else {
mVarStoreName = NULL;
}
mNext = NULL;
mVarStoreId = VarStoreId;
mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
mStorageInfo.mDataType = DataType;
}
SVfrVarStorageNode::SVfrVarStorageNode (
IN INT8 *StoreName,
IN EFI_VARSTORE_ID VarStoreId
)
{
if (StoreName != NULL) {
mVarStoreName = new INT8[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 (
VOID
)
{
UINT32 Index, Mask, Offset;
for (Index = 0; 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 INT8 *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 ();
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 INT8 *StoreName,
IN EFI_GUID *Guid,
IN EFI_STRING_ID NameStrId,
IN UINT32 VarSize
)
{
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 ();
if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize)) == NULL) {
return VFR_RETURN_OUT_FOR_RESOURCES;
}
pNode->mNext = mNameVarStoreList;
mNameVarStoreList = pNode;
return VFR_RETURN_SUCCESS;
}
EFI_VFR_RETURN_CODE
CVfrDataStorage::DeclareBufferVarStore (
IN INT8 *StoreName,
IN EFI_GUID *Guid,
IN CVfrVarDataTypeDB *DataTypeDB,
IN INT8 *TypeName,
IN EFI_VARSTORE_ID VarStoreId
)
{
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 ();
} else {
if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
return VFR_RETURN_VARSTOREID_REDEFINED;
}
MarkVarStoreIdUsed (VarStoreId);
}
if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType)) == 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 INT8 *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 INT8 *StoreName,
OUT INT8 **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 INT8 *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_RETURN_CODE
CVfrDataStorage::GetVarStoreName (
IN EFI_VARSTORE_ID VarStoreId,
OUT INT8 **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;
}
Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
return VFR_RETURN_SUCCESS;
}
EFI_VFR_RETURN_CODE
CVfrDataStorage::BufferVarStoreRequestElementAdd (
IN INT8 *StoreName,
IN EFI_VARSTORE_INFO &Info
)
{
INT8 NewReqElt[128] = {'\0',};
INT8 *OldReqElt = NULL;
SVfrVarStorageNode *pNode = NULL;
EFI_IFR_TYPE_VALUE Value;
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 INT8 *RefName,
IN EFI_STRING_ID DefaultStoreNameId,
IN UINT16 DefaultId
)
{
mObjBinAddr = ObjBinAddr;
if (RefName != NULL) {
mRefName = new INT8[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 INT8 *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 INT8 *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 INT8[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 INT8 *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 INT8 *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 INT8 *VarStoreName,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE Value
)
{
SVfrDefaultStoreNode *pNode = NULL;
INT8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {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 ((gCVfrBufferConfig.Select(VarStoreName) == 0) &&
(gCVfrBufferConfig.Select(VarStoreName, NewAltCfg) != 0)) {
if (gCVfrBufferConfig.Write ('i', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
goto WriteError;
}
}
if (gCVfrBufferConfig.Write ('a', VarStoreName, NULL, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
goto WriteError;
}
gCVfrBufferConfig.Close ();
return VFR_RETURN_SUCCESS;
WriteError:
gCVfrBufferConfig.Close ();
return VFR_RETURN_FATAL_ERROR;
}
SVfrRuleNode::SVfrRuleNode (
IN INT8 *RuleName,
IN UINT8 RuleId
)
{
if (RuleName != NULL) {
mRuleName = new INT8[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 INT8 *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 INT8 *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 INT8 *Name,
IN INT8 *VarIdStr,
IN UINT32 BitMask
)
{
mName = NULL;
mVarIdStr = NULL;
mQuestionId = EFI_QUESTION_ID_INVALID;
mBitMask = BitMask;
mNext = NULL;
if (Name == NULL) {
mName = new INT8[strlen ("$DEFAULT") + 1];
strcpy (mName, "$DEFAULT");
} else {
mName = new INT8[strlen (Name) + 1];
strcpy (mName, Name);
}
if (VarIdStr != NULL) {
mVarIdStr = new INT8[strlen (VarIdStr) + 1];
strcpy (mVarIdStr, VarIdStr);
} else {
mVarIdStr = new INT8[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;
}
}
EFI_VFR_RETURN_CODE
CVfrQuestionDB::RegisterQuestion (
IN INT8 *Name,
IN INT8 *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 {
if (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 INT8 *YearVarId,
IN INT8 *MonthVarId,
IN INT8 *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 INT8 *Name,
IN INT8 *BaseVarId,
IN OUT EFI_QUESTION_ID &QuestionId
)
{
SVfrQuestionNode *pNode[3] = {NULL, };
UINT32 Len;
INT8 *VarIdStr[3] = {NULL, };
INT8 Index;
if (BaseVarId == NULL) {
return;
}
Len = strlen (BaseVarId);
VarIdStr[0] = new INT8[Len + strlen (".Year") + 1];
if (VarIdStr[0] != NULL) {
strcpy (VarIdStr[0], BaseVarId);
strcat (VarIdStr[0], ".Year");
}
VarIdStr[1] = new INT8[Len + strlen (".Month") + 1];
if (VarIdStr[1] != NULL) {
strcpy (VarIdStr[1], BaseVarId);
strcat (VarIdStr[1], ".Month");
}
VarIdStr[2] = new INT8[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 INT8 *HourVarId,
IN INT8 *MinuteVarId,
IN INT8 *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 INT8 *Name,
IN INT8 *BaseVarId,
IN OUT EFI_QUESTION_ID &QuestionId
)
{
SVfrQuestionNode *pNode[3] = {NULL, };
UINT32 Len;
INT8 *VarIdStr[3] = {NULL, };
INT8 Index;
if (BaseVarId == NULL) {
return;
}
Len = strlen (BaseVarId);
VarIdStr[0] = new INT8[Len + strlen (".Hour") + 1];
if (VarIdStr[0] != NULL) {
strcpy (VarIdStr[0], BaseVarId);
strcat (VarIdStr[0], ".Hour");
}
VarIdStr[1] = new INT8[Len + strlen (".Minute") + 1];
if (VarIdStr[1] != NULL) {
strcpy (VarIdStr[1], BaseVarId);
strcat (VarIdStr[1], ".Minute");
}
VarIdStr[2] = new INT8[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 (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 INT8 *Name,
IN INT8 *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 INT8 *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;
}