/** @file\r
- \r
+\r
The definition of CFormPkg's member function\r
\r
-Copyright (c) 2004 - 2013, 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 "assert.h"\r
#include "VfrFormPkg.h"\r
\r
/*\r
*/\r
\r
SPendingAssign::SPendingAssign (\r
- IN CHAR8 *Key, \r
- IN VOID *Addr, \r
- IN UINT32 Len, \r
+ IN CHAR8 *Key,\r
+ IN VOID *Addr,\r
+ IN UINT32 Len,\r
IN UINT32 LineNo,\r
IN CONST CHAR8 *Msg\r
)\r
)\r
{\r
if (mKey != NULL) {\r
- delete mKey;\r
+ delete[] mKey;\r
}\r
mAddr = NULL;\r
mLen = 0;\r
mLineNo = 0;\r
if (mMsg != NULL) {\r
- delete mMsg;\r
+ delete[] mMsg;\r
}\r
mNext = NULL;\r
}\r
\r
VOID\r
SPendingAssign::SetAddrAndLen (\r
- IN VOID *Addr, \r
+ IN VOID *Addr,\r
IN UINT32 LineNo\r
)\r
{\r
\r
VOID\r
SPendingAssign::AssignValue (\r
- IN VOID *Addr, \r
+ IN VOID *Addr,\r
IN UINT32 Len\r
)\r
{\r
- memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));\r
+ memmove (mAddr, Addr, (mLen < Len ? mLen : Len));\r
mFlag = ASSIGNED;\r
}\r
\r
}\r
\r
CFormPkg::CFormPkg (\r
- IN UINT32 BufferSize = 4096\r
+ IN UINT32 BufferSize\r
)\r
{\r
CHAR8 *BufferStart;\r
SBufferNode *Node;\r
\r
mPkgLength = 0;\r
+ mBufferSize = 0;\r
mBufferNodeQueueHead = NULL;\r
+ mBufferNodeQueueTail = NULL;\r
mCurrBufferNode = NULL;\r
+ mReadBufferNode = NULL;\r
+ mReadBufferOffset = 0;\r
+ PendingAssignList = NULL;\r
\r
Node = new SBufferNode;\r
if (Node == NULL) {\r
}\r
BufferStart = new CHAR8[BufferSize];\r
if (BufferStart == NULL) {\r
+ delete Node;\r
return;\r
}\r
BufferEnd = BufferStart + BufferSize;\r
pBNode = mBufferNodeQueueHead;\r
mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
if (pBNode->mBufferStart != NULL) {\r
- delete pBNode->mBufferStart;\r
+ delete[] pBNode->mBufferStart;\r
delete pBNode;\r
}\r
}\r
\r
UINT32\r
CFormPkg::Read (\r
- IN CHAR8 *Buffer, \r
+ IN CHAR8 *Buffer,\r
IN UINT32 Size\r
)\r
{\r
OUT PACKAGE_DATA &TBuffer\r
)\r
{\r
- \r
+\r
CHAR8 *Temp;\r
UINT32 Size;\r
CHAR8 Buffer[1024];\r
}\r
fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
delete PkgHdr;\r
- \r
+\r
if (PkgData == NULL) {\r
Open ();\r
while ((Size = Read (Buffer, 1024)) != 0) {\r
BOOLEAN gNeedAdjustOpcode = FALSE;\r
UINT32 gAdjustOpcodeLen = 0;\r
\r
-EFI_VFR_RETURN_CODE \r
+EFI_VFR_RETURN_CODE\r
CFormPkg::GenCFile (\r
IN CHAR8 *BaseName,\r
IN FILE *pFile,\r
// For framework vfr file, the extension framework header will be added.\r
//\r
if (VfrCompatibleMode) {\r
- fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
- PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
- _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
- fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
- PkgLength = 3;\r
- _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16)); \r
- } else {\r
- fprintf (pFile, " // ARRAY LENGTH\n");\r
- PkgLength = PkgHdr->Length + sizeof (UINT32);\r
- _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
- }\r
+ fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
+ PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
+ _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));\r
+ fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
+ PkgLength = 3;\r
+ _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16));\r
+ } else {\r
+ fprintf (pFile, " // ARRAY LENGTH\n");\r
+ PkgLength = PkgHdr->Length + sizeof (UINT32);\r
+ _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));\r
+ }\r
\r
fprintf (pFile, "\n\n // PACKAGE HEADER\n");\r
_WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
\r
fprintf (pFile, "\n\n // PACKAGE DATA\n");\r
- \r
+\r
if (PkgData == NULL) {\r
Open ();\r
while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
\r
EFI_VFR_RETURN_CODE\r
CFormPkg::AssignPending (\r
- IN CHAR8 *Key, \r
- IN VOID *ValAddr, \r
+ IN CHAR8 *Key,\r
+ IN VOID *ValAddr,\r
IN UINT32 ValLen,\r
IN UINT32 LineNo,\r
IN CONST CHAR8 *Msg\r
\r
VOID\r
CFormPkg::DoPendingAssign (\r
- IN CHAR8 *Key, \r
- IN VOID *ValAddr, \r
+ IN CHAR8 *Key,\r
+ IN VOID *ValAddr,\r
IN UINT32 ValLen\r
)\r
{\r
\r
EFI_VFR_RETURN_CODE\r
CFormPkg::AdjustDynamicInsertOpcode (\r
- IN CHAR8 *LastFormEndAddr,\r
- IN CHAR8 *InsertOpcodeAddr\r
+ IN CHAR8 *InserPositionAddr,\r
+ IN CHAR8 *InsertOpcodeAddr,\r
+ IN BOOLEAN CreateOpcodeAfterParsingVfr\r
)\r
{\r
- SBufferNode *LastFormEndNode;\r
+ SBufferNode *InserPositionNode;\r
SBufferNode *InsertOpcodeNode;\r
SBufferNode *NewRestoreNodeBegin;\r
SBufferNode *NewRestoreNodeEnd;\r
\r
NewRestoreNodeEnd = NULL;\r
\r
- LastFormEndNode = GetBinBufferNodeForAddr(LastFormEndAddr);\r
+ InserPositionNode = GetBinBufferNodeForAddr(InserPositionAddr);\r
InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
+ assert (InserPositionNode != NULL);\r
+ assert (InsertOpcodeNode != NULL);\r
\r
- if (LastFormEndNode == InsertOpcodeNode) {\r
+ if (InserPositionNode == InsertOpcodeNode) {\r
//\r
// Create New Node to save the restore opcode.\r
//\r
- NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr;\r
+ NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;\r
gAdjustOpcodeLen = NeedRestoreCodeLen;\r
NewRestoreNodeBegin = CreateNewNode ();\r
if (NewRestoreNodeBegin == NULL) {\r
return VFR_RETURN_OUT_FOR_RESOURCES;\r
}\r
- memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
+ memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);\r
NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
\r
//\r
// Override the restore buffer data.\r
//\r
- memcpy (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
+ memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;\r
memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);\r
} else {\r
//\r
// Create New Node to save the restore opcode.\r
//\r
- NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr;\r
+ NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;\r
gAdjustOpcodeLen = NeedRestoreCodeLen;\r
NewRestoreNodeBegin = CreateNewNode ();\r
if (NewRestoreNodeBegin == NULL) {\r
return VFR_RETURN_OUT_FOR_RESOURCES;\r
}\r
- memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
+ memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);\r
NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
//\r
// Override the restore buffer data.\r
//\r
- LastFormEndNode->mBufferFree -= NeedRestoreCodeLen;\r
+ InserPositionNode->mBufferFree -= NeedRestoreCodeLen;\r
//\r
// Link the restore data to new node.\r
//\r
- NewRestoreNodeBegin->mNext = LastFormEndNode->mNext;\r
+ NewRestoreNodeBegin->mNext = InserPositionNode->mNext;\r
\r
//\r
// Count the Adjust opcode len.\r
//\r
- TmpNode = LastFormEndNode->mNext;\r
+ TmpNode = InserPositionNode->mNext;\r
while (TmpNode != InsertOpcodeNode) {\r
gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;\r
TmpNode = TmpNode->mNext;\r
//\r
// Override the restore buffer data.\r
//\r
- memcpy (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
+ memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
\r
//\r
// Insert the last restore data node.\r
//\r
TmpNode = GetNodeBefore (InsertOpcodeNode);\r
- if (TmpNode == LastFormEndNode) {\r
+ assert (TmpNode != NULL);\r
+\r
+ if (TmpNode == InserPositionNode) {\r
NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;\r
} else {\r
TmpNode->mNext = NewRestoreNodeEnd;\r
}\r
//\r
- // Connect the dynamic opcode node to the node before last form end node.\r
+ // Connect the dynamic opcode node to the node after InserPositionNode.\r
//\r
- LastFormEndNode->mNext = InsertOpcodeNode;\r
+ InserPositionNode->mNext = InsertOpcodeNode;\r
}\r
}\r
\r
- if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {\r
+ if (CreateOpcodeAfterParsingVfr) {\r
//\r
- // End form set opcode all in the mBufferNodeQueueTail node.\r
+ // Th new opcodes were created after Parsing Vfr file,\r
+ // so the content in mBufferNodeQueueTail must be the new created opcodes.\r
+ // So connet the NewRestoreNodeBegin to the tail and update the tail node.\r
//\r
- NewLastEndNode = CreateNewNode ();\r
- if (NewLastEndNode == NULL) {\r
- return VFR_RETURN_OUT_FOR_RESOURCES;\r
- }\r
- NewLastEndNode->mBufferStart[0] = 0x29;\r
- NewLastEndNode->mBufferStart[1] = 0x02;\r
- NewLastEndNode->mBufferFree += 2;\r
-\r
- mBufferNodeQueueTail->mBufferFree -= 2;\r
-\r
mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
if (NewRestoreNodeEnd != NULL) {\r
- NewRestoreNodeEnd->mNext = NewLastEndNode;\r
+ mBufferNodeQueueTail = NewRestoreNodeEnd;\r
} else {\r
- NewRestoreNodeBegin->mNext = NewLastEndNode;\r
+ mBufferNodeQueueTail = NewRestoreNodeBegin;\r
}\r
+ } else {\r
+ if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {\r
+ //\r
+ // End form set opcode all in the mBufferNodeQueueTail node.\r
+ //\r
+ NewLastEndNode = CreateNewNode ();\r
+ if (NewLastEndNode == NULL) {\r
+ return VFR_RETURN_OUT_FOR_RESOURCES;\r
+ }\r
+ NewLastEndNode->mBufferStart[0] = 0x29;\r
+ NewLastEndNode->mBufferStart[1] = 0x02;\r
+ NewLastEndNode->mBufferFree += 2;\r
\r
- mBufferNodeQueueTail = NewLastEndNode;\r
- } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
- TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
- TmpNode->mNext = NewRestoreNodeBegin;\r
- if (NewRestoreNodeEnd != NULL) {\r
- NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
- } else {\r
- NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;\r
+ mBufferNodeQueueTail->mBufferFree -= 2;\r
+\r
+ mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
+ if (NewRestoreNodeEnd != NULL) {\r
+ NewRestoreNodeEnd->mNext = NewLastEndNode;\r
+ } else {\r
+ NewRestoreNodeBegin->mNext = NewLastEndNode;\r
+ }\r
+\r
+ mBufferNodeQueueTail = NewLastEndNode;\r
+ } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
+ TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
+ assert (TmpNode != NULL);\r
+\r
+ TmpNode->mNext = NewRestoreNodeBegin;\r
+ if (NewRestoreNodeEnd != NULL) {\r
+ NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
+ } else {\r
+ NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;\r
+ }\r
}\r
}\r
-\r
+ mCurrBufferNode = mBufferNodeQueueTail;\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
CHAR8 FName[MAX_NAME_LEN];\r
CHAR8 *SName;\r
CHAR8 *NewStr;\r
- UINT32 ShrinkSize;\r
+ UINT32 ShrinkSize = 0;\r
EFI_VFR_RETURN_CODE ReturnCode;\r
EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
- EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;\r
+ UINT8 LFlags;\r
+ UINT32 MaxValue;\r
+ CIfrGuid *GuidObj = NULL;\r
\r
//\r
// Declare all questions as Numeric in DisableIf True\r
// DisableIf\r
CIfrDisableIf DIObj;\r
DIObj.SetLineNo (LineNo);\r
- *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
- \r
+ *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();\r
+\r
//TrueOpcode\r
CIfrTrue TObj (LineNo);\r
\r
// Declare Numeric qeustion for each undefined question.\r
for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
if (pNode->mFlag == PENDING) {\r
- CIfrNumeric CNObj;\r
- EFI_VARSTORE_INFO Info; \r
+ EFI_VARSTORE_INFO Info;\r
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
-\r
- CNObj.SetLineNo (LineNo);\r
- CNObj.SetPrompt (0x0);\r
- CNObj.SetHelp (0x0);\r
-\r
//\r
// Register this question, assume it is normal question, not date or time question\r
//\r
gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
return ReturnCode;\r
}\r
- \r
+\r
#ifdef VFREXP_DEBUG\r
printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
#endif\r
// Get VarStoreType\r
//\r
ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
- if (ReturnCode == VFR_RETURN_UNDEFINED) {\r
- lCVfrDataStorage.DeclareBufferVarStore (\r
- FName, \r
- LocalFormSetGuid, \r
- &lCVfrVarDataTypeDB, \r
- FName,\r
- EFI_VARSTORE_ID_INVALID,\r
- FALSE\r
- );\r
- ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId, LocalFormSetGuid); \r
- }\r
if (ReturnCode != VFR_RETURN_SUCCESS) {\r
gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
return ReturnCode;\r
}\r
- VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
+ VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);\r
\r
if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
} else {\r
if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
- } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
+ } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {\r
VarStr = pNode->mKey;\r
//convert VarStr with store name to VarStr with structure name\r
ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
NewStr[0] = '\0';\r
strcpy (NewStr, SName);\r
strcat (NewStr, VarStr + strlen (FName));\r
- ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
- delete NewStr;\r
+ ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);\r
+ delete[] NewStr;\r
}\r
} else {\r
ReturnCode = VFR_RETURN_UNSUPPORTED;\r
gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
return ReturnCode;\r
}\r
-\r
- CNObj.SetQuestionId (QId);\r
- CNObj.SetVarStoreInfo (&Info);\r
//\r
- // Numeric doesn't support BOOLEAN data type. \r
- // BOOLEAN type has the same data size to UINT8. \r
+ // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.\r
//\r
- if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
- Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ if (Info.mIsBitVar) {\r
+ GuidObj = new CIfrGuid(0);\r
+ GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);\r
+ GuidObj->SetLineNo(LineNo);\r
}\r
- CNObj.SetFlags (0, Info.mVarType);\r
+\r
+ CIfrNumeric CNObj;\r
+ CNObj.SetLineNo (LineNo);\r
+ CNObj.SetPrompt (0x0);\r
+ CNObj.SetHelp (0x0);\r
+ CNObj.SetQuestionId (QId);\r
+ CNObj.SetVarStoreInfo (&Info);\r
+\r
//\r
- // Use maximum value not to limit the vaild value for the undefined question.\r
+ // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.\r
//\r
- switch (Info.mVarType) {\r
- case EFI_IFR_TYPE_NUM_SIZE_64:\r
- CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
- ShrinkSize = 0;\r
- break;\r
- case EFI_IFR_TYPE_NUM_SIZE_32:\r
- CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
+ if (Info.mIsBitVar) {\r
+ MaxValue = (1 << Info.mVarTotalSize) -1;\r
+ CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);\r
ShrinkSize = 12;\r
- break;\r
- case EFI_IFR_TYPE_NUM_SIZE_16:\r
- CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
- ShrinkSize = 18;\r
- break;\r
- case EFI_IFR_TYPE_NUM_SIZE_8:\r
- CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
- ShrinkSize = 21;\r
- break;\r
- default:\r
- break;\r
+ LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);\r
+ CNObj.SetFlagsForBitField (0, LFlags);\r
+ } else {\r
+ //\r
+ // Numeric doesn't support BOOLEAN data type.\r
+ // BOOLEAN type has the same data size to UINT8.\r
+ //\r
+ if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
+ Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ }\r
+ CNObj.SetFlags (0, Info.mVarType);\r
+ //\r
+ // Use maximum value not to limit the valid value for the undefined question.\r
+ //\r
+ switch (Info.mVarType) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
+ ShrinkSize = 0;\r
+ break;\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
+ ShrinkSize = 12;\r
+ break;\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
+ ShrinkSize = 18;\r
+ break;\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
+ ShrinkSize = 21;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
}\r
CNObj.ShrinkBinSize (ShrinkSize);\r
\r
//\r
// End for Numeric\r
//\r
- CIfrEnd CEObj; \r
+ CIfrEnd CEObj;\r
CEObj.SetLineNo (LineNo);\r
+ //\r
+ // End for Guided opcode\r
+ //\r
+ if (GuidObj != NULL) {\r
+ CIfrEnd CEObjGuid;\r
+ CEObjGuid.SetLineNo (LineNo);\r
+ GuidObj->SetScope(1);\r
+ delete GuidObj;\r
+ GuidObj = NULL;\r
+ }\r
}\r
}\r
\r
mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
mIfrRecordListHead = NULL;\r
mIfrRecordListTail = NULL;\r
+ mAllDefaultTypeCount = 0;\r
+ for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {\r
+ mAllDefaultIdArray[i] = 0xffff;\r
+ }\r
}\r
\r
CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
)\r
{\r
CHAR8 *Temp;\r
- SIfrRecord *pNode; \r
+ SIfrRecord *pNode;\r
\r
if (TBuffer.Buffer != NULL) {\r
- delete TBuffer.Buffer;\r
+ delete[] TBuffer.Buffer;\r
}\r
\r
TBuffer.Size = 0;\r
\r
if (mSwitch == FALSE) {\r
return;\r
- } \r
- \r
+ }\r
+\r
for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
TBuffer.Size += pNode->mBinBufLen;\r
}\r
- \r
+\r
if (TBuffer.Size != 0) {\r
TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
} else {\r
return;\r
}\r
- \r
+\r
Temp = TBuffer.Buffer;\r
\r
for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
}\r
}\r
\r
- return; \r
-} \r
+ return;\r
+}\r
\r
VOID\r
CIfrRecordInfoDB::IfrRecordOutput (\r
fprintf (File, "\n");\r
}\r
}\r
- \r
+\r
if (LineNo == 0) {\r
fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
}\r
case EFI_IFR_DATE_OP:\r
case EFI_IFR_TIME_OP:\r
case EFI_IFR_ORDERED_LIST_OP:\r
+ case EFI_IFR_REF_OP:\r
return TRUE;\r
default:\r
return FALSE;\r
default:\r
return FALSE;\r
}\r
-} \r
+}\r
\r
EFI_QUESTION_ID\r
CIfrRecordInfoDB::GetOpcodeQuestionId (\r
)\r
{\r
EFI_IFR_QUESTION_HEADER *QuestionHead;\r
- \r
+\r
QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
- \r
+\r
return QuestionHead->QuestionId;\r
}\r
\r
return pNode;\r
}\r
\r
-/*\r
+/**\r
Add just the op code position.\r
\r
+ Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,\r
+ so pDynamicOpcodeNodes is before mIfrRecordListTail.\r
+\r
From\r
- \r
- | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |\r
- \r
+\r
+ |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|\r
+\r
To\r
- \r
- | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |\r
\r
-*/\r
+ |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|\r
+\r
+ Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,\r
+ so new records are appennded to the end of OriginalIfrRecordListTail.\r
+\r
+ From\r
+\r
+ |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|\r
+\r
+ To\r
+\r
+ |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|\r
+\r
+\r
+ @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
+\r
+**/\r
BOOLEAN\r
CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
- VOID\r
+ IN BOOLEAN CreateOpcodeAfterParsingVfr\r
)\r
{\r
UINT32 OpcodeOffset;\r
SIfrRecord *pNode, *pPreNode;\r
- SIfrRecord *pStartNode, *pNodeBeforeStart;\r
- SIfrRecord *pEndNode;\r
- \r
- pStartNode = NULL;\r
- pEndNode = NULL;\r
- OpcodeOffset = 0;\r
+ SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;\r
+ SIfrRecord *pNodeBeforeDynamic;\r
+\r
+ pPreNode = NULL;\r
+ pAdjustNode = NULL;\r
+ pNodeBeforeDynamic = NULL;\r
+ OpcodeOffset = 0;\r
\r
//\r
- // Base on the offset info to get the node.\r
+ // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,\r
+ // and the node before pDynamicOpcodeNode.\r
//\r
- for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {\r
+ for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {\r
if (OpcodeOffset == gAdjustOpcodeOffset) {\r
- pStartNode = pNode;\r
- pNodeBeforeStart = pPreNode;\r
+ pAdjustNode = pNode;\r
+ pNodeBeforeAdjust = pPreNode;\r
} else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
- pEndNode = pPreNode;\r
+ pNodeBeforeDynamic = pPreNode;\r
+ }\r
+ if (pNode->mNext != NULL) {\r
+ pPreNode = pNode;\r
}\r
-\r
OpcodeOffset += pNode->mBinBufLen;\r
}\r
\r
//\r
- // Check the value.\r
+ // Check the nodes whether exist.\r
//\r
- if (pEndNode == NULL || pStartNode == NULL) {\r
+ if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {\r
return FALSE;\r
}\r
\r
//\r
// Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
//\r
- pNodeBeforeStart->mNext = pEndNode->mNext;\r
- pPreNode->mNext = pStartNode;\r
- pEndNode->mNext = mIfrRecordListTail;\r
+ pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;\r
+ if (CreateOpcodeAfterParsingVfr) {\r
+ //\r
+ // mIfrRecordListTail is the end of pDynamicNode (Case2).\r
+ //\r
+ mIfrRecordListTail->mNext = pAdjustNode;\r
+ mIfrRecordListTail = pNodeBeforeDynamic;\r
+ mIfrRecordListTail->mNext = NULL;\r
+ } else {\r
+ //\r
+ //pPreNode is the end of pDynamicNode(Case1).\r
+ //\r
+ pPreNode->mNext = pAdjustNode;\r
+ pNodeBeforeDynamic->mNext = mIfrRecordListTail;\r
+ }\r
\r
return TRUE;\r
}\r
\r
+/**\r
+ Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.\r
+\r
+ @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.\r
+\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (\r
+ IN BOOLEAN CreateOpcodeAfterParsingVfr\r
+ )\r
+{\r
+ SIfrRecord *pRecord;\r
+\r
+ //\r
+ // Base on the original offset info to update the record list.\r
+ //\r
+ if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {\r
+ gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");\r
+ }\r
+\r
+ //\r
+ // Base on the opcode binary length to recalculate the offset for each opcode.\r
+ //\r
+ IfrAdjustOffsetForRecord();\r
+\r
+ //\r
+ // Base on the offset to find the binary address.\r
+ //\r
+ pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);\r
+ while (pRecord != NULL) {\r
+ pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);\r
+ pRecord = pRecord->mNext;\r
+ }\r
+}\r
+\r
+\r
VOID\r
CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
VOID\r
EFI_QUESTION_ID QuestionId;\r
UINT32 StackCount;\r
UINT32 QuestionScope;\r
- UINT32 OpcodeOffset;\r
CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
EFI_VFR_RETURN_CODE Status;\r
\r
QuestionScope = 0;\r
while (pNode != NULL) {\r
OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
- \r
+\r
//\r
// make sure the inconsistent opcode in question scope\r
//\r
QuestionScope --;\r
}\r
}\r
- \r
+\r
if (CheckQuestionOpCode (OpHead->OpCode)) {\r
QuestionScope = 1;\r
}\r
//\r
\r
//\r
- // Count inconsistent opcode Scope \r
+ // Count inconsistent opcode Scope\r
//\r
StackCount = OpHead->Scope;\r
QuestionId = EFI_QUESTION_ID_INVALID;\r
//\r
// by IdEqual opcode to get QuestionId\r
//\r
- if (QuestionId == EFI_QUESTION_ID_INVALID && \r
+ if (QuestionId == EFI_QUESTION_ID_INVALID &&\r
CheckIdOpCode (tOpHead->OpCode)) {\r
QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
}\r
}\r
//\r
// extract inconsistent opcode list\r
- // pNode is Incosistent opcode, tNode is End Opcode\r
+ // pNode is Inconsistent opcode, tNode is End Opcode\r
//\r
- \r
+\r
//\r
// insert inconsistent opcode list into the right question scope by questionid\r
//\r
for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
- if (CheckQuestionOpCode (tOpHead->OpCode) && \r
+ if (CheckQuestionOpCode (tOpHead->OpCode) &&\r
(QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
break;\r
}\r
//\r
OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
}\r
- \r
+\r
//\r
// skip the default storage for Date and Time\r
//\r
Status = VFR_RETURN_MISMATCHED;\r
break;\r
}\r
- } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
+ } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||\r
OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
//\r
// for new added group of varstore opcode\r
tNode = pNode;\r
while (tNode->mNext != NULL) {\r
tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
- if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
+ if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&\r
tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
- break; \r
+ break;\r
}\r
tNode = tNode->mNext;\r
}\r
if (tNode->mNext == NULL) {\r
//\r
// invalid IfrCode, IfrCode end by EndOpCode\r
- // \r
+ //\r
gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
Status = VFR_RETURN_MISMATCHED;\r
break;\r
}\r
- \r
+\r
if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
//\r
// not new added varstore, which are not needed to be adjust.\r
//\r
preNode = tNode;\r
pNode = tNode->mNext;\r
- continue; \r
+ continue;\r
} else {\r
//\r
- // move new added varstore opcode to the position befor form opcode \r
+ // move new added varstore opcode to the position befor form opcode\r
// varstore opcode between pNode and tNode\r
//\r
\r
// next node\r
//\r
preNode = pNode;\r
- pNode = pNode->mNext; \r
+ pNode = pNode->mNext;\r
}\r
- \r
+\r
//\r
// Update Ifr Opcode Offset\r
//\r
return Status;\r
}\r
\r
+/**\r
+ When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not\r
+ given by expression, should save the default info for the Buffer VarStore.\r
+\r
+ @param DefaultId The default id.\r
+ @param pQuestionNode Point to the question opcode node.\r
+ @param Value The default value.\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (\r
+ IN UINT16 DefaultId,\r
+ IN SIfrRecord *pQuestionNode,\r
+ IN EFI_IFR_TYPE_VALUE Value\r
+ )\r
+{\r
+ CHAR8 *VarStoreName = NULL;\r
+ EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
+ EFI_GUID *VarGuid = NULL;\r
+ EFI_VARSTORE_INFO VarInfo;\r
+ EFI_IFR_QUESTION_HEADER *QuestionHead;\r
+ EFI_IFR_OP_HEADER *pQuestionOpHead;\r
+\r
+ pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
+ QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);\r
+\r
+ //\r
+ // Get the Var Store name and type.\r
+ //\r
+ gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);\r
+ VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);\r
+ VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);\r
+\r
+ //\r
+ // Only for Buffer storage need to save the default info in the storage.\r
+ // Other type storage, just return.\r
+ //\r
+ if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {\r
+ return;\r
+ } else {\r
+ VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;\r
+ VarInfo.mVarStoreId = QuestionHead->VarStoreId;\r
+ }\r
+\r
+ //\r
+ // Get the buffer storage info about this question.\r
+ //\r
+ gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);\r
+\r
+ //\r
+ // Add action.\r
+ //\r
+ gCVfrDefaultStore.BufferVarStoreAltConfigAdd (\r
+ DefaultId,\r
+ VarInfo,\r
+ VarStoreName,\r
+ VarGuid,\r
+ VarInfo.mVarType,\r
+ Value\r
+ );\r
+}\r
+\r
+/**\r
+ Record the number and default id of all defaultstore opcode.\r
+\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrGetDefaultStoreInfo (\r
+ VOID\r
+ )\r
+{\r
+ SIfrRecord *pNode;\r
+ EFI_IFR_OP_HEADER *pOpHead;\r
+ EFI_IFR_DEFAULTSTORE *DefaultStore;\r
+\r
+ pNode = mIfrRecordListHead;\r
+ mAllDefaultTypeCount = 0;\r
+\r
+ while (pNode != NULL) {\r
+ pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
+\r
+ if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){\r
+ DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;\r
+ mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;\r
+ }\r
+ pNode = pNode->mNext;\r
+ }\r
+}\r
+\r
+/**\r
+ Create new default opcode record.\r
+\r
+ @param Size The new default opcode size.\r
+ @param DefaultId The new default id.\r
+ @param Type The new default type.\r
+ @param LineNo The line number of the new record.\r
+ @param Value The new default value.\r
+\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrCreateDefaultRecord(\r
+ IN UINT8 Size,\r
+ IN UINT16 DefaultId,\r
+ IN UINT8 Type,\r
+ IN UINT32 LineNo,\r
+ IN EFI_IFR_TYPE_VALUE Value\r
+ )\r
+{\r
+ CIfrDefault *DObj;\r
+ CIfrDefault2 *DObj2;\r
+\r
+ DObj = NULL;\r
+ DObj2 = NULL;\r
+\r
+ if (Type == EFI_IFR_TYPE_OTHER) {\r
+ DObj2 = new CIfrDefault2 (Size);\r
+ DObj2->SetDefaultId(DefaultId);\r
+ DObj2->SetType(Type);\r
+ DObj2->SetLineNo(LineNo);\r
+ DObj2->SetScope (1);\r
+ delete DObj2;\r
+ } else {\r
+ DObj = new CIfrDefault (Size);\r
+ DObj->SetDefaultId(DefaultId);\r
+ DObj->SetType(Type);\r
+ DObj->SetLineNo(LineNo);\r
+ DObj->SetValue (Value);\r
+ delete DObj;\r
+ }\r
+}\r
+\r
+/**\r
+ Create new default opcode for question base on the QuestionDefaultInfo.\r
+\r
+ @param pQuestionNode Point to the question opcode Node.\r
+ @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.\r
+\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrCreateDefaultForQuestion (\r
+ IN SIfrRecord *pQuestionNode,\r
+ IN QuestionDefaultRecord *QuestionDefaultInfo\r
+ )\r
+{\r
+ EFI_IFR_OP_HEADER *pOpHead;\r
+ EFI_IFR_DEFAULT *Default;\r
+ SIfrRecord *pSNode;\r
+ SIfrRecord *pENode;\r
+ SIfrRecord *pDefaultNode;\r
+ CIfrObj *Obj;\r
+ CHAR8 *ObjBinBuf;\r
+ UINT8 ScopeCount;\r
+ UINT8 OpcodeNumber;\r
+ UINT8 OpcodeCount;\r
+ UINT8 DefaultSize;\r
+ EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;\r
+ EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;\r
+\r
+ CheckBoxDefaultValue.b = 1;\r
+ pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;\r
+ ScopeCount = 0;\r
+ OpcodeCount = 0;\r
+ Obj = NULL;\r
+\r
+ //\r
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
+ //\r
+ gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;\r
+ //\r
+ // Case 1:\r
+ // For oneof, the default with smallest default id is given by the option flag.\r
+ // So create the missing defaults base on the oneof option value(mDefaultValueRecord).\r
+ //\r
+ if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
+ DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;\r
+ DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);\r
+ DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);\r
+ //\r
+ // Save the new created default in the buffer storage.\r
+ //\r
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Case2:\r
+ // For checkbox, the default with smallest default id is given by the question flag.\r
+ // And create the missing defaults with true value.\r
+ //\r
+ if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {\r
+ DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);\r
+ //\r
+ // Save the new created default.\r
+ //\r
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Case3:\r
+ // The default with smallest default id is given by the default opcode.\r
+ // So create the missing defaults base on the value in the default opcode.\r
+ //\r
+\r
+ //\r
+ // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.\r
+ //\r
+ pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;\r
+ Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;\r
+ //\r
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
+ //\r
+ gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;\r
+\r
+ if (Default->Type == EFI_IFR_TYPE_OTHER) {\r
+ //\r
+ // EFI_IFR_DEFAULT_2 opcode.\r
+ //\r
+ // Point to the first expression opcode.\r
+ //\r
+ pSNode = pDefaultNode->mNext;\r
+ pENode = NULL;\r
+ ScopeCount++;\r
+ //\r
+ // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)\r
+ //\r
+ while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {\r
+ pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
+ if (pOpHead->Scope == 1) {\r
+ ScopeCount++;\r
+ }\r
+ if (pOpHead->OpCode == EFI_IFR_END_OP) {\r
+ ScopeCount--;\r
+ }\r
+ pENode = pSNode;\r
+ pSNode = pSNode->mNext;\r
+ OpcodeCount++;\r
+ }\r
+\r
+ assert (pSNode);\r
+ assert (pENode);\r
+\r
+ //\r
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
+ //\r
+ gAdjustOpcodeOffset = pSNode->mOffset;\r
+ //\r
+ // Create new default opcode node for missing default.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ OpcodeNumber = OpcodeCount;\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);\r
+ //\r
+ // Point to the first expression opcode node.\r
+ //\r
+ pSNode = pDefaultNode->mNext;\r
+ //\r
+ // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.\r
+ //\r
+ while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {\r
+ pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
+ Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);\r
+ assert (Obj != NULL);\r
+ Obj->SetLineNo (pSNode->mLineNo);\r
+ ObjBinBuf = Obj->GetObjBinAddr<CHAR8>();\r
+ memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);\r
+ delete Obj;\r
+ pSNode = pSNode->mNext;\r
+ }\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // EFI_IFR_DEFAULT opcode.\r
+ //\r
+ // Create new default opcode node for missing default.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);\r
+ //\r
+ // Save the new created default in the buffer storage..\r
+ //\r
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Parse the default information in a question, get the QuestionDefaultInfo.\r
+\r
+ @param pQuestionNode Point to the question record Node.\r
+ @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(\r
+ IN SIfrRecord *pQuestionNode,\r
+ OUT QuestionDefaultRecord *QuestionDefaultInfo\r
+ )\r
+{\r
+ SIfrRecord *pSNode;\r
+ EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;\r
+ EFI_IFR_OP_HEADER *pSOpHead;\r
+ EFI_IFR_CHECKBOX *CheckBoxOpcode;\r
+ EFI_IFR_DEFAULT *DefaultOpcode;\r
+ BOOLEAN IsOneOfOpcode;\r
+ UINT16 SmallestDefaultId;\r
+ UINT8 ScopeCount;\r
+\r
+ SmallestDefaultId = 0xffff;\r
+ IsOneOfOpcode = FALSE;\r
+ ScopeCount = 0;\r
+ pSNode = pQuestionNode;\r
+\r
+ //\r
+ // Parse all the opcodes in the Question.\r
+ //\r
+ while (pSNode != NULL) {\r
+ pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
+ //\r
+ // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.\r
+ // Scopes may be nested within other scopes.\r
+ // When finishing parsing a question, the scope count must be zero.\r
+ //\r
+ if (pSOpHead->Scope == 1) {\r
+ ScopeCount++;\r
+ }\r
+ if (pSOpHead->OpCode == EFI_IFR_END_OP) {\r
+ ScopeCount--;\r
+ }\r
+ //\r
+ // Check whether finishing parsing a question.\r
+ //\r
+ if (ScopeCount == 0) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Record the default information in the question.\r
+ //\r
+ switch (pSOpHead->OpCode) {\r
+ case EFI_IFR_ONE_OF_OP:\r
+ IsOneOfOpcode = TRUE;\r
+ break;\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ //\r
+ // The default info of check box may be given by flag.\r
+ // So need to check the flag of check box.\r
+ //\r
+ CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;\r
+ if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {\r
+ //\r
+ // Check whether need to update the smallest default id.\r
+ //\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ }\r
+ //\r
+ // Update the QuestionDefaultInfo.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ QuestionDefaultInfo->mDefaultNumber ++;\r
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {\r
+ //\r
+ // Check whether need to update the smallest default id.\r
+ //\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ }\r
+ //\r
+ // Update the QuestionDefaultInfo.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ QuestionDefaultInfo->mDefaultNumber ++;\r
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ if (!IsOneOfOpcode) {\r
+ //\r
+ // Only check the option in oneof.\r
+ //\r
+ break;\r
+ }\r
+ OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;\r
+ if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
+ //\r
+ // The option is used as the standard default.\r
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
+ //\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
+ }\r
+ //\r
+ // Update the IsDefaultIdExist array in QuestionDefaultInfo.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ QuestionDefaultInfo->mDefaultNumber ++;\r
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {\r
+ //\r
+ // This option is used as the manufacture default.\r
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
+ //\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ QuestionDefaultInfo->mDefaultValueRecord = pSNode;\r
+ }\r
+ //\r
+ // Update the QuestionDefaultInfo.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {\r
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ QuestionDefaultInfo->mDefaultNumber ++;\r
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case EFI_IFR_DEFAULT_OP:\r
+ DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;\r
+ //\r
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.\r
+ //\r
+ if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {\r
+ SmallestDefaultId = DefaultOpcode->DefaultId;\r
+ QuestionDefaultInfo->mDefaultValueRecord= pSNode;\r
+ QuestionDefaultInfo->mIsDefaultOpcode= TRUE;\r
+ }\r
+ //\r
+ // Update the QuestionDefaultInfo.\r
+ //\r
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){\r
+ if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {\r
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {\r
+ QuestionDefaultInfo->mDefaultNumber ++;\r
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ //\r
+ // Parse next opcode in this question.\r
+ //\r
+ pSNode = pSNode->mNext;\r
+ }\r
+}\r
+\r
+/**\r
+ Check or add default for question if need.\r
+\r
+ This function will check the default info for question.\r
+ If the question has default, but the default number < defaultstore opcode number.\r
+ will do following two action :\r
+\r
+ 1. if (AutoDefault) will add default for question to support all kinds of defaults.\r
+ 2. if (CheckDefault) will generate an error to tell user the question misses some default value.\r
+\r
+ We assume that the two options can not be TRUE at same time.\r
+ If they are TRUE at same time, only do the action corresponding to AutoDefault option.\r
+\r
+ @param AutoDefault Add default for question if needed\r
+ @param CheckDefault Check the default info, if missing default, generates an error.\r
+\r
+**/\r
+VOID\r
+CIfrRecordInfoDB::IfrCheckAddDefaultRecord (\r
+ BOOLEAN AutoDefault,\r
+ BOOLEAN CheckDefault\r
+ )\r
+{\r
+ SIfrRecord *pNode;\r
+ SIfrRecord *pTailNode;\r
+ SIfrRecord *pStartAdjustNode;\r
+ EFI_IFR_OP_HEADER *pOpHead;\r
+ QuestionDefaultRecord QuestionDefaultInfo;\r
+ UINT8 MissingDefaultCount;\r
+ CHAR8 Msg[MAX_STRING_LEN] = {0, };\r
+\r
+ pNode = mIfrRecordListHead;\r
+\r
+ //\r
+ // Record the number and default id of all defaultstore opcode.\r
+ //\r
+ IfrGetDefaultStoreInfo ();\r
+\r
+ while (pNode != NULL) {\r
+ pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
+ //\r
+ // Check whether is question opcode.\r
+ //\r
+ if (CheckQuestionOpCode (pOpHead->OpCode)) {\r
+ //\r
+ // Initialize some local variables here, because they vary with question.\r
+ // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.\r
+ //\r
+ memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));\r
+ pTailNode = mIfrRecordListTail;\r
+ //\r
+ // Get the QuestionDefaultInfo for current question.\r
+ //\r
+ IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);\r
+\r
+ if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {\r
+ if (AutoDefault) {\r
+ //\r
+ // Create default for question which misses default.\r
+ //\r
+ IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);\r
+\r
+ //\r
+ // Adjust the buffer content.\r
+ // pStartAdjustNode->mIfrBinBuf points to the insert position.\r
+ // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.\r
+ //\r
+ pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);\r
+ gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);\r
+\r
+ //\r
+ // Update the record info.\r
+ //\r
+ IfrUpdateRecordInfoForDynamicOpcode (TRUE);\r
+ } else if (CheckDefault) {\r
+ //\r
+ // Generate an error for question which misses default.\r
+ //\r
+ MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;\r
+ sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);\r
+ gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // parse next opcode.\r
+ //\r
+ pNode = pNode->mNext;\r
+ }\r
+}\r
+\r
CIfrRecordInfoDB gCIfrRecordInfoDB;\r
\r
VOID\r
)\r
{\r
CHAR8 *ObjBinBuf = NULL;\r
- \r
+\r
//\r
// do nothing\r
//\r
//\r
ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
if (ObjBinBuf != NULL) {\r
- memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
+ memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
}\r
- \r
+\r
//\r
// update bin buffer to package data buffer\r
//\r
if (mObjBinBuf != NULL) {\r
- delete mObjBinBuf;\r
+ delete[] mObjBinBuf;\r
mObjBinBuf = ObjBinBuf;\r
}\r
- \r
+\r
mDelayEmit = FALSE;\r
}\r
\r
{ sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61\r
{ sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
{ sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63\r
+ { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64\r
};\r
\r
#ifdef CIFROBJ_DEUBG\r
"EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
"EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
"EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
- "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF",\r
+ "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",\r
};\r
\r
VOID\r
mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+ mLineNo = 0;\r
+\r
+ assert (mObjBinBuf != NULL);\r
\r
if (IfrObj != NULL) {\r
*IfrObj = mObjBinBuf;\r