]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
index 87da95af715c76f7eab6c218f1947a34c4b547a4..2944ffc76b9c30b13b277bd5d4dbfff71c4dbc72 100644 (file)
@@ -1,19 +1,20 @@
 /** @file\r
-  \r
+\r
   The definition of CFormPkg's member function\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation                                                         \r
-All rights reserved. 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
+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
 \r
 **/\r
 \r
 #include "stdio.h"\r
+#include "assert.h"\r
 #include "VfrFormPkg.h"\r
 \r
 /*\r
@@ -21,11 +22,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  */\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 CHAR8  *Msg\r
+  IN CONST CHAR8  *Msg\r
   )\r
 {\r
   mKey    = NULL;\r
@@ -55,20 +56,20 @@ SPendingAssign::~SPendingAssign (
   )\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
@@ -78,11 +79,11 @@ SPendingAssign::SetAddrAndLen (
 \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
@@ -95,7 +96,7 @@ SPendingAssign::GetKey (
 }\r
 \r
 CFormPkg::CFormPkg (\r
-  IN UINT32 BufferSize = 4096\r
+  IN UINT32 BufferSize\r
   )\r
 {\r
   CHAR8       *BufferStart;\r
@@ -103,8 +104,13 @@ CFormPkg::CFormPkg (
   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
@@ -112,6 +118,7 @@ CFormPkg::CFormPkg (
   }\r
   BufferStart = new CHAR8[BufferSize];\r
   if (BufferStart == NULL) {\r
+    delete Node;\r
     return;\r
   }\r
   BufferEnd   = BufferStart + BufferSize;\r
@@ -137,7 +144,7 @@ CFormPkg::~CFormPkg ()
     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
@@ -152,12 +159,39 @@ CFormPkg::~CFormPkg ()
   PendingAssignList = NULL;\r
 }\r
 \r
+SBufferNode *\r
+CFormPkg::CreateNewNode (\r
+  VOID\r
+  )\r
+{\r
+  SBufferNode *Node;\r
+\r
+  Node = new SBufferNode;\r
+  if (Node == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Node->mBufferStart = new CHAR8[mBufferSize];\r
+  if (Node->mBufferStart == NULL) {\r
+    delete Node;\r
+    return NULL;\r
+  } else {\r
+    memset (Node->mBufferStart, 0, mBufferSize);\r
+    Node->mBufferEnd  = Node->mBufferStart + mBufferSize;\r
+    Node->mBufferFree = Node->mBufferStart;\r
+    Node->mNext       = NULL;\r
+  }\r
+\r
+  return Node;\r
+}\r
+\r
 CHAR8 *\r
 CFormPkg::IfrBinBufferGet (\r
   IN UINT32 Len\r
   )\r
 {\r
-  CHAR8 *BinBuffer = NULL;\r
+  CHAR8       *BinBuffer = NULL;\r
+  SBufferNode *Node      = NULL;\r
 \r
   if ((Len == 0) || (Len > mBufferSize)) {\r
     return NULL;\r
@@ -167,24 +201,11 @@ CFormPkg::IfrBinBufferGet (
     BinBuffer = mCurrBufferNode->mBufferFree;\r
     mCurrBufferNode->mBufferFree += Len;\r
   } else {\r
-    SBufferNode *Node;\r
-\r
-    Node = new SBufferNode;\r
+    Node = CreateNewNode ();\r
     if (Node == NULL) {\r
       return NULL;\r
     }\r
 \r
-    Node->mBufferStart = new CHAR8[mBufferSize];\r
-    if (Node->mBufferStart == NULL) {\r
-      delete Node;\r
-      return NULL;\r
-    } else {\r
-      memset (Node->mBufferStart, 0, mBufferSize);\r
-      Node->mBufferEnd  = Node->mBufferStart + mBufferSize;\r
-      Node->mBufferFree = Node->mBufferStart;\r
-      Node->mNext       = NULL;\r
-    }\r
-\r
     if (mBufferNodeQueueTail == NULL) {\r
       mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
     } else {\r
@@ -234,7 +255,7 @@ CFormPkg::Close (
 \r
 UINT32\r
 CFormPkg::Read (\r
-  IN CHAR8     *Buffer, \r
+  IN CHAR8     *Buffer,\r
   IN UINT32    Size\r
   )\r
 {\r
@@ -245,7 +266,7 @@ CFormPkg::Read (
   }\r
 \r
   if (mReadBufferNode == NULL) {\r
-       return 0;\r
+    return 0;\r
   }\r
 \r
   for (Index = 0; Index < Size; Index++) {\r
@@ -256,7 +277,7 @@ CFormPkg::Read (
         return Index;\r
       } else {\r
         mReadBufferOffset = 0;\r
-        Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+        Index --;\r
       }\r
     }\r
   }\r
@@ -288,7 +309,7 @@ CFormPkg::BuildPkg (
   OUT PACKAGE_DATA &TBuffer\r
   )\r
 {\r
-  \r
+\r
   CHAR8  *Temp;\r
   UINT32 Size;\r
   CHAR8  Buffer[1024];\r
@@ -336,7 +357,7 @@ CFormPkg::BuildPkg (
   }\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
@@ -352,11 +373,11 @@ CFormPkg::BuildPkg (
 \r
 VOID\r
 CFormPkg::_WRITE_PKG_LINE (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -375,11 +396,11 @@ CFormPkg::_WRITE_PKG_LINE (
 \r
 VOID\r
 CFormPkg::_WRITE_PKG_END (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -402,8 +423,11 @@ CFormPkg::_WRITE_PKG_END (
 }\r
 \r
 #define BYTES_PRE_LINE 0x10\r
+UINT32   gAdjustOpcodeOffset = 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
@@ -430,24 +454,24 @@ CFormPkg::GenCFile (
   // 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
@@ -479,11 +503,11 @@ CFormPkg::GenCFile (
 \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 CHAR8  *Msg\r
+  IN CONST CHAR8  *Msg\r
   )\r
 {\r
   SPendingAssign *pNew;\r
@@ -500,8 +524,8 @@ CFormPkg::AssignPending (
 \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
@@ -548,43 +572,288 @@ CFormPkg::PendingAssignPrintAll (
   }\r
 }\r
 \r
+SBufferNode *\r
+CFormPkg::GetBinBufferNodeForAddr (\r
+  IN CHAR8              *BinBuffAddr\r
+  )\r
+{\r
+  SBufferNode *TmpNode;\r
+\r
+  TmpNode = mBufferNodeQueueHead;\r
+\r
+  while (TmpNode != NULL) {\r
+    if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {\r
+      return TmpNode;\r
+    }\r
+\r
+    TmpNode = TmpNode->mNext;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+SBufferNode *\r
+CFormPkg::GetNodeBefore(\r
+  IN SBufferNode *CurrentNode\r
+  )\r
+{\r
+  SBufferNode *FirstNode   = mBufferNodeQueueHead;\r
+  SBufferNode *LastNode    = mBufferNodeQueueHead;\r
+\r
+  while (FirstNode != NULL) {\r
+    if (FirstNode == CurrentNode) {\r
+      break;\r
+    }\r
+\r
+    LastNode    = FirstNode;\r
+    FirstNode   = FirstNode->mNext;\r
+  }\r
+\r
+  if (FirstNode == NULL) {\r
+    LastNode = NULL;\r
+  }\r
+\r
+  return LastNode;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::InsertNodeBefore(\r
+  IN SBufferNode *CurrentNode,\r
+  IN SBufferNode *NewNode\r
+  )\r
+{\r
+  SBufferNode *LastNode = GetNodeBefore (CurrentNode);\r
+\r
+  if (LastNode == NULL) {\r
+    return VFR_RETURN_MISMATCHED;\r
+  }\r
+\r
+  NewNode->mNext = LastNode->mNext;\r
+  LastNode->mNext = NewNode;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+CHAR8 *\r
+CFormPkg::GetBufAddrBaseOnOffset (\r
+  IN UINT32      Offset\r
+  )\r
+{\r
+  SBufferNode *TmpNode;\r
+  UINT32      TotalBufLen;\r
+  UINT32      CurrentBufLen;\r
+\r
+  TotalBufLen = 0;\r
+\r
+  for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {\r
+    CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;\r
+    if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {\r
+      return TmpNode->mBufferStart + (Offset - TotalBufLen);\r
+    }\r
+\r
+    TotalBufLen += CurrentBufLen;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::AdjustDynamicInsertOpcode (\r
+  IN CHAR8              *InserPositionAddr,\r
+  IN CHAR8              *InsertOpcodeAddr,\r
+  IN BOOLEAN            CreateOpcodeAfterParsingVfr\r
+  )\r
+{\r
+  SBufferNode *InserPositionNode;\r
+  SBufferNode *InsertOpcodeNode;\r
+  SBufferNode *NewRestoreNodeBegin;\r
+  SBufferNode *NewRestoreNodeEnd;\r
+  SBufferNode *NewLastEndNode;\r
+  SBufferNode *TmpNode;\r
+  UINT32      NeedRestoreCodeLen;\r
+\r
+  NewRestoreNodeEnd = NULL;\r
+\r
+  InserPositionNode  = GetBinBufferNodeForAddr(InserPositionAddr);\r
+  InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
+  assert (InserPositionNode != NULL);\r
+  assert (InsertOpcodeNode  != NULL);\r
+\r
+  if (InserPositionNode == InsertOpcodeNode) {\r
+    //\r
+    // Create New Node to save the restore opcode.\r
+    //\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, InserPositionAddr, NeedRestoreCodeLen);\r
+    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
+\r
+    //\r
+    // Override the restore buffer data.\r
+    //\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 = 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, InserPositionAddr, NeedRestoreCodeLen);\r
+    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
+    //\r
+    // Override the restore buffer data.\r
+    //\r
+    InserPositionNode->mBufferFree -= NeedRestoreCodeLen;\r
+    //\r
+    // Link the restore data to new node.\r
+    //\r
+    NewRestoreNodeBegin->mNext = InserPositionNode->mNext;\r
+\r
+    //\r
+    // Count the Adjust opcode len.\r
+    //\r
+    TmpNode = InserPositionNode->mNext;\r
+    while (TmpNode != InsertOpcodeNode) {\r
+      gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;\r
+      TmpNode = TmpNode->mNext;\r
+    }\r
+\r
+    //\r
+    // Create New Node to save the last node of restore opcode.\r
+    //\r
+    NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
+    gAdjustOpcodeLen  += NeedRestoreCodeLen;\r
+    if (NeedRestoreCodeLen > 0) {\r
+      NewRestoreNodeEnd = CreateNewNode ();\r
+      if (NewRestoreNodeEnd == NULL) {\r
+        return VFR_RETURN_OUT_FOR_RESOURCES;\r
+      }\r
+      memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);\r
+      NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;\r
+      //\r
+      // Override the restore buffer data.\r
+      //\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
+      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 after InserPositionNode.\r
+      //\r
+      InserPositionNode->mNext = InsertOpcodeNode;\r
+    }\r
+  }\r
+\r
+  if (CreateOpcodeAfterParsingVfr) {\r
+    //\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
+    mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
+    if (NewRestoreNodeEnd != NULL) {\r
+      mBufferNodeQueueTail = NewRestoreNodeEnd;\r
+    } else {\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->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
+  mCurrBufferNode = mBufferNodeQueueTail;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CFormPkg::DeclarePendingQuestion (\r
   IN CVfrVarDataTypeDB   &lCVfrVarDataTypeDB,\r
   IN CVfrDataStorage     &lCVfrDataStorage,\r
   IN CVfrQuestionDB      &lCVfrQuestionDB,\r
   IN EFI_GUID            *LocalFormSetGuid,\r
-  IN UINT32 LineNo\r
+  IN UINT32              LineNo,\r
+  OUT CHAR8              **InsertOpcodeAddr\r
   )\r
 {\r
   SPendingAssign *pNode;\r
   CHAR8          *VarStr;\r
   UINT32         ArrayIdx;\r
   CHAR8          FName[MAX_NAME_LEN];\r
+  CHAR8          *SName;\r
+  CHAR8          *NewStr;\r
+  UINT32         ShrinkSize = 0;\r
   EFI_VFR_RETURN_CODE  ReturnCode;\r
   EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;\r
+  UINT8    LFlags;\r
+  UINT32   MaxValue;\r
+  CIfrGuid *GuidObj = NULL;\r
 \r
-  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (pNode->mFlag == PENDING) {\r
-      //\r
-      //  declare this question as Numeric in SuppressIf True\r
-      //\r
-      // SuppressIf\r
-      CIfrSuppressIf SIObj;\r
-      SIObj.SetLineNo (LineNo);\r
-      \r
-      //TrueOpcode\r
-      CIfrTrue TObj (LineNo);\r
-      \r
-      //Numeric qeustion\r
-      CIfrNumeric CNObj;\r
-      EFI_VARSTORE_INFO Info; \r
-         EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;\r
+  //\r
+  // Declare all questions as Numeric in DisableIf True\r
+  //\r
+  // DisableIf\r
+  CIfrDisableIf DIObj;\r
+  DIObj.SetLineNo (LineNo);\r
+  *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();\r
 \r
-      CNObj.SetLineNo (LineNo);\r
-      CNObj.SetPrompt (0x0);\r
-      CNObj.SetHelp (0x0);\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
+      EFI_VARSTORE_INFO Info;\r
+      EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;\r
       //\r
       // Register this question, assume it is normal question, not date or time question\r
       //\r
@@ -594,7 +863,7 @@ CFormPkg::DeclarePendingQuestion (
         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
@@ -609,37 +878,30 @@ CFormPkg::DeclarePendingQuestion (
       //\r
       // Get VarStoreType\r
       //\r
-      ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);\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.GetVarStoreType (FName, VarStoreType);  \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
-      \r
       ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\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
 \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
-          ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
+          //convert VarStr with store name to VarStr with structure name\r
+          ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
+          if (ReturnCode == VFR_RETURN_SUCCESS) {\r
+            NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\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, Info.mIsBitVar);\r
+            delete[] NewStr;\r
+          }\r
         } else {\r
           ReturnCode = VFR_RETURN_UNSUPPORTED;\r
         }\r
@@ -648,32 +910,99 @@ CFormPkg::DeclarePendingQuestion (
         gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
         return ReturnCode;\r
       }\r
+      //\r
+      // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.\r
+      //\r
+      if (Info.mIsBitVar) {\r
+        GuidObj = new CIfrGuid(0);\r
+        GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);\r
+        GuidObj->SetLineNo(LineNo);\r
+      }\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
-      CNObj.SetFlags (0, Info.mVarType);\r
+\r
+      //\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
+      if (Info.mIsBitVar) {\r
+        MaxValue = (1 << Info.mVarTotalSize) -1;\r
+        CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);\r
+        ShrinkSize = 12;\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 vaild 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
       // For undefined Efi VarStore type question\r
       // Append the extended guided opcode to contain VarName\r
       //\r
-      if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
+      if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
         CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
         CVNObj.SetLineNo (LineNo);\r
       }\r
-      \r
+\r
       //\r
       // End for Numeric\r
       //\r
-      CIfrEnd CEObj; \r
+      CIfrEnd CEObj;\r
       CEObj.SetLineNo (LineNo);\r
       //\r
-      // End for SuppressIf\r
+      // End for Guided opcode\r
       //\r
-      CIfrEnd SEObj;\r
-      SEObj.SetLineNo (LineNo);\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
+  //\r
+  // End for DisableIf\r
+  //\r
+  CIfrEnd SEObj;\r
+  SEObj.SetLineNo (LineNo);\r
+\r
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
@@ -712,6 +1041,10 @@ CIfrRecordInfoDB::CIfrRecordInfoDB (
   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
@@ -816,10 +1149,10 @@ CIfrRecordInfoDB::IfrRecordOutput (
   )\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
@@ -828,18 +1161,18 @@ CIfrRecordInfoDB::IfrRecordOutput (
 \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
@@ -849,8 +1182,8 @@ CIfrRecordInfoDB::IfrRecordOutput (
     }\r
   }\r
 \r
-  return;   \r
-}   \r
+  return;\r
+}\r
 \r
 VOID\r
 CIfrRecordInfoDB::IfrRecordOutput (\r
@@ -884,7 +1217,7 @@ CIfrRecordInfoDB::IfrRecordOutput (
       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
@@ -910,6 +1243,7 @@ CIfrRecordInfoDB::CheckQuestionOpCode (
   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
@@ -924,13 +1258,13 @@ CIfrRecordInfoDB::CheckIdOpCode (
   switch (OpCode) {\r
   case EFI_IFR_EQ_ID_VAL_OP:\r
   case EFI_IFR_EQ_ID_ID_OP:\r
-  case EFI_IFR_EQ_ID_LIST_OP:\r
+  case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
   case EFI_IFR_QUESTION_REF1_OP:\r
     return TRUE;\r
   default:\r
     return FALSE;\r
   }\r
-} \r
+}\r
 \r
 EFI_QUESTION_ID\r
 CIfrRecordInfoDB::GetOpcodeQuestionId (\r
@@ -938,60 +1272,216 @@ CIfrRecordInfoDB::GetOpcodeQuestionId (
   )\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
-EFI_VFR_RETURN_CODE\r
-CIfrRecordInfoDB::IfrRecordAdjust (\r
-  VOID\r
+SIfrRecord *\r
+CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNode = NULL;\r
+\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mOffset == Offset) {\r
+      return pNode;\r
+    }\r
+  }\r
+\r
+  return pNode;\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
+  |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|\r
+\r
+  To\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
+  IN BOOLEAN  CreateOpcodeAfterParsingVfr\r
   )\r
 {\r
-  SIfrRecord *pNode, *preNode;\r
-  SIfrRecord *uNode, *tNode;\r
-  EFI_IFR_OP_HEADER  *OpHead, *tOpHead;\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
+  SIfrRecord         *pNode, *pPreNode;\r
+  SIfrRecord         *pAdjustNode, *pNodeBeforeAdjust;\r
+  SIfrRecord         *pNodeBeforeDynamic;\r
+\r
+  pPreNode            = NULL;\r
+  pAdjustNode         = NULL;\r
+  pNodeBeforeDynamic  = NULL;\r
+  OpcodeOffset        = 0;\r
 \r
   //\r
-  // Init local variable\r
+  // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,\r
+  // and the node before pDynamicOpcodeNode.\r
   //\r
-  Status = VFR_RETURN_SUCCESS;\r
-  pNode = mIfrRecordListHead;\r
-  preNode = pNode;\r
-  QuestionScope = 0;\r
-  while (pNode != NULL) {\r
-    OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
-    \r
-    //\r
-    // make sure the inconsistent opcode in question scope\r
-    //\r
-    if (QuestionScope > 0) {\r
-      QuestionScope += OpHead->Scope;\r
-      if (OpHead->OpCode == EFI_IFR_END_OP) {\r
-        QuestionScope --;\r
-      }\r
+  for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {\r
+    if (OpcodeOffset == gAdjustOpcodeOffset) {\r
+      pAdjustNode       = pNode;\r
+      pNodeBeforeAdjust = pPreNode;\r
+    } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
+      pNodeBeforeDynamic = pPreNode;\r
     }\r
-    \r
-    if (CheckQuestionOpCode (OpHead->OpCode)) {\r
-      QuestionScope = 1;\r
+    if (pNode->mNext != NULL) {\r
+      pPreNode = pNode;\r
     }\r
-    //\r
-    // for the inconsistent opcode not in question scope, adjust it\r
-    //\r
-    if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
-      //\r
-      // for inconsistent opcode not in question scope\r
+    OpcodeOffset += pNode->mBinBufLen;\r
+  }\r
+\r
+  //\r
+  // Check the nodes whether exist.\r
+  //\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
+  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
+  )\r
+{\r
+  UINT32             OpcodeOffset;\r
+  SIfrRecord         *pNode;\r
+\r
+  OpcodeOffset = 0;\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    pNode->mOffset = OpcodeOffset;\r
+    OpcodeOffset += pNode->mBinBufLen;\r
+  }\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CIfrRecordInfoDB::IfrRecordAdjust (\r
+  VOID\r
+  )\r
+{\r
+  SIfrRecord *pNode, *preNode;\r
+  SIfrRecord *uNode, *tNode;\r
+  EFI_IFR_OP_HEADER  *OpHead, *tOpHead;\r
+  EFI_QUESTION_ID    QuestionId;\r
+  UINT32             StackCount;\r
+  UINT32             QuestionScope;\r
+  CHAR8              ErrorMsg[MAX_STRING_LEN] = {0, };\r
+  EFI_VFR_RETURN_CODE  Status;\r
+\r
+  //\r
+  // Init local variable\r
+  //\r
+  Status = VFR_RETURN_SUCCESS;\r
+  pNode = mIfrRecordListHead;\r
+  preNode = pNode;\r
+  QuestionScope = 0;\r
+  while (pNode != NULL) {\r
+    OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
+\r
+    //\r
+    // make sure the inconsistent opcode in question scope\r
+    //\r
+    if (QuestionScope > 0) {\r
+      QuestionScope += OpHead->Scope;\r
+      if (OpHead->OpCode == EFI_IFR_END_OP) {\r
+        QuestionScope --;\r
+      }\r
+    }\r
+\r
+    if (CheckQuestionOpCode (OpHead->OpCode)) {\r
+      QuestionScope = 1;\r
+    }\r
+    //\r
+    // for the inconsistent opcode not in question scope, adjust it\r
+    //\r
+    if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
+      //\r
+      // for inconsistent opcode not in question scope\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
@@ -1009,7 +1499,7 @@ CIfrRecordInfoDB::IfrRecordAdjust (
         //\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
@@ -1027,13 +1517,13 @@ CIfrRecordInfoDB::IfrRecordAdjust (
       // extract inconsistent opcode list\r
       // pNode is Incosistent 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
@@ -1048,7 +1538,7 @@ CIfrRecordInfoDB::IfrRecordAdjust (
           //\r
           OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
         }\r
-        \r
+\r
         //\r
         // skip the default storage for Date and Time\r
         //\r
@@ -1075,7 +1565,7 @@ CIfrRecordInfoDB::IfrRecordAdjust (
         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
@@ -1083,9 +1573,9 @@ CIfrRecordInfoDB::IfrRecordAdjust (
       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
@@ -1093,22 +1583,22 @@ CIfrRecordInfoDB::IfrRecordAdjust (
       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
@@ -1149,22 +1639,597 @@ CIfrRecordInfoDB::IfrRecordAdjust (
     // 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
   if (Status == VFR_RETURN_SUCCESS) {\r
-    OpcodeOffset = 0;\r
-    for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
-      pNode->mOffset = OpcodeOffset;\r
-      OpcodeOffset += pNode->mBinBufLen;\r
-    }\r
+    IfrAdjustOffsetForRecord ();\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
@@ -1173,7 +2238,7 @@ CIfrObj::_EMIT_PENDING_OBJ (
   )\r
 {\r
   CHAR8  *ObjBinBuf = NULL;\r
-  \r
+\r
   //\r
   // do nothing\r
   //\r
@@ -1187,17 +2252,17 @@ CIfrObj::_EMIT_PENDING_OBJ (
   //\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
@@ -1242,7 +2307,7 @@ static struct {
   { 0, 0 },                                    // 0x1F\r
   { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20\r
   { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21\r
-  { 0, 0 },                                    // 0x22\r
+  { sizeof (EFI_IFR_MAP), 1 },                 // EFI_IFR_MAP - 0x22\r
   { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23\r
   { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP\r
   { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
@@ -1250,8 +2315,11 @@ static struct {
   { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP\r
   { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28\r
   { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP\r
-  { sizeof (EFI_IFR_MATCH), 1 },               // EFI_IFR_MATCH_OP - 0x2A\r
-  { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} ,      // 0x2B ~ 0x2E\r
+  { sizeof (EFI_IFR_MATCH), 0 },               // EFI_IFR_MATCH_OP - 0x2A\r
+  { sizeof (EFI_IFR_GET), 0 },                 // EFI_IFR_GET - 0x2B\r
+  { sizeof (EFI_IFR_SET), 0 },                 // EFI_IFR_SET - 0x2C\r
+  { sizeof (EFI_IFR_READ), 0 },                // EFI_IFR_READ - 0x2D\r
+  { sizeof (EFI_IFR_WRITE), 0 },               // EFI_IFR_WRITE - 0x2E\r
   { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F\r
   { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP\r
   { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP\r
@@ -1298,9 +2366,14 @@ static struct {
   { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP\r
   { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP\r
   { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
-  { 0, 0},                                     // 0x5D\r
+  { sizeof (EFI_IFR_FORM_MAP), 1},             // EFI_IFR_FORM_MAP_OP - 0x5D\r
   { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP\r
   { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP\r
+  { sizeof (EFI_IFR_SECURITY), 0 },            // EFI_IFR_SECURITY_OP - 0x60\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
@@ -1312,9 +2385,9 @@ static struct {
   "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",\r
   "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",\r
   "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",\r
-  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_INVALID",       "EFI_IFR_ORDERED_LIST",\r
+  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_MAP",           "EFI_IFR_ORDERED_LIST",\r
   "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",\r
-  "EFI_IFR_MATCH",      "EFI_IFR_INVALID",              "EFI_IFR_INVALID",       "EFI_IFR_INVALID",         "EFI_IFR_INVALID",       "EFI_IFR_EQUAL",\r
+  "EFI_IFR_MATCH",      "EFI_IFR_GET",                  "EFI_IFR_SET",           "EFI_IFR_READ",            "EFI_IFR_WRITE",         "EFI_IFR_EQUAL",\r
   "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",\r
   "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",\r
   "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
@@ -1322,7 +2395,8 @@ static struct {
   "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",\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_INVALID",         "EFI_IFR_CATENATE",      "EFI_IFR_GUID",\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",      "EFI_IFR_MATCH2",\r
 };\r
 \r
 VOID\r
@@ -1338,7 +2412,7 @@ CIFROBJ_DEBUG_PRINT (
 \r
 #endif\r
 \r
-bool gCreateOp = TRUE;\r
+BOOLEAN gCreateOp = TRUE;\r
 \r
 CIfrObj::CIfrObj (\r
   IN  UINT8   OpCode,\r
@@ -1352,6 +2426,9 @@ CIfrObj::CIfrObj (
   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
@@ -1394,4 +2471,4 @@ CIfrOpHeader::CIfrOpHeader (
   mHeader = OpHdr.mHeader;\r
 }\r
 \r
-UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r
+UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r