/** @file Vfr common library functions. Copyright (c) 2004 - 2011, 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 CONST 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 CONST 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, (UINT16) 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 { CONST 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++; } 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 ((CHAR8 *)"UINT16", &pYearField->mFieldType); pYearField->mOffset = 0; pYearField->mNext = pMonthField; pYearField->mArrayNum = 0; strcpy (pMonthField->mFieldName, "Month"); GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType); pMonthField->mOffset = 2; pMonthField->mNext = pDayField; pMonthField->mArrayNum = 0; strcpy (pDayField->mFieldName, "Day"); GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType); pDayField->mOffset = 3; 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 ((CHAR8 *)"UINT8", &pHoursField->mFieldType); pHoursField->mOffset = 0; pHoursField->mNext = pMinutesField; pHoursField->mArrayNum = 0; strcpy (pMinutesField->mFieldName, "Minutes"); GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType); pMinutesField->mOffset = 1; pMinutesField->mNext = pSecondsField; pMinutesField->mArrayNum = 0; strcpy (pSecondsField->mFieldName, "Seconds"); GetDataType ((CHAR8 *)"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, NULL, "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, NULL, "Error", "#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, NULL, "Error", "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 = (UINT16) (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 // Index = 0; 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; } if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) { 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; } if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) { 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; EFI_VARSTORE_ID TempVarStoreId; if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) { return VFR_RETURN_FATAL_ERROR; } if (GetVarStoreId (StoreName, &TempVarStoreId) == VFR_RETURN_SUCCESS) { return VFR_RETURN_REDEFINED; } 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::GetVarStoreByDataType ( IN CHAR8 *DataTypeName, OUT SVfrVarStorageNode **VarNode ) { SVfrVarStorageNode *pNode; SVfrVarStorageNode *MatchNode; // // Framework VFR uses Data type name as varstore name, so don't need check again. // if (VfrCompatibleMode) { return VFR_RETURN_UNDEFINED; } MatchNode = NULL; for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) == 0) { if (MatchNode == NULL) { MatchNode = pNode; } else { // // More than one varstores referred the same data structures. // return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR; } } } if (MatchNode == NULL) { return VFR_RETURN_UNDEFINED; } *VarNode = MatchNode; return VFR_RETURN_SUCCESS; } EFI_VFR_RETURN_CODE CVfrDataStorage::GetVarStoreId ( IN CHAR8 *StoreName, OUT EFI_VARSTORE_ID *VarStoreId ) { EFI_VFR_RETURN_CODE ReturnCode; 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; // // Assume that Data strucutre name is used as StoreName, and check again. // ReturnCode = GetVarStoreByDataType (StoreName, &pNode); if (pNode != NULL) { mCurrVarStorageNode = pNode; *VarStoreId = pNode->mVarStoreId; } return ReturnCode; } EFI_VFR_RETURN_CODE CVfrDataStorage::GetBufferVarStoreDataTypeName ( IN CHAR8 *StoreName, OUT CHAR8 **DataTypeName ) { SVfrVarStorageNode *pNode; EFI_VFR_RETURN_CODE ReturnCode; 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; } } ReturnCode = VFR_RETURN_UNDEFINED; // // Assume that Data strucutre name is used as StoreName, and check again. // if (pNode == NULL) { ReturnCode = GetVarStoreByDataType (StoreName, &pNode); } if (pNode == NULL) { return ReturnCode; } 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; EFI_VFR_RETURN_CODE ReturnCode; if (StoreName == NULL) { return VFR_RETURN_FATAL_ERROR; } for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { if (strcmp (pNode->mVarStoreName, StoreName) == 0) { VarStoreType = pNode->mVarStoreType; return VFR_RETURN_SUCCESS; } } for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) { if (strcmp (pNode->mVarStoreName, StoreName) == 0) { VarStoreType = pNode->mVarStoreType; return VFR_RETURN_SUCCESS; } } for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) { if (strcmp (pNode->mVarStoreName, StoreName) == 0) { VarStoreType = pNode->mVarStoreType; return VFR_RETURN_SUCCESS; } } VarStoreType = EFI_VFR_VARSTORE_INVALID; // // Assume that Data strucutre name is used as StoreName, and check again. // ReturnCode = GetVarStoreByDataType (StoreName, &pNode); if (pNode != NULL) { VarStoreType = pNode->mVarStoreType; } return ReturnCode; } 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 ) { SVfrVarStorageNode *pNode = NULL; EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue; EFI_VFR_RETURN_CODE ReturnCode; for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) { if (strcmp (pNode->mVarStoreName, StoreName) == 0) { break; } } ReturnCode = VFR_RETURN_UNDEFINED; // // Assume that Data strucutre name is used as StoreName, and check again. // if (pNode == NULL) { ReturnCode = GetVarStoreByDataType (StoreName, &pNode); } if (pNode == NULL) { return ReturnCode; } 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; } 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; mQtype = QUESTION_NORMAL; 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]->mQtype = QUESTION_DATE; pNode[1]->mQtype = QUESTION_DATE; pNode[2]->mQtype = QUESTION_DATE; 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]->mQtype = QUESTION_DATE; pNode[1]->mQtype = QUESTION_DATE; pNode[2]->mQtype = QUESTION_DATE; 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]->mQtype = QUESTION_TIME; pNode[1]->mQtype = QUESTION_TIME; pNode[2]->mQtype = QUESTION_TIME; 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]->mQtype = QUESTION_TIME; pNode[1]->mQtype = QUESTION_TIME; pNode[2]->mQtype = QUESTION_TIME; 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, OUT EFI_QUESION_TYPE *QType ) { SVfrQuestionNode *pNode; QuestionId = EFI_QUESTION_ID_INVALID; BitMask = 0x00000000; if (QType != NULL) { *QType = QUESTION_NORMAL; } 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; if (QType != NULL) { *QType = pNode->mQtype; } 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;