/** @file\r
- \r
+\r
Vfr common library functions.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "stdio.h"\r
#include "stdlib.h"\r
+#include "assert.h"\r
+#include "CommonLib.h"\r
#include "VfrUtilityLib.h"\r
#include "VfrFormPkg.h"\r
\r
}\r
\r
SConfigInfo::SConfigInfo (\r
- IN UINT8 Type, \r
- IN UINT16 Offset, \r
- IN UINT32 Width, \r
+ IN UINT8 Type,\r
+ IN UINT16 Offset,\r
+ IN UINT32 Width,\r
IN EFI_IFR_TYPE_VALUE Value\r
)\r
{\r
case EFI_IFR_TYPE_STRING :\r
memcpy (mValue, &Value.string, mWidth);\r
break;\r
+ case EFI_IFR_TYPE_BUFFER :\r
+ memcpy (mValue, &Value.u8, mWidth);\r
+ break;\r
+\r
case EFI_IFR_TYPE_OTHER :\r
return;\r
}\r
VOID\r
)\r
{\r
- BUFFER_SAFE_FREE (mValue);\r
+ ARRAY_SAFE_FREE (mValue);\r
}\r
\r
SConfigItem::SConfigItem (\r
IN CHAR8 *Name,\r
+ IN EFI_GUID *Guid,\r
IN CHAR8 *Id\r
)\r
{\r
mName = NULL;\r
- mId = 0;\r
+ mGuid = NULL;\r
+ mId = NULL;\r
mInfoStrList = NULL;\r
mNext = NULL;\r
\r
}\r
}\r
\r
+ if (Guid != NULL) {\r
+ if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {\r
+ memcpy (mGuid, Guid, sizeof (EFI_GUID));\r
+ }\r
+ }\r
+\r
if (Id != NULL) {\r
if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
strcpy (mId, Id);\r
\r
SConfigItem::SConfigItem (\r
IN CHAR8 *Name,\r
+ IN EFI_GUID *Guid,\r
IN CHAR8 *Id,\r
IN UINT8 Type,\r
IN UINT16 Offset,\r
)\r
{\r
mName = NULL;\r
+ mGuid = NULL;\r
mId = NULL;\r
mInfoStrList = NULL;\r
mNext = NULL;\r
}\r
}\r
\r
+ if (Guid != NULL) {\r
+ if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {\r
+ memcpy (mGuid, Guid, sizeof (EFI_GUID));\r
+ }\r
+ }\r
+\r
if (Id != NULL) {\r
if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
strcpy (mId, Id);\r
{\r
SConfigInfo *Info;\r
\r
- BUFFER_SAFE_FREE (mName);\r
- BUFFER_SAFE_FREE (mId);\r
+ ARRAY_SAFE_FREE (mName);\r
+ ARRAY_SAFE_FREE (mGuid);\r
+ ARRAY_SAFE_FREE (mId);\r
while (mInfoStrList != NULL) {\r
Info = mInfoStrList;\r
mInfoStrList = mInfoStrList->mNext;\r
UINT8\r
CVfrBufferConfig::Register (\r
IN CHAR8 *Name,\r
+ IN EFI_GUID *Guid,\r
IN CHAR8 *Id\r
)\r
{\r
SConfigItem *pNew;\r
\r
- if (Select (Name) == 0) {\r
+ if (Select (Name, Guid) == 0) {\r
return 1;\r
}\r
\r
- if ((pNew = new SConfigItem (Name, Id)) == NULL) {\r
+ if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {\r
return 2;\r
}\r
+\r
if (mItemListHead == NULL) {\r
mItemListHead = pNew;\r
mItemListTail = pNew;\r
\r
UINT8\r
CVfrBufferConfig::Select (\r
- IN CHAR8 *Name,\r
- IN CHAR8 *Id\r
+ IN CHAR8 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN CHAR8 *Id\r
)\r
{\r
SConfigItem *p;\r
\r
- if (Name == NULL) {\r
+ if (Name == NULL || Guid == NULL) {\r
mItemListPos = mItemListHead;\r
return 0;\r
} else {\r
for (p = mItemListHead; p != NULL; p = p->mNext) {\r
- if (strcmp (p->mName, Name) != 0) {\r
+ if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {\r
continue;\r
}\r
\r
CVfrBufferConfig::Write (\r
IN CONST CHAR8 Mode,\r
IN CHAR8 *Name,\r
+ IN EFI_GUID *Guid,\r
IN CHAR8 *Id,\r
IN UINT8 Type,\r
IN UINT16 Offset,\r
SConfigItem *pItem;\r
SConfigInfo *pInfo;\r
\r
- if ((Ret = Select (Name)) != 0) {\r
+ if ((Ret = Select (Name, Guid)) != 0) {\r
return Ret;\r
}\r
\r
switch (Mode) {\r
case 'a' : // add\r
- if (Select (Name, Id) != 0) {\r
- if ((pItem = new SConfigItem (Name, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {\r
+ if (Select (Name, Guid, Id) != 0) {\r
+ if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {\r
return 2;\r
}\r
if (mItemListHead == NULL) {\r
// tranverse the list to find out if there's already the value for the same offset\r
for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {\r
if (pInfo->mOffset == Offset) {\r
- // check if the value and width are the same; return error if not\r
- if ((Id != NULL) && (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0)) {\r
- return VFR_RETURN_DEFAULT_VALUE_REDEFINED;\r
- }\r
return 0;\r
}\r
}\r
\r
case 'i' : // set info\r
if (mItemListPos->mId != NULL) {\r
- delete mItemListPos->mId;\r
+ delete[] mItemListPos->mId;\r
}\r
mItemListPos->mId = NULL;\r
if (Id != NULL) {\r
{"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},\r
{"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},\r
{"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},\r
+ {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},\r
{NULL, EFI_IFR_TYPE_OTHER, 0, 0}\r
};\r
\r
//\r
// BUG: does not handle overflow here\r
//\r
- (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
\r
if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
Value += (c - 'a' + 10);\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
+/**\r
+ Check whether the DataType contain bit field.\r
+\r
+ @param TypeName The name of the type.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::DataTypeHasBitField (\r
+ IN CHAR8 *TypeName\r
+ )\r
+{\r
+ SVfrDataType *pType = NULL;\r
+ SVfrDataField *pTmp;\r
+\r
+ GetDataType (TypeName, &pType);\r
+\r
+ if (pType == NULL){\r
+ return FALSE;\r
+ }\r
+ for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {\r
+ if (pTmp->mIsBitField) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check whether the field is bit field or not.\r
+\r
+ @param VarStr Point to the field name which may contain the structure name.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::IsThisBitField (\r
+ IN CHAR8 *VarStr\r
+ )\r
+{\r
+ CHAR8 FName[MAX_NAME_LEN];\r
+ CHAR8 TName[MAX_NAME_LEN];\r
+ UINT32 ArrayIdx;\r
+ SVfrDataType *pType = NULL;\r
+ SVfrDataField *pField = NULL;\r
+\r
+ CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
+\r
+ while (*VarStr != '\0') {\r
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
+ pType = pField->mFieldType;\r
+ }\r
+ if (pField != NULL && pField->mIsBitField) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
EFI_VFR_RETURN_CODE\r
CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
IN CHAR8 *&VarStr,\r
if (*VarStr == ']') {\r
VarStr++;\r
}\r
+ if (*VarStr == '.') {\r
+ VarStr++;\r
+ }\r
return VFR_RETURN_SUCCESS;\r
case ']':\r
return VFR_RETURN_DATA_STRING_ERROR;\r
\r
EFI_VFR_RETURN_CODE\r
CVfrVarDataTypeDB::GetTypeField (\r
- IN CHAR8 *FName,\r
+ IN CONST CHAR8 *FName,\r
IN SVfrDataType *Type,\r
OUT SVfrDataField *&Field\r
)\r
{\r
SVfrDataField *pField = NULL;\r
\r
- if ((FName == NULL) && (Type == NULL)) {\r
+ if ((FName == NULL) || (Type == NULL)) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
\r
for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
+ //\r
+ // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,\r
+ // add code to adjust it.\r
+ //\r
+ if (Type->mType == EFI_IFR_TYPE_TIME) {\r
+ if (strcmp (FName, "Hour") == 0) {\r
+ FName = "Hours";\r
+ } else if (strcmp (FName, "Minute") == 0) {\r
+ FName = "Minuts";\r
+ } else if (strcmp (FName, "Second") == 0) {\r
+ FName = "Seconds";\r
+ }\r
+ }\r
+\r
if (strcmp (pField->mFieldName, FName) == 0) {\r
Field = pField;\r
return VFR_RETURN_SUCCESS;\r
CVfrVarDataTypeDB::GetFieldOffset (\r
IN SVfrDataField *Field,\r
IN UINT32 ArrayIdx,\r
- OUT UINT32 &Offset\r
+ OUT UINT32 &Offset,\r
+ IN BOOLEAN IsBitField\r
)\r
{\r
if (Field == NULL) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
- \r
+\r
//\r
// Framework Vfr file Array Index is from 1.\r
// But Uefi Vfr file Array Index is from 0.\r
if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
return VFR_RETURN_ERROR_ARRARY_NUM;\r
}\r
- \r
+\r
//\r
// Be compatible with the current usage\r
// If ArraryIdx is not specified, the first one is used.\r
// return VFR_RETURN_ERROR_ARRARY_NUM;\r
// }\r
//\r
-\r
- Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+ if (IsBitField) {\r
+ Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;\r
+ } else {\r
+ Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+ }\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
UINT32\r
CVfrVarDataTypeDB::GetFieldSize (\r
IN SVfrDataField *Field,\r
- IN UINT32 ArrayIdx\r
+ IN UINT32 ArrayIdx,\r
+ IN BOOLEAN BitField\r
)\r
{\r
if (Field == NULL) {\r
}\r
\r
if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
- return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
+ return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
} else {\r
- return Field->mFieldType->mTotalSize;\r
+ if (BitField) {\r
+ return Field->mBitWidth;\r
+ } else {\r
+ return Field->mFieldType->mTotalSize;\r
+ }\r
}\r
}\r
\r
for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
New = new SVfrDataType;\r
if (New != NULL) {\r
- strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
+ assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN);\r
+ strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1);\r
+ New->mTypeName[MAX_NAME_LEN - 1] = 0;\r
New->mType = gInternalTypesTable[Index].mType;\r
New->mAlign = gInternalTypesTable[Index].mAlign;\r
New->mTotalSize = gInternalTypesTable[Index].mSize;\r
pYearField->mOffset = 0;\r
pYearField->mNext = pMonthField;\r
pYearField->mArrayNum = 0;\r
+ pYearField->mIsBitField = FALSE;\r
\r
strcpy (pMonthField->mFieldName, "Month");\r
GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);\r
pMonthField->mOffset = 2;\r
pMonthField->mNext = pDayField;\r
pMonthField->mArrayNum = 0;\r
+ pMonthField->mIsBitField = FALSE;\r
\r
strcpy (pDayField->mFieldName, "Day");\r
GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);\r
pDayField->mOffset = 3;\r
pDayField->mNext = NULL;\r
pDayField->mArrayNum = 0;\r
+ pDayField->mIsBitField = FALSE;\r
\r
New->mMembers = pYearField;\r
} else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
pHoursField->mOffset = 0;\r
pHoursField->mNext = pMinutesField;\r
pHoursField->mArrayNum = 0;\r
+ pHoursField->mIsBitField = FALSE;\r
\r
strcpy (pMinutesField->mFieldName, "Minutes");\r
GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);\r
pMinutesField->mOffset = 1;\r
pMinutesField->mNext = pSecondsField;\r
pMinutesField->mArrayNum = 0;\r
+ pMinutesField->mIsBitField = FALSE;\r
\r
strcpy (pSecondsField->mFieldName, "Seconds");\r
GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);\r
pSecondsField->mOffset = 2;\r
pSecondsField->mNext = NULL;\r
pSecondsField->mArrayNum = 0;\r
+ pSecondsField->mIsBitField = FALSE;\r
\r
New->mMembers = pHoursField;\r
+ } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {\r
+ SVfrDataField *pQuestionIdField = new SVfrDataField;\r
+ SVfrDataField *pFormIdField = new SVfrDataField;\r
+ SVfrDataField *pFormSetGuidField = new SVfrDataField;\r
+ SVfrDataField *pDevicePathField = new SVfrDataField;\r
+\r
+ strcpy (pQuestionIdField->mFieldName, "QuestionId");\r
+ GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);\r
+ pQuestionIdField->mOffset = 0;\r
+ pQuestionIdField->mNext = pFormIdField;\r
+ pQuestionIdField->mArrayNum = 0;\r
+ pQuestionIdField->mIsBitField = FALSE;\r
+\r
+ strcpy (pFormIdField->mFieldName, "FormId");\r
+ GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);\r
+ pFormIdField->mOffset = 2;\r
+ pFormIdField->mNext = pFormSetGuidField;\r
+ pFormIdField->mArrayNum = 0;\r
+ pFormIdField->mIsBitField = FALSE;\r
+\r
+ strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");\r
+ GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);\r
+ pFormSetGuidField->mOffset = 4;\r
+ pFormSetGuidField->mNext = pDevicePathField;\r
+ pFormSetGuidField->mArrayNum = 0;\r
+ pFormSetGuidField->mIsBitField = FALSE;\r
+\r
+ strcpy (pDevicePathField->mFieldName, "DevicePath");\r
+ GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);\r
+ pDevicePathField->mOffset = 20;\r
+ pDevicePathField->mNext = NULL;\r
+ pDevicePathField->mArrayNum = 0;\r
+ pDevicePathField->mIsBitField = FALSE;\r
+\r
+ New->mMembers = pQuestionIdField;\r
} else {\r
New->mMembers = NULL;\r
}\r
mPackAlign = DEFAULT_PACK_ALIGN;\r
mPackStack = NULL;\r
mFirstNewDataTypeName = NULL;\r
+ mCurrDataType = NULL;\r
\r
InternalTypesListInit ();\r
}\r
pType->mMembers = pType->mMembers->mNext;\r
delete pField;\r
}\r
- delete pType;\r
+ delete pType;\r
}\r
\r
while (mPackStack != NULL) {\r
pNewType->mTotalSize = 0;\r
pNewType->mMembers = NULL;\r
pNewType->mNext = NULL;\r
+ pNewType->mHasBitField = FALSE;\r
\r
mNewDataType = pNewType;\r
}\r
}\r
}\r
\r
- strcpy(mNewDataType->mTypeName, TypeName);\r
+ strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);\r
+ mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;\r
+ return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Record the bit field info in the data type.\r
+\r
+ @param FieldName Point to the field name.\r
+ @param TypeName Point to the type name.\r
+ @param Width The bit width.\r
+ @param FieldInUnion The filed is in Union type or Structure type.\r
+\r
+**/\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::DataTypeAddBitField (\r
+ IN CHAR8 *FieldName,\r
+ IN CHAR8 *TypeName,\r
+ IN UINT32 Width,\r
+ IN BOOLEAN FieldInUnion\r
+ )\r
+{\r
+ SVfrDataField *pNewField = NULL;\r
+ SVfrDataType *pFieldType = NULL;\r
+ SVfrDataField *pTmp;\r
+ UINT32 Align;\r
+ UINT32 MaxDataTypeSize;\r
+ BOOLEAN UpdateTotalSize;\r
+\r
+ CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+\r
+ if (Width > MAX_BIT_WIDTH) {\r
+ return VFR_RETURN_BIT_WIDTH_ERROR;\r
+ }\r
+\r
+ if (Width > pFieldType->mTotalSize * 8) {\r
+ return VFR_RETURN_BIT_WIDTH_ERROR;\r
+ }\r
+\r
+ if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {\r
+ return VFR_RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == 0 && FieldName != NULL) {\r
+ return VFR_RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
+ if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {\r
+ return VFR_RETURN_REDEFINED;\r
+ }\r
+ }\r
+\r
+ Align = MIN (mPackAlign, pFieldType->mAlign);\r
+ UpdateTotalSize = FALSE;\r
+\r
+ if ((pNewField = new SVfrDataField) == NULL) {\r
+ return VFR_RETURN_OUT_FOR_RESOURCES;\r
+ }\r
+\r
+ MaxDataTypeSize = mNewDataType->mTotalSize;\r
+ if (FieldName != NULL) {\r
+ strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
+ pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
+ }\r
+ pNewField->mFieldType = pFieldType;\r
+ pNewField->mIsBitField = TRUE;\r
+ pNewField->mBitWidth = Width;\r
+ pNewField->mArrayNum = 0;\r
+ pNewField->mBitOffset = 0;\r
+ pNewField->mOffset = 0;\r
+\r
+ if (mNewDataType->mMembers == NULL) {\r
+ mNewDataType->mMembers = pNewField;\r
+ pNewField->mNext = NULL;\r
+ } else {\r
+ for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
+ ;\r
+ pTmp->mNext = pNewField;\r
+ pNewField->mNext = NULL;\r
+ }\r
+\r
+ if (FieldInUnion) {\r
+ pNewField->mOffset = 0;\r
+ if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
+ mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
+ }\r
+ } else {\r
+ //\r
+ // Check whether the bit fields can be contained within one FieldType.\r
+ //\r
+ if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&\r
+ (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {\r
+ pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;\r
+ pNewField->mOffset = pTmp->mOffset;\r
+ //\r
+ // If BitWidth=0,used to force alignment at the next word boundary.\r
+ // So make this bit field occupy the remaing bit width of current field type.\r
+ //\r
+ if (pNewField->mBitWidth == 0) {\r
+ pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);\r
+ }\r
+ } else {\r
+ //\r
+ // The bit filed start a new memory\r
+ //\r
+ pNewField->mBitOffset = mNewDataType->mTotalSize * 8;\r
+ UpdateTotalSize = TRUE;\r
+ }\r
+ }\r
+\r
+ if (UpdateTotalSize){\r
+ if ((mNewDataType->mTotalSize % Align) == 0) {\r
+ pNewField->mOffset = mNewDataType->mTotalSize;\r
+ } else {\r
+ pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
+ }\r
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);\r
+ }\r
+\r
+ mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
+ mNewDataType->mHasBitField = TRUE;\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
CVfrVarDataTypeDB::DataTypeAddField (\r
IN CHAR8 *FieldName,\r
IN CHAR8 *TypeName,\r
- IN UINT32 ArrayNum\r
+ IN UINT32 ArrayNum,\r
+ IN BOOLEAN FieldInUnion\r
)\r
{\r
SVfrDataField *pNewField = NULL;\r
SVfrDataType *pFieldType = NULL;\r
SVfrDataField *pTmp;\r
UINT32 Align;\r
+ UINT32 MaxDataTypeSize;\r
\r
CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+ MaxDataTypeSize = mNewDataType->mTotalSize;\r
\r
if (strlen (FieldName) >= MAX_NAME_LEN) {\r
return VFR_RETURN_INVALID_PARAMETER;\r
if ((pNewField = new SVfrDataField) == NULL) {\r
return VFR_RETURN_OUT_FOR_RESOURCES;\r
}\r
- strcpy (pNewField->mFieldName, FieldName);\r
+ strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
+ pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
pNewField->mFieldType = pFieldType;\r
pNewField->mArrayNum = ArrayNum;\r
+ pNewField->mIsBitField = FALSE;\r
if ((mNewDataType->mTotalSize % Align) == 0) {\r
pNewField->mOffset = mNewDataType->mTotalSize;\r
} else {\r
}\r
\r
mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
- mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
+\r
+ if (FieldInUnion) {\r
+ if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
+ mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
+ }\r
+ pNewField->mOffset = 0;\r
+ } else {\r
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
+ }\r
\r
return VFR_RETURN_SUCCESS;\r
}\r
IN CHAR8 *VarStr,\r
OUT UINT16 &Offset,\r
OUT UINT8 &Type,\r
- OUT UINT32 &Size\r
+ OUT UINT32 &Size,\r
+ OUT BOOLEAN &BitField\r
)\r
{\r
CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
UINT32 ArrayIdx, Tmp;\r
SVfrDataType *pType = NULL;\r
SVfrDataField *pField = NULL;\r
+ CHAR8 *VarStrName;\r
\r
Offset = 0;\r
Type = EFI_IFR_TYPE_OTHER;\r
Size = 0;\r
+ VarStrName = VarStr;\r
\r
CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
\r
+ BitField = IsThisBitField (VarStrName);\r
+\r
//\r
// if it is not struct data type\r
//\r
Size = pType->mTotalSize;\r
\r
while (*VarStr != '\0') {\r
- CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
pType = pField->mFieldType;\r
- CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
- Offset = (UINT16) (Offset + Tmp);\r
+ CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);\r
+ if (BitField && !pField->mIsBitField) {\r
+ Offset = (UINT16) (Offset + Tmp * 8);\r
+ } else {\r
+ Offset = (UINT16) (Offset + Tmp);\r
+ }\r
Type = GetFieldWidth (pField);\r
- Size = GetFieldSize (pField, ArrayIdx);\r
+ Size = GetFieldSize (pField, ArrayIdx, BitField);\r
}\r
return VFR_RETURN_SUCCESS;\r
}\r
fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);\r
for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
if (pFNode->mArrayNum > 0) {\r
- fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
+ fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,\r
pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);\r
} else {\r
- fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
+ fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,\r
pFNode->mFieldName, pFNode->mFieldType->mTypeName);\r
}\r
}\r
printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
}\r
printf ("\t\t};\n");\r
- printf ("---------------------------------------------------------------\n");\r
+ printf ("---------------------------------------------------------------\n");\r
}\r
printf ("***************************************************************\n");\r
}\r
if (Guid != NULL) {\r
mGuid = *Guid;\r
} else {\r
- memset (&Guid, 0, sizeof (EFI_GUID));\r
+ memset (&mGuid, 0, sizeof (EFI_GUID));\r
}\r
if (StoreName != NULL) {\r
mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
IN CHAR8 *StoreName,\r
IN EFI_VARSTORE_ID VarStoreId,\r
IN SVfrDataType *DataType,\r
+ IN BOOLEAN BitsVarstore,\r
IN BOOLEAN Flag\r
)\r
{\r
if (Guid != NULL) {\r
mGuid = *Guid;\r
} else {\r
- memset (&Guid, 0, sizeof (EFI_GUID));\r
+ memset (&mGuid, 0, sizeof (EFI_GUID));\r
}\r
if (StoreName != NULL) {\r
mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
}\r
mNext = NULL;\r
mVarStoreId = VarStoreId;\r
- mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
+ if (BitsVarstore) {\r
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;\r
+ } else {\r
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
+ }\r
mStorageInfo.mDataType = DataType;\r
mAssignedFlag = Flag;\r
}\r
IN EFI_VARSTORE_ID VarStoreId\r
)\r
{\r
+ memset (&mGuid, 0, sizeof (EFI_GUID));\r
if (StoreName != NULL) {\r
mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
strcpy (mVarStoreName, StoreName);\r
mVarStoreType = EFI_VFR_VARSTORE_NAME;\r
mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
mStorageInfo.mNameSpace.mTableSize = 0;\r
+ mAssignedFlag = FALSE;\r
}\r
\r
SVfrVarStorageNode::~SVfrVarStorageNode (\r
)\r
{\r
if (mVarStoreName != NULL) {\r
- delete mVarStoreName;\r
+ delete[] mVarStoreName;\r
}\r
\r
if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
- delete mStorageInfo.mNameSpace.mNameTable;\r
+ delete[] mStorageInfo.mNameSpace.mNameTable;\r
}\r
}\r
\r
mNameVarStoreList = NULL;\r
mCurrVarStorageNode = NULL;\r
mNewVarStorageNode = NULL;\r
+ mBufferFieldInfoListHead = NULL;\r
+ mBufferFieldInfoListTail = NULL;\r
}\r
\r
CVfrDataStorage::~CVfrDataStorage (\r
)\r
{\r
UINT32 Index, Mask, Offset;\r
- \r
+\r
//\r
// Assign the different ID range for the different type VarStore to support Framework Vfr\r
//\r
}\r
}\r
\r
+ if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {\r
+ return EFI_VARSTORE_ID_INVALID;\r
+ }\r
+\r
for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
mFreeVarStoreIdBitMap[Index] |= Mask;\r
\r
EFI_VFR_RETURN_CODE\r
CVfrDataStorage::DeclareNameVarStoreBegin (\r
- IN CHAR8 *StoreName\r
+ IN CHAR8 *StoreName,\r
+ IN EFI_VARSTORE_ID VarStoreId\r
)\r
{\r
SVfrVarStorageNode *pNode = NULL;\r
- EFI_VARSTORE_ID VarStoreId;\r
+ EFI_VARSTORE_ID TmpVarStoreId;\r
\r
if (StoreName == NULL) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
\r
- for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- return VFR_RETURN_REDEFINED;\r
+ if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {\r
+ return VFR_RETURN_REDEFINED;\r
+ }\r
+\r
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
+ } else {\r
+ if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
+ return VFR_RETURN_VARSTOREID_REDEFINED;\r
}\r
+ MarkVarStoreIdUsed (VarStoreId);\r
}\r
\r
- VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
return VFR_RETURN_UNDEFINED;\r
}\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
-EFI_VFR_RETURN_CODE \r
+EFI_VFR_RETURN_CODE\r
CVfrDataStorage::DeclareEfiVarStore (\r
- IN CHAR8 *StoreName, \r
- IN EFI_GUID *Guid, \r
+ IN CHAR8 *StoreName,\r
+ IN EFI_GUID *Guid,\r
IN EFI_STRING_ID NameStrId,\r
IN UINT32 VarSize,\r
IN BOOLEAN Flag\r
return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
}\r
\r
- for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- return VFR_RETURN_REDEFINED;\r
- }\r
+ if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
+ return VFR_RETURN_REDEFINED;\r
}\r
\r
VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
-EFI_VFR_RETURN_CODE \r
+EFI_VFR_RETURN_CODE\r
CVfrDataStorage::DeclareBufferVarStore (\r
- IN CHAR8 *StoreName, \r
- IN EFI_GUID *Guid, \r
+ IN CHAR8 *StoreName,\r
+ IN EFI_GUID *Guid,\r
IN CVfrVarDataTypeDB *DataTypeDB,\r
IN CHAR8 *TypeName,\r
IN EFI_VARSTORE_ID VarStoreId,\r
+ IN BOOLEAN IsBitVarStore,\r
IN BOOLEAN Flag\r
)\r
{\r
SVfrVarStorageNode *pNew = NULL;\r
SVfrDataType *pDataType = NULL;\r
+ EFI_VARSTORE_ID TempVarStoreId;\r
\r
if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
\r
+ if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
+ return VFR_RETURN_REDEFINED;\r
+ }\r
+\r
CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
\r
if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
MarkVarStoreIdUsed (VarStoreId);\r
}\r
\r
- if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
+ if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {\r
return VFR_RETURN_OUT_FOR_RESOURCES;\r
}\r
\r
pNew->mNext = mBufferVarStoreList;\r
mBufferVarStoreList = pNew;\r
\r
- if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
+ if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
-EFI_VFR_RETURN_CODE \r
-CVfrDataStorage::GetVarStoreId (\r
- IN CHAR8 *StoreName,\r
- OUT EFI_VARSTORE_ID *VarStoreId\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetVarStoreByDataType (\r
+ IN CHAR8 *DataTypeName,\r
+ OUT SVfrVarStorageNode **VarNode,\r
+ IN EFI_GUID *VarGuid\r
)\r
{\r
SVfrVarStorageNode *pNode;\r
+ SVfrVarStorageNode *MatchNode;\r
+\r
+ //\r
+ // Framework VFR uses Data type name as varstore name, so don't need check again.\r
+ //\r
+ if (VfrCompatibleMode) {\r
+ return VFR_RETURN_UNDEFINED;\r
+ }\r
\r
+ MatchNode = NULL;\r
for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- mCurrVarStorageNode = pNode;\r
- *VarStoreId = pNode->mVarStoreId;\r
- return VFR_RETURN_SUCCESS;\r
+ if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {\r
+ continue;\r
}\r
- }\r
\r
- for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- mCurrVarStorageNode = pNode;\r
- *VarStoreId = pNode->mVarStoreId;\r
- return VFR_RETURN_SUCCESS;\r
+ if ((VarGuid != NULL)) {\r
+ if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
+ *VarNode = pNode;\r
+ return VFR_RETURN_SUCCESS;\r
+ }\r
+ } else {\r
+ if (MatchNode == NULL) {\r
+ MatchNode = pNode;\r
+ } else {\r
+ //\r
+ // More than one varstores referred the same data structures.\r
+ //\r
+ return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;\r
+ }\r
}\r
}\r
\r
- for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+ if (MatchNode == NULL) {\r
+ return VFR_RETURN_UNDEFINED;\r
+ }\r
+\r
+ *VarNode = MatchNode;\r
+ return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VARSTORE_ID\r
+CVfrDataStorage::CheckGuidField (\r
+ IN SVfrVarStorageNode *pNode,\r
+ IN EFI_GUID *StoreGuid,\r
+ IN BOOLEAN *HasFoundOne,\r
+ OUT EFI_VFR_RETURN_CODE *ReturnCode\r
+ )\r
+{\r
+ if (StoreGuid != NULL) {\r
+ //\r
+ // If has guid info, compare the guid filed.\r
+ //\r
+ if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
+ //\r
+ // Both name and guid are same, this this varstore.\r
+ //\r
mCurrVarStorageNode = pNode;\r
- *VarStoreId = pNode->mVarStoreId;\r
- return VFR_RETURN_SUCCESS;\r
+ *ReturnCode = VFR_RETURN_SUCCESS;\r
+ return TRUE;\r
+ }\r
+ } else {\r
+ //\r
+ // Not has Guid field, check whether this name is the only one.\r
+ //\r
+ if (*HasFoundOne) {\r
+ //\r
+ // The name has conflict, return name redefined.\r
+ //\r
+ *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;\r
+ return TRUE;\r
}\r
+\r
+ *HasFoundOne = TRUE;\r
+ mCurrVarStorageNode = pNode;\r
}\r
\r
- mCurrVarStorageNode = NULL;\r
- *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
- return VFR_RETURN_UNDEFINED;\r
+ return FALSE;\r
}\r
\r
+/**\r
+ Base on the input store name and guid to find the varstore id.\r
+\r
+ If both name and guid are inputed, base on the name and guid to\r
+ found the varstore. If only name inputed, base on the name to\r
+ found the varstore and go on to check whether more than one varstore\r
+ has the same name. If only has found one varstore, return this\r
+ varstore; if more than one varstore has same name, return varstore\r
+ name redefined error. If no varstore found by varstore name, call\r
+ function GetVarStoreByDataType and use inputed varstore name as\r
+ data type name to search.\r
+**/\r
EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
- IN CHAR8 *StoreName,\r
- OUT CHAR8 **DataTypeName\r
+CVfrDataStorage::GetVarStoreId (\r
+ IN CHAR8 *StoreName,\r
+ OUT EFI_VARSTORE_ID *VarStoreId,\r
+ IN EFI_GUID *StoreGuid\r
)\r
{\r
+ EFI_VFR_RETURN_CODE ReturnCode;\r
SVfrVarStorageNode *pNode;\r
+ BOOLEAN HasFoundOne = FALSE;\r
\r
- if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
- return VFR_RETURN_FATAL_ERROR;\r
- }\r
+ mCurrVarStorageNode = NULL;\r
\r
for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- break;\r
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+ return ReturnCode;\r
+ }\r
}\r
}\r
\r
- if (pNode == NULL) {\r
- return VFR_RETURN_UNDEFINED;\r
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+ return ReturnCode;\r
+ }\r
+ }\r
}\r
\r
- if (pNode->mStorageInfo.mDataType == NULL) {\r
- return VFR_RETURN_FATAL_ERROR;\r
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+ return ReturnCode;\r
+ }\r
+ }\r
}\r
\r
- *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
- return VFR_RETURN_SUCCESS;\r
+ if (HasFoundOne) {\r
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+ return VFR_RETURN_SUCCESS;\r
+ }\r
+\r
+ *VarStoreId = EFI_VARSTORE_ID_INVALID;\r
+\r
+ //\r
+ // Assume that Data structure name is used as StoreName, and check again.\r
+ //\r
+ ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
+ if (pNode != NULL) {\r
+ mCurrVarStorageNode = pNode;\r
+ *VarStoreId = pNode->mVarStoreId;\r
+ }\r
+\r
+ return ReturnCode;\r
}\r
\r
EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::GetVarStoreType (\r
- IN CHAR8 *StoreName,\r
- OUT EFI_VFR_VARSTORE_TYPE &VarStoreType\r
+CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
+ IN EFI_VARSTORE_ID VarStoreId,\r
+ OUT CHAR8 **DataTypeName\r
)\r
{\r
SVfrVarStorageNode *pNode;\r
\r
- if (StoreName == NULL) {\r
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
return VFR_RETURN_FATAL_ERROR;\r
}\r
\r
for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- VarStoreType = pNode->mVarStoreType;\r
+ if (pNode->mVarStoreId == VarStoreId) {\r
+ *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
return VFR_RETURN_SUCCESS;\r
}\r
}\r
\r
- for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- VarStoreType = pNode->mVarStoreType;\r
- return VFR_RETURN_SUCCESS;\r
- }\r
- }\r
-\r
- for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- VarStoreType = pNode->mVarStoreType;\r
- return VFR_RETURN_SUCCESS;\r
- }\r
- }\r
-\r
- VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
return VFR_RETURN_UNDEFINED;\r
}\r
\r
return VarStoreType;\r
}\r
\r
+EFI_GUID *\r
+CVfrDataStorage::GetVarStoreGuid (\r
+ IN EFI_VARSTORE_ID VarStoreId\r
+ )\r
+{\r
+ SVfrVarStorageNode *pNode;\r
+ EFI_GUID *VarGuid;\r
+\r
+ VarGuid = NULL;\r
+\r
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+ return VarGuid;\r
+ }\r
+\r
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+ if (pNode->mVarStoreId == VarStoreId) {\r
+ VarGuid = &pNode->mGuid;\r
+ return VarGuid;\r
+ }\r
+ }\r
+\r
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+ if (pNode->mVarStoreId == VarStoreId) {\r
+ VarGuid = &pNode->mGuid;\r
+ return VarGuid;\r
+ }\r
+ }\r
+\r
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+ if (pNode->mVarStoreId == VarStoreId) {\r
+ VarGuid = &pNode->mGuid;\r
+ return VarGuid;\r
+ }\r
+ }\r
+\r
+ return VarGuid;\r
+}\r
+\r
EFI_VFR_RETURN_CODE\r
CVfrDataStorage::GetVarStoreName (\r
- IN EFI_VARSTORE_ID VarStoreId, \r
+ IN EFI_VARSTORE_ID VarStoreId,\r
OUT CHAR8 **VarStoreName\r
)\r
{\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::AddBufferVarStoreFieldInfo (\r
+ IN EFI_VARSTORE_INFO *Info\r
+ )\r
+{\r
+ BufferVarStoreFieldInfoNode *pNew;\r
+\r
+ if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {\r
+ return VFR_RETURN_FATAL_ERROR;\r
+ }\r
+\r
+ if (mBufferFieldInfoListHead == NULL) {\r
+ mBufferFieldInfoListHead = pNew;\r
+ mBufferFieldInfoListTail= pNew;\r
+ } else {\r
+ mBufferFieldInfoListTail->mNext = pNew;\r
+ mBufferFieldInfoListTail = pNew;\r
+ }\r
+\r
+ return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetBufferVarStoreFieldInfo (\r
+ IN OUT EFI_VARSTORE_INFO *Info\r
+ )\r
+{\r
+ BufferVarStoreFieldInfoNode *pNode;\r
+\r
+ pNode = mBufferFieldInfoListHead;\r
+ while (pNode != NULL) {\r
+ if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&\r
+ Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {\r
+ Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;\r
+ Info->mVarType = pNode->mVarStoreInfo.mVarType;\r
+ return VFR_RETURN_SUCCESS;\r
+ }\r
+ pNode = pNode->mNext;\r
+ }\r
+ return VFR_RETURN_FATAL_ERROR;\r
+}\r
+\r
EFI_VFR_RETURN_CODE\r
CVfrDataStorage::GetNameVarStoreInfo (\r
OUT EFI_VARSTORE_INFO *Info,\r
if (mCurrVarStorageNode == NULL) {\r
return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
}\r
- \r
+\r
//\r
// Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
//\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
-EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
- IN CHAR8 *StoreName,\r
- IN EFI_VARSTORE_INFO &Info\r
- )\r
-{\r
- SVfrVarStorageNode *pNode = NULL;\r
- EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue;\r
-\r
- for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
- if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
- break;\r
- }\r
- }\r
-\r
- if (pNode == NULL) {\r
- return VFR_RETURN_UNDEFINED;\r
- }\r
-\r
- gCVfrBufferConfig.Open ();\r
- Value.u8 = 0;\r
- if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
- return VFR_RETURN_FATAL_ERROR;\r
- }\r
- gCVfrBufferConfig.Close ();\r
-\r
- return VFR_RETURN_SUCCESS;\r
-}\r
-\r
SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
- IN CHAR8 *RefName, \r
- IN EFI_STRING_ID DefaultStoreNameId, \r
+ IN CHAR8 *RefName,\r
+ IN EFI_STRING_ID DefaultStoreNameId,\r
IN UINT16 DefaultId\r
)\r
{\r
)\r
{\r
if (mRefName != NULL) {\r
- delete mRefName;\r
+ delete[] mRefName;\r
}\r
}\r
\r
}\r
\r
/*\r
- * assign new reference name or new default store name id only if \r
+ * assign new reference name or new default store name id only if\r
* the original is invalid\r
*/\r
EFI_VFR_RETURN_CODE\r
IN EFI_VARSTORE_ID DefaultId,\r
IN EFI_VARSTORE_INFO &Info,\r
IN CHAR8 *VarStoreName,\r
+ IN EFI_GUID *VarStoreGuid,\r
IN UINT8 Type,\r
IN EFI_IFR_TYPE_VALUE Value\r
)\r
gCVfrBufferConfig.Open ();\r
\r
sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
- if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
- if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
+ if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {\r
+ if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
goto WriteError;\r
}\r
}\r
- \r
+\r
gCVfrBufferConfig.Close ();\r
\r
return VFR_RETURN_SUCCESS;\r
)\r
{\r
if (mRuleName != NULL) {\r
- delete mRuleName;\r
+ delete[] mRuleName;\r
}\r
}\r
\r
mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
mVarType = EFI_IFR_TYPE_OTHER;\r
mVarTotalSize = 0;\r
+ mIsBitVar = FALSE;\r
}\r
\r
EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
mVarType = Info.mVarType;\r
mVarTotalSize = Info.mVarTotalSize;\r
+ mIsBitVar = Info.mIsBitVar;\r
+}\r
+\r
+EFI_VARSTORE_INFO&\r
+EFI_VARSTORE_INFO::operator= (\r
+ IN CONST EFI_VARSTORE_INFO &Info\r
+ )\r
+{\r
+ if (this != &Info) {\r
+ mVarStoreId = Info.mVarStoreId;\r
+ mInfo.mVarName = Info.mInfo.mVarName;\r
+ mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
+ mVarType = Info.mVarType;\r
+ mVarTotalSize = Info.mVarTotalSize;\r
+ mIsBitVar = Info.mIsBitVar;\r
+ }\r
+\r
+ return *this;\r
}\r
\r
BOOLEAN\r
)\r
{\r
if ((mVarStoreId == Info->mVarStoreId) &&\r
- (mInfo.mVarName == Info->mInfo.mVarName) &&\r
+ (mInfo.mVarName == Info->mInfo.mVarName) &&\r
(mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
(mVarType == Info->mVarType) &&\r
- (mVarTotalSize == Info->mVarTotalSize)) {\r
+ (mVarTotalSize == Info->mVarTotalSize) &&\r
+ (mIsBitVar == Info->mIsBitVar)) {\r
return TRUE;\r
}\r
\r
return FALSE;\r
}\r
\r
+BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(\r
+ IN EFI_VARSTORE_INFO *Info\r
+ )\r
+{\r
+ mVarStoreInfo.mVarType = Info->mVarType;\r
+ mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;\r
+ mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;\r
+ mVarStoreInfo.mVarStoreId = Info->mVarStoreId;\r
+ mNext = NULL;\r
+}\r
+\r
+BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()\r
+{\r
+ mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;\r
+ mVarStoreInfo.mVarTotalSize = 0;\r
+ mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
+ mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;\r
+ mNext = NULL;\r
+}\r
+\r
static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
\r
EFI_QUESTION_ID\r
}\r
}\r
\r
+ if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {\r
+ return EFI_QUESTION_ID_INVALID;\r
+ }\r
+\r
for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
mFreeQIdBitMap[Index] |= Mask;\r
)\r
{\r
if (mName != NULL) {\r
- delete mName;\r
+ delete[] mName;\r
}\r
\r
if (mVarIdStr != NULL) {\r
- delete mVarIdStr;\r
+ delete[] mVarIdStr;\r
}\r
}\r
\r
\r
// Question ID 0 is reserved.\r
mFreeQIdBitMap[0] = 0x80000000;\r
- mQuestionList = NULL; \r
+ mQuestionList = NULL;\r
}\r
\r
VOID\r
SVfrQuestionNode *pNode = NULL;\r
\r
for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
- printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
+ printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
}\r
}\r
\r
CHAR8 *VarIdStr[3] = {NULL, };\r
CHAR8 Index;\r
\r
- if (BaseVarId == NULL) {\r
+ if (BaseVarId == NULL && Name == NULL) {\r
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+ QuestionId = GetFreeQuestionId ();\r
+ } else {\r
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+ goto Err;\r
+ }\r
+ MarkQuestionIdUsed (QuestionId);\r
+ }\r
return;\r
}\r
\r
- Len = strlen (BaseVarId);\r
+ if (BaseVarId != NULL) {\r
+ Len = strlen (BaseVarId);\r
\r
- VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
- if (VarIdStr[0] != NULL) {\r
- strcpy (VarIdStr[0], BaseVarId);\r
- strcat (VarIdStr[0], ".Year");\r
- }\r
- VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
- if (VarIdStr[1] != NULL) {\r
- strcpy (VarIdStr[1], BaseVarId);\r
- strcat (VarIdStr[1], ".Month");\r
- }\r
- VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
- if (VarIdStr[2] != NULL) {\r
- strcpy (VarIdStr[2], BaseVarId);\r
- strcat (VarIdStr[2], ".Day");\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], BaseVarId);\r
+ strcat (VarIdStr[0], ".Year");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], BaseVarId);\r
+ strcat (VarIdStr[1], ".Month");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], BaseVarId);\r
+ strcat (VarIdStr[2], ".Day");\r
+ }\r
+ } else {\r
+ Len = strlen (Name);\r
+\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], Name);\r
+ strcat (VarIdStr[0], ".Year");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], Name);\r
+ strcat (VarIdStr[1], ".Month");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], Name);\r
+ strcat (VarIdStr[2], ".Day");\r
+ }\r
}\r
\r
if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
\r
for (Index = 0; Index < 3; Index++) {\r
if (VarIdStr[Index] != NULL) {\r
- delete VarIdStr[Index];\r
+ delete[] VarIdStr[Index];\r
+ VarIdStr[Index] = NULL;\r
}\r
}\r
\r
}\r
\r
if (VarIdStr[Index] != NULL) {\r
- delete VarIdStr[Index];\r
+ delete[] VarIdStr [Index];\r
+ VarIdStr [Index] = NULL;\r
}\r
}\r
}\r
CHAR8 *VarIdStr[3] = {NULL, };\r
CHAR8 Index;\r
\r
- if (BaseVarId == NULL) {\r
+ if (BaseVarId == NULL && Name == NULL) {\r
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+ QuestionId = GetFreeQuestionId ();\r
+ } else {\r
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+ goto Err;\r
+ }\r
+ MarkQuestionIdUsed (QuestionId);\r
+ }\r
return;\r
}\r
\r
- Len = strlen (BaseVarId);\r
+ if (BaseVarId != NULL) {\r
+ Len = strlen (BaseVarId);\r
\r
- VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
- if (VarIdStr[0] != NULL) {\r
- strcpy (VarIdStr[0], BaseVarId);\r
- strcat (VarIdStr[0], ".Hour");\r
- }\r
- VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
- if (VarIdStr[1] != NULL) {\r
- strcpy (VarIdStr[1], BaseVarId);\r
- strcat (VarIdStr[1], ".Minute");\r
- }\r
- VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
- if (VarIdStr[2] != NULL) {\r
- strcpy (VarIdStr[2], BaseVarId);\r
- strcat (VarIdStr[2], ".Second");\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], BaseVarId);\r
+ strcat (VarIdStr[0], ".Hour");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], BaseVarId);\r
+ strcat (VarIdStr[1], ".Minute");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], BaseVarId);\r
+ strcat (VarIdStr[2], ".Second");\r
+ }\r
+ } else {\r
+ Len = strlen (Name);\r
+\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], Name);\r
+ strcat (VarIdStr[0], ".Hour");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], Name);\r
+ strcat (VarIdStr[1], ".Minute");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], Name);\r
+ strcat (VarIdStr[2], ".Second");\r
+ }\r
}\r
\r
if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
\r
for (Index = 0; Index < 3; Index++) {\r
if (VarIdStr[Index] != NULL) {\r
- delete VarIdStr[Index];\r
+ delete[] VarIdStr[Index];\r
+ VarIdStr[Index] = NULL;\r
}\r
}\r
\r
delete pNode[Index];\r
}\r
\r
+ if (VarIdStr[Index] != NULL) {\r
+ delete[] VarIdStr[Index];\r
+ VarIdStr[Index] = NULL;\r
+ }\r
+ }\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterRefQuestion (\r
+ IN CHAR8 *Name,\r
+ IN CHAR8 *BaseVarId,\r
+ IN OUT EFI_QUESTION_ID &QuestionId\r
+ )\r
+{\r
+ SVfrQuestionNode *pNode[4] = {NULL, };\r
+ UINT32 Len;\r
+ CHAR8 *VarIdStr[4] = {NULL, };\r
+ CHAR8 Index;\r
+\r
+ if (BaseVarId == NULL && Name == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (BaseVarId != NULL) {\r
+ Len = strlen (BaseVarId);\r
+\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], BaseVarId);\r
+ strcat (VarIdStr[0], ".QuestionId");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], BaseVarId);\r
+ strcat (VarIdStr[1], ".FormId");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], BaseVarId);\r
+ strcat (VarIdStr[2], ".FormSetGuid");\r
+ }\r
+ VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
+ if (VarIdStr[3] != NULL) {\r
+ strcpy (VarIdStr[3], BaseVarId);\r
+ strcat (VarIdStr[3], ".DevicePath");\r
+ }\r
+ } else {\r
+ Len = strlen (Name);\r
+\r
+ VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
+ if (VarIdStr[0] != NULL) {\r
+ strcpy (VarIdStr[0], Name);\r
+ strcat (VarIdStr[0], ".QuestionId");\r
+ }\r
+ VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
+ if (VarIdStr[1] != NULL) {\r
+ strcpy (VarIdStr[1], Name);\r
+ strcat (VarIdStr[1], ".FormId");\r
+ }\r
+ VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
+ if (VarIdStr[2] != NULL) {\r
+ strcpy (VarIdStr[2], Name);\r
+ strcat (VarIdStr[2], ".FormSetGuid");\r
+ }\r
+ VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
+ if (VarIdStr[3] != NULL) {\r
+ strcpy (VarIdStr[3], Name);\r
+ strcat (VarIdStr[3], ".DevicePath");\r
+ }\r
+ }\r
+\r
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {\r
+ goto Err;\r
+ }\r
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {\r
+ goto Err;\r
+ }\r
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {\r
+ goto Err;\r
+ }\r
+ if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {\r
+ goto Err;\r
+ }\r
+\r
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+ QuestionId = GetFreeQuestionId ();\r
+ } else {\r
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+ goto Err;\r
+ }\r
+ MarkQuestionIdUsed (QuestionId);\r
+ }\r
+\r
+ pNode[0]->mQuestionId = QuestionId;\r
+ pNode[1]->mQuestionId = QuestionId;\r
+ pNode[2]->mQuestionId = QuestionId;\r
+ pNode[3]->mQuestionId = QuestionId;\r
+ pNode[0]->mQtype = QUESTION_REF;\r
+ pNode[1]->mQtype = QUESTION_REF;\r
+ pNode[2]->mQtype = QUESTION_REF;\r
+ pNode[3]->mQtype = QUESTION_REF;\r
+ pNode[0]->mNext = pNode[1];\r
+ pNode[1]->mNext = pNode[2];\r
+ pNode[2]->mNext = pNode[3];\r
+ pNode[3]->mNext = mQuestionList;\r
+ mQuestionList = pNode[0];\r
+\r
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+ gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+ return;\r
+\r
+ Err:\r
+ for (Index = 0; Index < 4; Index++) {\r
+ if (pNode[Index] != NULL) {\r
+ delete pNode[Index];\r
+ }\r
+\r
if (VarIdStr[Index] != NULL) {\r
delete VarIdStr[Index];\r
}\r
)\r
{\r
SVfrQuestionNode *pNode = NULL;\r
- \r
+\r
if (QId == NewQId) {\r
// don't update\r
return VFR_RETURN_SUCCESS;\r
}\r
- \r
+\r
//\r
// For Framework Vfr, don't check question ID conflict.\r
- // \r
+ //\r
if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
return VFR_RETURN_REDEFINED;\r
}\r
if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
continue;\r
}\r
- }\r
+ }\r
\r
QuestionId = pNode->mQuestionId;\r
BitMask = pNode->mBitMask;\r
return VFR_RETURN_UNDEFINED;\r
}\r
\r
+CVfrStringDB::CVfrStringDB ()\r
+{\r
+ mStringFileName = NULL;\r
+}\r
+\r
+CVfrStringDB::~CVfrStringDB ()\r
+{\r
+ if (mStringFileName != NULL) {\r
+ delete[] mStringFileName;\r
+ }\r
+ mStringFileName = NULL;\r
+}\r
+\r
+\r
+VOID\r
+CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
+{\r
+ UINT32 FileLen = 0;\r
+\r
+ if (StringFileName == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (mStringFileName != NULL) {\r
+ delete[] mStringFileName;\r
+ }\r
+\r
+ FileLen = strlen (StringFileName) + 1;\r
+ mStringFileName = new CHAR8[FileLen];\r
+ if (mStringFileName == NULL) {\r
+ return;\r
+ }\r
+\r
+ strcpy (mStringFileName, StringFileName);\r
+ mStringFileName[FileLen - 1] = '\0';\r
+}\r
+\r
+\r
+/**\r
+ Returns TRUE or FALSE whether SupportedLanguages contains the best matching language\r
+ from a set of supported languages.\r
+\r
+ @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that\r
+ contains a set of language codes.\r
+ @param[in] Language A variable that contains pointers to Null-terminated\r
+ ASCII strings that contain one language codes.\r
+\r
+ @retval FALSE The best matching language could not be found in SupportedLanguages.\r
+ @retval TRUE The best matching language could be found in SupportedLanguages.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrStringDB::GetBestLanguage (\r
+ IN CONST CHAR8 *SupportedLanguages,\r
+ IN CHAR8 *Language\r
+ )\r
+{\r
+ UINTN CompareLength;\r
+ UINTN LanguageLength;\r
+ CONST CHAR8 *Supported;\r
+\r
+ if (SupportedLanguages == NULL || Language == NULL){\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Determine the length of the first RFC 4646 language code in Language\r
+ //\r
+ for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
+\r
+ //\r
+ // Trim back the length of Language used until it is empty\r
+ //\r
+ while (LanguageLength > 0) {\r
+ //\r
+ // Loop through all language codes in SupportedLanguages\r
+ //\r
+ for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
+ //\r
+ // Skip ';' characters in Supported\r
+ //\r
+ for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
+ //\r
+ // Determine the length of the next language code in Supported\r
+ //\r
+ for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
+ //\r
+ // If Language is longer than the Supported, then skip to the next language\r
+ //\r
+ if (LanguageLength > CompareLength) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // See if the first LanguageLength characters in Supported match Language\r
+ //\r
+ if (strncmp (Supported, Language, LanguageLength) == 0) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Trim Language from the right to the next '-' character\r
+ //\r
+ for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
+ }\r
+\r
+ //\r
+ // No matches were found\r
+ //\r
+ return FALSE;\r
+}\r
+\r
+\r
+CHAR8 *\r
+CVfrStringDB::GetVarStoreNameFormStringId (\r
+ IN EFI_STRING_ID StringId\r
+ )\r
+{\r
+ FILE *pInFile = NULL;\r
+ UINT32 NameOffset;\r
+ UINT32 Length;\r
+ UINT8 *StringPtr;\r
+ CHAR8 *StringName;\r
+ CHAR16 *UnicodeString;\r
+ CHAR8 *VarStoreName = NULL;\r
+ CHAR8 *DestTmp;\r
+ UINT8 *Current;\r
+ EFI_STATUS Status;\r
+ CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];\r
+ UINT8 BlockType;\r
+ EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
+\r
+ if (mStringFileName == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Get file length.\r
+ //\r
+ fseek (pInFile, 0, SEEK_END);\r
+ Length = ftell (pInFile);\r
+ fseek (pInFile, 0, SEEK_SET);\r
+\r
+ //\r
+ // Get file data.\r
+ //\r
+ StringPtr = new UINT8[Length];\r
+ if (StringPtr == NULL) {\r
+ fclose (pInFile);\r
+ return NULL;\r
+ }\r
+ fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
+ fclose (pInFile);\r
+\r
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
+ //\r
+ // Check the String package.\r
+ //\r
+ if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
+ delete[] StringPtr;\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Search the language, get best language base on RFC 4647 matching algorithm.\r
+ //\r
+ Current = StringPtr;\r
+ while (!GetBestLanguage ("en", PkgHeader->Language)) {\r
+ Current += PkgHeader->Header.Length;\r
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
+ //\r
+ // If can't find string package base on language, just return the first string package.\r
+ //\r
+ if (Current - StringPtr >= Length) {\r
+ Current = StringPtr;\r
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
+ break;\r
+ }\r
+ }\r
+\r
+ Current += PkgHeader->HdrSize;\r
+ //\r
+ // Find the string block according the stringId.\r
+ //\r
+ Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
+ if (Status != EFI_SUCCESS) {\r
+ delete[] StringPtr;\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Get varstore name according the string type.\r
+ //\r
+ switch (BlockType) {\r
+ case EFI_HII_SIBT_STRING_SCSU:\r
+ case EFI_HII_SIBT_STRING_SCSU_FONT:\r
+ case EFI_HII_SIBT_STRINGS_SCSU:\r
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
+ StringName = (CHAR8*)(Current + NameOffset);\r
+ VarStoreName = new CHAR8[strlen(StringName) + 1];\r
+ strcpy (VarStoreName, StringName);\r
+ break;\r
+ case EFI_HII_SIBT_STRING_UCS2:\r
+ case EFI_HII_SIBT_STRING_UCS2_FONT:\r
+ case EFI_HII_SIBT_STRINGS_UCS2:\r
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
+ UnicodeString = (CHAR16*)(Current + NameOffset);\r
+ Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
+ DestTmp = new CHAR8[Length / 2 + 1];\r
+ VarStoreName = DestTmp;\r
+ while (*UnicodeString != '\0') {\r
+ *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
+ }\r
+ *DestTmp = '\0';\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ delete[] StringPtr;\r
+\r
+ return VarStoreName;\r
+}\r
+\r
+EFI_STATUS\r
+CVfrStringDB::FindStringBlock (\r
+ IN UINT8 *StringData,\r
+ IN EFI_STRING_ID StringId,\r
+ OUT UINT32 *StringTextOffset,\r
+ OUT UINT8 *BlockType\r
+ )\r
+{\r
+ UINT8 *BlockHdr;\r
+ EFI_STRING_ID CurrentStringId;\r
+ UINT32 BlockSize;\r
+ UINT32 Index;\r
+ UINT8 *StringTextPtr;\r
+ UINT32 Offset;\r
+ UINT16 StringCount;\r
+ UINT16 SkipCount;\r
+ UINT8 Length8;\r
+ EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
+ UINT32 Length32;\r
+ UINT32 StringSize;\r
+\r
+ CurrentStringId = 1;\r
+\r
+ //\r
+ // Parse the string blocks to get the string text and font.\r
+ //\r
+ BlockHdr = StringData;\r
+ BlockSize = 0;\r
+ Offset = 0;\r
+ while (*BlockHdr != EFI_HII_SIBT_END) {\r
+ switch (*BlockHdr) {\r
+ case EFI_HII_SIBT_STRING_SCSU:\r
+ Offset = sizeof (EFI_HII_STRING_BLOCK);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ CurrentStringId++;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRING_SCSU_FONT:\r
+ Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ CurrentStringId++;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRINGS_SCSU:\r
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
+ BlockSize += StringTextPtr - BlockHdr;\r
+\r
+ for (Index = 0; Index < StringCount; Index++) {\r
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ if (CurrentStringId == StringId) {\r
+ *BlockType = *BlockHdr;\r
+ *StringTextOffset = StringTextPtr - StringData;\r
+ return EFI_SUCCESS;\r
+ }\r
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ CurrentStringId++;\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
+ memcpy (\r
+ &StringCount,\r
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ sizeof (UINT16)\r
+ );\r
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
+ BlockSize += StringTextPtr - BlockHdr;\r
+\r
+ for (Index = 0; Index < StringCount; Index++) {\r
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ if (CurrentStringId == StringId) {\r
+ *BlockType = *BlockHdr;\r
+ *StringTextOffset = StringTextPtr - StringData;\r
+ return EFI_SUCCESS;\r
+ }\r
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+ CurrentStringId++;\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRING_UCS2:\r
+ Offset = sizeof (EFI_HII_STRING_BLOCK);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ //\r
+ // Use StringSize to store the size of the specified string, including the NULL\r
+ // terminator.\r
+ //\r
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+ BlockSize += Offset + StringSize;\r
+ CurrentStringId++;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRING_UCS2_FONT:\r
+ Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ //\r
+ // Use StrSize to store the size of the specified string, including the NULL\r
+ // terminator.\r
+ //\r
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+ BlockSize += Offset + StringSize;\r
+ CurrentStringId++;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRINGS_UCS2:\r
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ BlockSize += Offset;\r
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+ for (Index = 0; Index < StringCount; Index++) {\r
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+ BlockSize += StringSize;\r
+ if (CurrentStringId == StringId) {\r
+ *BlockType = *BlockHdr;\r
+ *StringTextOffset = StringTextPtr - StringData;\r
+ return EFI_SUCCESS;\r
+ }\r
+ StringTextPtr = StringTextPtr + StringSize;\r
+ CurrentStringId++;\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
+ StringTextPtr = BlockHdr + Offset;\r
+ BlockSize += Offset;\r
+ memcpy (\r
+ &StringCount,\r
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ sizeof (UINT16)\r
+ );\r
+ for (Index = 0; Index < StringCount; Index++) {\r
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+ BlockSize += StringSize;\r
+ if (CurrentStringId == StringId) {\r
+ *BlockType = *BlockHdr;\r
+ *StringTextOffset = StringTextPtr - StringData;\r
+ return EFI_SUCCESS;\r
+ }\r
+ StringTextPtr = StringTextPtr + StringSize;\r
+ CurrentStringId++;\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_SIBT_DUPLICATE:\r
+ if (CurrentStringId == StringId) {\r
+ //\r
+ // Incoming StringId is an id of a duplicate string block.\r
+ // Update the StringId to be the previous string block.\r
+ // Go back to the header of string block to search.\r
+ //\r
+ memcpy (\r
+ &StringId,\r
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
+ sizeof (EFI_STRING_ID)\r
+ );\r
+ CurrentStringId = 1;\r
+ BlockSize = 0;\r
+ } else {\r
+ BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
+ CurrentStringId++;\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_SIBT_SKIP1:\r
+ SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
+ break;\r
+\r
+ case EFI_HII_SIBT_SKIP2:\r
+ memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+ break;\r
+\r
+ case EFI_HII_SIBT_EXT1:\r
+ memcpy (\r
+ &Length8,\r
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ sizeof (UINT8)\r
+ );\r
+ BlockSize += Length8;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_EXT2:\r
+ memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
+ BlockSize += Ext2.Length;\r
+ break;\r
+\r
+ case EFI_HII_SIBT_EXT4:\r
+ memcpy (\r
+ &Length32,\r
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ sizeof (UINT32)\r
+ );\r
+\r
+ BlockSize += Length32;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
+ *StringTextOffset = BlockHdr - StringData + Offset;\r
+ *BlockType = *BlockHdr;\r
+\r
+ if (StringId == CurrentStringId - 1) {\r
+ //\r
+ // if only one skip item, return EFI_NOT_FOUND.\r
+ //\r
+ if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ if (StringId < CurrentStringId - 1) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ BlockHdr = StringData + BlockSize;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+UINT32\r
+CVfrStringDB::GetUnicodeStringTextSize (\r
+ IN UINT8 *StringSrc\r
+ )\r
+{\r
+ UINT32 StringSize;\r
+ CHAR16 *StringPtr;\r
+\r
+ StringSize = sizeof (CHAR16);\r
+ StringPtr = (UINT16*)StringSrc;\r
+ while (*StringPtr++ != L'\0') {\r
+ StringSize += sizeof (CHAR16);\r
+ }\r
+\r
+ return StringSize;\r
+}\r
+\r
BOOLEAN VfrCompatibleMode = FALSE;\r
\r
CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
+CVfrDefaultStore gCVfrDefaultStore;\r
+CVfrDataStorage gCVfrDataStorage;\r
\r
\r