Home | History | Annotate | Download | only in VfrCompile
      1 /** @file
      2 
      3   The definition of CFormPkg's member function
      4 
      5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "stdio.h"
     17 #include "assert.h"
     18 #include "VfrFormPkg.h"
     19 
     20 /*
     21  * The definition of CFormPkg's member function
     22  */
     23 
     24 SPendingAssign::SPendingAssign (
     25   IN CHAR8  *Key,
     26   IN VOID   *Addr,
     27   IN UINT32 Len,
     28   IN UINT32 LineNo,
     29   IN CONST CHAR8  *Msg
     30   )
     31 {
     32   mKey    = NULL;
     33   mAddr   = Addr;
     34   mLen    = Len;
     35   mFlag   = PENDING;
     36   mLineNo = LineNo;
     37   mMsg    = NULL;
     38   mNext   = NULL;
     39   if (Key != NULL) {
     40     mKey = new CHAR8[strlen (Key) + 1];
     41     if (mKey != NULL) {
     42       strcpy (mKey, Key);
     43     }
     44   }
     45 
     46   if (Msg != NULL) {
     47     mMsg = new CHAR8[strlen (Msg) + 1];
     48     if (mMsg != NULL) {
     49       strcpy (mMsg, Msg);
     50     }
     51   }
     52 }
     53 
     54 SPendingAssign::~SPendingAssign (
     55   VOID
     56   )
     57 {
     58   if (mKey != NULL) {
     59     delete[] mKey;
     60   }
     61   mAddr   = NULL;
     62   mLen    = 0;
     63   mLineNo = 0;
     64   if (mMsg != NULL) {
     65     delete[] mMsg;
     66   }
     67   mNext   = NULL;
     68 }
     69 
     70 VOID
     71 SPendingAssign::SetAddrAndLen (
     72   IN VOID   *Addr,
     73   IN UINT32 LineNo
     74   )
     75 {
     76   mAddr   = Addr;
     77   mLineNo = LineNo;
     78 }
     79 
     80 VOID
     81 SPendingAssign::AssignValue (
     82   IN VOID   *Addr,
     83   IN UINT32 Len
     84   )
     85 {
     86   memmove (mAddr, Addr, (mLen < Len ? mLen : Len));
     87   mFlag = ASSIGNED;
     88 }
     89 
     90 CHAR8 *
     91 SPendingAssign::GetKey (
     92   VOID
     93   )
     94 {
     95   return mKey;
     96 }
     97 
     98 CFormPkg::CFormPkg (
     99   IN UINT32 BufferSize
    100   )
    101 {
    102   CHAR8       *BufferStart;
    103   CHAR8       *BufferEnd;
    104   SBufferNode *Node;
    105 
    106   mPkgLength           = 0;
    107   mBufferNodeQueueHead = NULL;
    108   mCurrBufferNode      = NULL;
    109 
    110   Node = new SBufferNode;
    111   if (Node == NULL) {
    112     return ;
    113   }
    114   BufferStart = new CHAR8[BufferSize];
    115   if (BufferStart == NULL) {
    116     delete Node;
    117     return;
    118   }
    119   BufferEnd   = BufferStart + BufferSize;
    120 
    121   memset (BufferStart, 0, BufferSize);
    122   Node->mBufferStart   = BufferStart;
    123   Node->mBufferEnd     = BufferEnd;
    124   Node->mBufferFree    = BufferStart;
    125   Node->mNext          = NULL;
    126 
    127   mBufferSize          = BufferSize;
    128   mBufferNodeQueueHead = Node;
    129   mBufferNodeQueueTail = Node;
    130   mCurrBufferNode      = Node;
    131 }
    132 
    133 CFormPkg::~CFormPkg ()
    134 {
    135   SBufferNode    *pBNode;
    136   SPendingAssign *pPNode;
    137 
    138   while (mBufferNodeQueueHead != NULL) {
    139     pBNode = mBufferNodeQueueHead;
    140     mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
    141     if (pBNode->mBufferStart != NULL) {
    142       delete pBNode->mBufferStart;
    143       delete pBNode;
    144     }
    145   }
    146   mBufferNodeQueueTail = NULL;
    147   mCurrBufferNode      = NULL;
    148 
    149   while (PendingAssignList != NULL) {
    150     pPNode = PendingAssignList;
    151     PendingAssignList = PendingAssignList->mNext;
    152     delete pPNode;
    153   }
    154   PendingAssignList = NULL;
    155 }
    156 
    157 SBufferNode *
    158 CFormPkg::CreateNewNode (
    159   VOID
    160   )
    161 {
    162   SBufferNode *Node;
    163 
    164   Node = new SBufferNode;
    165   if (Node == NULL) {
    166     return NULL;
    167   }
    168 
    169   Node->mBufferStart = new CHAR8[mBufferSize];
    170   if (Node->mBufferStart == NULL) {
    171     delete Node;
    172     return NULL;
    173   } else {
    174     memset (Node->mBufferStart, 0, mBufferSize);
    175     Node->mBufferEnd  = Node->mBufferStart + mBufferSize;
    176     Node->mBufferFree = Node->mBufferStart;
    177     Node->mNext       = NULL;
    178   }
    179 
    180   return Node;
    181 }
    182 
    183 CHAR8 *
    184 CFormPkg::IfrBinBufferGet (
    185   IN UINT32 Len
    186   )
    187 {
    188   CHAR8       *BinBuffer = NULL;
    189   SBufferNode *Node      = NULL;
    190 
    191   if ((Len == 0) || (Len > mBufferSize)) {
    192     return NULL;
    193   }
    194 
    195   if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
    196     BinBuffer = mCurrBufferNode->mBufferFree;
    197     mCurrBufferNode->mBufferFree += Len;
    198   } else {
    199     Node = CreateNewNode ();
    200     if (Node == NULL) {
    201       return NULL;
    202     }
    203 
    204     if (mBufferNodeQueueTail == NULL) {
    205       mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
    206     } else {
    207       mBufferNodeQueueTail->mNext = Node;
    208       mBufferNodeQueueTail = Node;
    209     }
    210     mCurrBufferNode = Node;
    211 
    212     //
    213     // Now try again.
    214     //
    215     BinBuffer = mCurrBufferNode->mBufferFree;
    216     mCurrBufferNode->mBufferFree += Len;
    217   }
    218 
    219   mPkgLength += Len;
    220 
    221   return BinBuffer;
    222 }
    223 
    224 inline
    225 UINT32
    226 CFormPkg::GetPkgLength (
    227   VOID
    228   )
    229 {
    230   return mPkgLength;
    231 }
    232 
    233 VOID
    234 CFormPkg::Open (
    235   VOID
    236   )
    237 {
    238   mReadBufferNode   = mBufferNodeQueueHead;
    239   mReadBufferOffset = 0;
    240 }
    241 
    242 VOID
    243 CFormPkg::Close (
    244   VOID
    245   )
    246 {
    247   mReadBufferNode   = NULL;
    248   mReadBufferOffset = 0;
    249 }
    250 
    251 UINT32
    252 CFormPkg::Read (
    253   IN CHAR8     *Buffer,
    254   IN UINT32    Size
    255   )
    256 {
    257   UINT32       Index;
    258 
    259   if ((Size == 0) || (Buffer == NULL)) {
    260     return 0;
    261   }
    262 
    263   if (mReadBufferNode == NULL) {
    264     return 0;
    265   }
    266 
    267   for (Index = 0; Index < Size; Index++) {
    268     if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
    269       Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
    270     } else {
    271       if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
    272         return Index;
    273       } else {
    274         mReadBufferOffset = 0;
    275         Index --;
    276       }
    277     }
    278   }
    279 
    280   return Size;
    281 }
    282 
    283 EFI_VFR_RETURN_CODE
    284 CFormPkg::BuildPkgHdr (
    285   OUT EFI_HII_PACKAGE_HEADER **PkgHdr
    286   )
    287 {
    288   if (PkgHdr == NULL) {
    289     return VFR_RETURN_FATAL_ERROR;
    290   }
    291 
    292   if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
    293     return VFR_RETURN_OUT_FOR_RESOURCES;
    294   }
    295 
    296   (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
    297   (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
    298 
    299   return VFR_RETURN_SUCCESS;
    300 }
    301 
    302 EFI_VFR_RETURN_CODE
    303 CFormPkg::BuildPkg (
    304   OUT PACKAGE_DATA &TBuffer
    305   )
    306 {
    307 
    308   CHAR8  *Temp;
    309   UINT32 Size;
    310   CHAR8  Buffer[1024];
    311 
    312   if (TBuffer.Buffer != NULL) {
    313     delete TBuffer.Buffer;
    314   }
    315 
    316   TBuffer.Size = mPkgLength;
    317   TBuffer.Buffer = NULL;
    318   if (TBuffer.Size != 0) {
    319     TBuffer.Buffer = new CHAR8[TBuffer.Size];
    320   } else {
    321     return VFR_RETURN_SUCCESS;
    322   }
    323 
    324   Temp = TBuffer.Buffer;
    325   Open ();
    326   while ((Size = Read (Buffer, 1024)) != 0) {
    327     memcpy (Temp, Buffer, Size);
    328     Temp += Size;
    329   }
    330   Close ();
    331   return VFR_RETURN_SUCCESS;
    332 }
    333 
    334 
    335 EFI_VFR_RETURN_CODE
    336 CFormPkg::BuildPkg (
    337   IN FILE  *Output,
    338   IN PACKAGE_DATA *PkgData
    339   )
    340 {
    341   EFI_VFR_RETURN_CODE     Ret;
    342   CHAR8                   Buffer[1024];
    343   UINT32                  Size;
    344   EFI_HII_PACKAGE_HEADER  *PkgHdr;
    345 
    346   if (Output == NULL) {
    347     return VFR_RETURN_FATAL_ERROR;
    348   }
    349 
    350   if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    351     return Ret;
    352   }
    353   fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
    354   delete PkgHdr;
    355 
    356   if (PkgData == NULL) {
    357     Open ();
    358     while ((Size = Read (Buffer, 1024)) != 0) {
    359       fwrite (Buffer, Size, 1, Output);
    360     }
    361     Close ();
    362   } else {
    363     fwrite (PkgData->Buffer, PkgData->Size, 1, Output);
    364   }
    365 
    366   return VFR_RETURN_SUCCESS;
    367 }
    368 
    369 VOID
    370 CFormPkg::_WRITE_PKG_LINE (
    371   IN FILE         *pFile,
    372   IN UINT32       LineBytes,
    373   IN CONST CHAR8  *LineHeader,
    374   IN CHAR8        *BlkBuf,
    375   IN UINT32       BlkSize
    376   )
    377 {
    378   UINT32    Index;
    379 
    380   if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    381     return;
    382   }
    383 
    384   for (Index = 0; Index < BlkSize; Index++) {
    385     if ((Index % LineBytes) == 0) {
    386       fprintf (pFile, "\n%s", LineHeader);
    387     }
    388     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
    389   }
    390 }
    391 
    392 VOID
    393 CFormPkg::_WRITE_PKG_END (
    394   IN FILE         *pFile,
    395   IN UINT32       LineBytes,
    396   IN CONST CHAR8  *LineHeader,
    397   IN CHAR8        *BlkBuf,
    398   IN UINT32       BlkSize
    399   )
    400 {
    401   UINT32    Index;
    402 
    403   if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    404     return;
    405   }
    406 
    407   for (Index = 0; Index < BlkSize - 1; Index++) {
    408     if ((Index % LineBytes) == 0) {
    409       fprintf (pFile, "\n%s", LineHeader);
    410     }
    411     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
    412   }
    413 
    414   if ((Index % LineBytes) == 0) {
    415     fprintf (pFile, "\n%s", LineHeader);
    416   }
    417   fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
    418 }
    419 
    420 #define BYTES_PRE_LINE 0x10
    421 UINT32   gAdjustOpcodeOffset = 0;
    422 BOOLEAN  gNeedAdjustOpcode   = FALSE;
    423 UINT32   gAdjustOpcodeLen    = 0;
    424 
    425 EFI_VFR_RETURN_CODE
    426 CFormPkg::GenCFile (
    427   IN CHAR8 *BaseName,
    428   IN FILE *pFile,
    429   IN PACKAGE_DATA *PkgData
    430   )
    431 {
    432   EFI_VFR_RETURN_CODE          Ret;
    433   CHAR8                        Buffer[BYTES_PRE_LINE * 8];
    434   EFI_HII_PACKAGE_HEADER       *PkgHdr;
    435   UINT32                       PkgLength  = 0;
    436   UINT32                       ReadSize   = 0;
    437 
    438   if ((BaseName == NULL) || (pFile == NULL)) {
    439     return VFR_RETURN_FATAL_ERROR;
    440   }
    441 
    442   fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
    443 
    444   if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    445     return Ret;
    446   }
    447 
    448   //
    449   // For framework vfr file, the extension framework header will be added.
    450   //
    451   if (VfrCompatibleMode) {
    452 	  fprintf (pFile, "  // FRAMEWORK PACKAGE HEADER Length\n");
    453 	  PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;
    454 	  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT32));
    455 	  fprintf (pFile, "\n\n  // FRAMEWORK PACKAGE HEADER Type\n");
    456 	  PkgLength = 3;
    457 	  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT16));
    458 	} else {
    459 	  fprintf (pFile, "  // ARRAY LENGTH\n");
    460 	  PkgLength = PkgHdr->Length + sizeof (UINT32);
    461 	  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT32));
    462 	}
    463 
    464   fprintf (pFile, "\n\n  // PACKAGE HEADER\n");
    465   _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
    466   PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
    467 
    468   fprintf (pFile, "\n\n  // PACKAGE DATA\n");
    469 
    470   if (PkgData == NULL) {
    471     Open ();
    472     while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
    473       PkgLength += ReadSize;
    474       if (PkgLength < PkgHdr->Length) {
    475         _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
    476       } else {
    477         _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
    478       }
    479     }
    480     Close ();
    481   } else {
    482     if (PkgData->Size % BYTES_PRE_LINE != 0) {
    483       PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);
    484       _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer, PkgLength);
    485       _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);
    486     } else {
    487       PkgLength = PkgData->Size - BYTES_PRE_LINE;
    488       _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer, PkgLength);
    489       _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);
    490     }
    491   }
    492 
    493   delete PkgHdr;
    494   fprintf (pFile, "\n};\n");
    495 
    496   return VFR_RETURN_SUCCESS;
    497 }
    498 
    499 EFI_VFR_RETURN_CODE
    500 CFormPkg::AssignPending (
    501   IN CHAR8  *Key,
    502   IN VOID   *ValAddr,
    503   IN UINT32 ValLen,
    504   IN UINT32 LineNo,
    505   IN CONST CHAR8  *Msg
    506   )
    507 {
    508   SPendingAssign *pNew;
    509 
    510   pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
    511   if (pNew == NULL) {
    512     return VFR_RETURN_OUT_FOR_RESOURCES;
    513   }
    514 
    515   pNew->mNext       = PendingAssignList;
    516   PendingAssignList = pNew;
    517   return VFR_RETURN_SUCCESS;
    518 }
    519 
    520 VOID
    521 CFormPkg::DoPendingAssign (
    522   IN CHAR8  *Key,
    523   IN VOID   *ValAddr,
    524   IN UINT32 ValLen
    525   )
    526 {
    527   SPendingAssign *pNode;
    528 
    529   if ((Key == NULL) || (ValAddr == NULL)) {
    530     return;
    531   }
    532 
    533   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    534     if (strcmp (pNode->mKey, Key) == 0) {
    535       pNode->AssignValue (ValAddr, ValLen);
    536     }
    537   }
    538 }
    539 
    540 bool
    541 CFormPkg::HavePendingUnassigned (
    542   VOID
    543   )
    544 {
    545   SPendingAssign *pNode;
    546 
    547   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    548     if (pNode->mFlag == PENDING) {
    549       return TRUE;
    550     }
    551   }
    552 
    553   return FALSE;
    554 }
    555 
    556 VOID
    557 CFormPkg::PendingAssignPrintAll (
    558   VOID
    559   )
    560 {
    561   SPendingAssign *pNode;
    562 
    563   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    564     if (pNode->mFlag == PENDING) {
    565       gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
    566     }
    567   }
    568 }
    569 
    570 SBufferNode *
    571 CFormPkg::GetBinBufferNodeForAddr (
    572   IN CHAR8              *BinBuffAddr
    573   )
    574 {
    575   SBufferNode *TmpNode;
    576 
    577   TmpNode = mBufferNodeQueueHead;
    578 
    579   while (TmpNode != NULL) {
    580     if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {
    581       return TmpNode;
    582     }
    583 
    584     TmpNode = TmpNode->mNext;
    585   }
    586 
    587   return NULL;
    588 }
    589 
    590 SBufferNode *
    591 CFormPkg::GetNodeBefore(
    592   IN SBufferNode *CurrentNode
    593   )
    594 {
    595   SBufferNode *FirstNode   = mBufferNodeQueueHead;
    596   SBufferNode *LastNode    = mBufferNodeQueueHead;
    597 
    598   while (FirstNode != NULL) {
    599     if (FirstNode == CurrentNode) {
    600       break;
    601     }
    602 
    603     LastNode    = FirstNode;
    604     FirstNode   = FirstNode->mNext;
    605   }
    606 
    607   if (FirstNode == NULL) {
    608     LastNode = NULL;
    609   }
    610 
    611   return LastNode;
    612 }
    613 
    614 EFI_VFR_RETURN_CODE
    615 CFormPkg::InsertNodeBefore(
    616   IN SBufferNode *CurrentNode,
    617   IN SBufferNode *NewNode
    618   )
    619 {
    620   SBufferNode *LastNode = GetNodeBefore (CurrentNode);
    621 
    622   if (LastNode == NULL) {
    623     return VFR_RETURN_MISMATCHED;
    624   }
    625 
    626   NewNode->mNext = LastNode->mNext;
    627   LastNode->mNext = NewNode;
    628 
    629   return VFR_RETURN_SUCCESS;
    630 }
    631 
    632 CHAR8 *
    633 CFormPkg::GetBufAddrBaseOnOffset (
    634   IN UINT32      Offset
    635   )
    636 {
    637   SBufferNode *TmpNode;
    638   UINT32      TotalBufLen;
    639   UINT32      CurrentBufLen;
    640 
    641   TotalBufLen = 0;
    642 
    643   for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {
    644     CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;
    645     if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {
    646       return TmpNode->mBufferStart + (Offset - TotalBufLen);
    647     }
    648 
    649     TotalBufLen += CurrentBufLen;
    650   }
    651 
    652   return NULL;
    653 }
    654 
    655 EFI_VFR_RETURN_CODE
    656 CFormPkg::AdjustDynamicInsertOpcode (
    657   IN CHAR8              *InserPositionAddr,
    658   IN CHAR8              *InsertOpcodeAddr,
    659   IN BOOLEAN            CreateOpcodeAfterParsingVfr
    660   )
    661 {
    662   SBufferNode *InserPositionNode;
    663   SBufferNode *InsertOpcodeNode;
    664   SBufferNode *NewRestoreNodeBegin;
    665   SBufferNode *NewRestoreNodeEnd;
    666   SBufferNode *NewLastEndNode;
    667   SBufferNode *TmpNode;
    668   UINT32      NeedRestoreCodeLen;
    669 
    670   NewRestoreNodeEnd = NULL;
    671 
    672   InserPositionNode  = GetBinBufferNodeForAddr(InserPositionAddr);
    673   InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);
    674   assert (InserPositionNode != NULL);
    675   assert (InsertOpcodeNode  != NULL);
    676 
    677   if (InserPositionNode == InsertOpcodeNode) {
    678     //
    679     // Create New Node to save the restore opcode.
    680     //
    681     NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;
    682     gAdjustOpcodeLen   = NeedRestoreCodeLen;
    683     NewRestoreNodeBegin = CreateNewNode ();
    684     if (NewRestoreNodeBegin == NULL) {
    685       return VFR_RETURN_OUT_FOR_RESOURCES;
    686     }
    687     memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
    688     NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
    689 
    690     //
    691     // Override the restore buffer data.
    692     //
    693     memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
    694     InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;
    695     memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);
    696   } else {
    697     //
    698     // Create New Node to save the restore opcode.
    699     //
    700     NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;
    701     gAdjustOpcodeLen   = NeedRestoreCodeLen;
    702     NewRestoreNodeBegin = CreateNewNode ();
    703     if (NewRestoreNodeBegin == NULL) {
    704       return VFR_RETURN_OUT_FOR_RESOURCES;
    705     }
    706     memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
    707     NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
    708     //
    709     // Override the restore buffer data.
    710     //
    711     InserPositionNode->mBufferFree -= NeedRestoreCodeLen;
    712     //
    713     // Link the restore data to new node.
    714     //
    715     NewRestoreNodeBegin->mNext = InserPositionNode->mNext;
    716 
    717     //
    718     // Count the Adjust opcode len.
    719     //
    720     TmpNode = InserPositionNode->mNext;
    721     while (TmpNode != InsertOpcodeNode) {
    722       gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;
    723       TmpNode = TmpNode->mNext;
    724     }
    725 
    726     //
    727     // Create New Node to save the last node of restore opcode.
    728     //
    729     NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
    730     gAdjustOpcodeLen  += NeedRestoreCodeLen;
    731     if (NeedRestoreCodeLen > 0) {
    732       NewRestoreNodeEnd = CreateNewNode ();
    733       if (NewRestoreNodeEnd == NULL) {
    734         return VFR_RETURN_OUT_FOR_RESOURCES;
    735       }
    736       memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);
    737       NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;
    738       //
    739       // Override the restore buffer data.
    740       //
    741       memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
    742       InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
    743 
    744       //
    745       // Insert the last restore data node.
    746       //
    747       TmpNode = GetNodeBefore (InsertOpcodeNode);
    748       assert (TmpNode != NULL);
    749 
    750       if (TmpNode == InserPositionNode) {
    751         NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;
    752       } else {
    753         TmpNode->mNext = NewRestoreNodeEnd;
    754       }
    755       //
    756       // Connect the dynamic opcode node to the node after InserPositionNode.
    757       //
    758       InserPositionNode->mNext = InsertOpcodeNode;
    759     }
    760   }
    761 
    762   if (CreateOpcodeAfterParsingVfr) {
    763     //
    764     // Th new opcodes were created after Parsing Vfr file,
    765     // so the content in mBufferNodeQueueTail must be the new created opcodes.
    766     // So connet the  NewRestoreNodeBegin to the tail and update the tail node.
    767     //
    768     mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
    769     if (NewRestoreNodeEnd != NULL) {
    770       mBufferNodeQueueTail = NewRestoreNodeEnd;
    771     } else {
    772       mBufferNodeQueueTail = NewRestoreNodeBegin;
    773     }
    774   } else {
    775     if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {
    776       //
    777       // End form set opcode all in the mBufferNodeQueueTail node.
    778       //
    779       NewLastEndNode = CreateNewNode ();
    780       if (NewLastEndNode == NULL) {
    781         return VFR_RETURN_OUT_FOR_RESOURCES;
    782       }
    783       NewLastEndNode->mBufferStart[0] = 0x29;
    784       NewLastEndNode->mBufferStart[1] = 0x02;
    785       NewLastEndNode->mBufferFree += 2;
    786 
    787       mBufferNodeQueueTail->mBufferFree -= 2;
    788 
    789       mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
    790       if (NewRestoreNodeEnd != NULL) {
    791         NewRestoreNodeEnd->mNext = NewLastEndNode;
    792       } else {
    793         NewRestoreNodeBegin->mNext = NewLastEndNode;
    794       }
    795 
    796       mBufferNodeQueueTail = NewLastEndNode;
    797     } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {
    798       TmpNode = GetNodeBefore(mBufferNodeQueueTail);
    799       assert (TmpNode != NULL);
    800 
    801       TmpNode->mNext = NewRestoreNodeBegin;
    802       if (NewRestoreNodeEnd != NULL) {
    803         NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;
    804       } else {
    805         NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;
    806       }
    807     }
    808   }
    809   mCurrBufferNode = mBufferNodeQueueTail;
    810   return VFR_RETURN_SUCCESS;
    811 }
    812 
    813 EFI_VFR_RETURN_CODE
    814 CFormPkg::DeclarePendingQuestion (
    815   IN CVfrVarDataTypeDB   &lCVfrVarDataTypeDB,
    816   IN CVfrDataStorage     &lCVfrDataStorage,
    817   IN CVfrQuestionDB      &lCVfrQuestionDB,
    818   IN EFI_GUID            *LocalFormSetGuid,
    819   IN UINT32              LineNo,
    820   OUT CHAR8              **InsertOpcodeAddr
    821   )
    822 {
    823   SPendingAssign *pNode;
    824   CHAR8          *VarStr;
    825   UINT32         ArrayIdx;
    826   CHAR8          FName[MAX_NAME_LEN];
    827   CHAR8          *SName;
    828   CHAR8          *NewStr;
    829   UINT32         ShrinkSize = 0;
    830   EFI_VFR_RETURN_CODE  ReturnCode;
    831   EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;
    832 
    833   //
    834   // Declare all questions as Numeric in DisableIf True
    835   //
    836   // DisableIf
    837   CIfrDisableIf DIObj;
    838   DIObj.SetLineNo (LineNo);
    839   *InsertOpcodeAddr = DIObj.GetObjBinAddr ();
    840 
    841   //TrueOpcode
    842   CIfrTrue TObj (LineNo);
    843 
    844   // Declare Numeric qeustion for each undefined question.
    845   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    846     if (pNode->mFlag == PENDING) {
    847       CIfrNumeric CNObj;
    848       EFI_VARSTORE_INFO Info;
    849       EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;
    850 
    851       CNObj.SetLineNo (LineNo);
    852       CNObj.SetPrompt (0x0);
    853       CNObj.SetHelp (0x0);
    854 
    855       //
    856       // Register this question, assume it is normal question, not date or time question
    857       //
    858       VarStr = pNode->mKey;
    859       ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
    860       if (ReturnCode != VFR_RETURN_SUCCESS) {
    861         gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
    862         return ReturnCode;
    863       }
    864 
    865 #ifdef VFREXP_DEBUG
    866       printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
    867 #endif
    868       //
    869       // Get Question Info, framework vfr VarName == StructName
    870       //
    871       ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);
    872       if (ReturnCode != VFR_RETURN_SUCCESS) {
    873         gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
    874         return ReturnCode;
    875       }
    876       //
    877       // Get VarStoreType
    878       //
    879       ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
    880       if (ReturnCode != VFR_RETURN_SUCCESS) {
    881         gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
    882         return ReturnCode;
    883       }
    884       VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);
    885 
    886       if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
    887         ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
    888       } else {
    889         if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
    890           ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
    891         } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
    892           VarStr = pNode->mKey;
    893           //convert VarStr with store name to VarStr with structure name
    894           ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
    895           if (ReturnCode == VFR_RETURN_SUCCESS) {
    896             NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
    897             NewStr[0] = '\0';
    898             strcpy (NewStr, SName);
    899             strcat (NewStr, VarStr + strlen (FName));
    900             ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);
    901             delete[] NewStr;
    902           }
    903         } else {
    904           ReturnCode = VFR_RETURN_UNSUPPORTED;
    905         }
    906       }
    907       if (ReturnCode != VFR_RETURN_SUCCESS) {
    908         gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
    909         return ReturnCode;
    910       }
    911 
    912       CNObj.SetQuestionId (QId);
    913       CNObj.SetVarStoreInfo (&Info);
    914       //
    915       // Numeric doesn't support BOOLEAN data type.
    916       // BOOLEAN type has the same data size to UINT8.
    917       //
    918       if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
    919         Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
    920       }
    921       CNObj.SetFlags (0, Info.mVarType);
    922       //
    923       // Use maximum value not to limit the vaild value for the undefined question.
    924       //
    925       switch (Info.mVarType) {
    926       case EFI_IFR_TYPE_NUM_SIZE_64:
    927         CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);
    928         ShrinkSize = 0;
    929         break;
    930       case EFI_IFR_TYPE_NUM_SIZE_32:
    931         CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);
    932         ShrinkSize = 12;
    933         break;
    934       case EFI_IFR_TYPE_NUM_SIZE_16:
    935         CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);
    936         ShrinkSize = 18;
    937         break;
    938       case EFI_IFR_TYPE_NUM_SIZE_8:
    939         CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);
    940         ShrinkSize = 21;
    941         break;
    942       default:
    943         break;
    944       }
    945       CNObj.ShrinkBinSize (ShrinkSize);
    946 
    947       //
    948       // For undefined Efi VarStore type question
    949       // Append the extended guided opcode to contain VarName
    950       //
    951       if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {
    952         CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
    953         CVNObj.SetLineNo (LineNo);
    954       }
    955 
    956       //
    957       // End for Numeric
    958       //
    959       CIfrEnd CEObj;
    960       CEObj.SetLineNo (LineNo);
    961     }
    962   }
    963 
    964   //
    965   // End for DisableIf
    966   //
    967   CIfrEnd SEObj;
    968   SEObj.SetLineNo (LineNo);
    969 
    970   return VFR_RETURN_SUCCESS;
    971 }
    972 
    973 CFormPkg gCFormPkg;
    974 
    975 SIfrRecord::SIfrRecord (
    976   VOID
    977   )
    978 {
    979   mIfrBinBuf = NULL;
    980   mBinBufLen = 0;
    981   mLineNo    = 0xFFFFFFFF;
    982   mOffset    = 0xFFFFFFFF;
    983   mNext      = NULL;
    984 }
    985 
    986 SIfrRecord::~SIfrRecord (
    987   VOID
    988   )
    989 {
    990   if (mIfrBinBuf != NULL) {
    991     //delete mIfrBinBuf;
    992     mIfrBinBuf = NULL;
    993   }
    994   mLineNo      = 0xFFFFFFFF;
    995   mOffset      = 0xFFFFFFFF;
    996   mBinBufLen   = 0;
    997   mNext        = NULL;
    998 }
    999 
   1000 CIfrRecordInfoDB::CIfrRecordInfoDB (
   1001   VOID
   1002   )
   1003 {
   1004   mSwitch            = TRUE;
   1005   mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;
   1006   mIfrRecordListHead = NULL;
   1007   mIfrRecordListTail = NULL;
   1008   mAllDefaultTypeCount = 0;
   1009   for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {
   1010     mAllDefaultIdArray[i] = 0xffff;
   1011   }
   1012 }
   1013 
   1014 CIfrRecordInfoDB::~CIfrRecordInfoDB (
   1015   VOID
   1016   )
   1017 {
   1018   SIfrRecord *pNode;
   1019 
   1020   while (mIfrRecordListHead != NULL) {
   1021     pNode = mIfrRecordListHead;
   1022     mIfrRecordListHead = mIfrRecordListHead->mNext;
   1023     delete pNode;
   1024   }
   1025 }
   1026 
   1027 SIfrRecord *
   1028 CIfrRecordInfoDB::GetRecordInfoFromIdx (
   1029   IN UINT32 RecordIdx
   1030   )
   1031 {
   1032   UINT32     Idx;
   1033   SIfrRecord *pNode = NULL;
   1034 
   1035   if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
   1036     return NULL;
   1037   }
   1038 
   1039   for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
   1040        (Idx != RecordIdx) && (pNode != NULL);
   1041        Idx++, pNode = pNode->mNext)
   1042   ;
   1043 
   1044   return pNode;
   1045 }
   1046 
   1047 UINT32
   1048 CIfrRecordInfoDB::IfrRecordRegister (
   1049   IN UINT32 LineNo,
   1050   IN CHAR8  *IfrBinBuf,
   1051   IN UINT8  BinBufLen,
   1052   IN UINT32 Offset
   1053   )
   1054 {
   1055   SIfrRecord *pNew;
   1056 
   1057   if (mSwitch == FALSE) {
   1058     return EFI_IFR_RECORDINFO_IDX_INVALUD;
   1059   }
   1060 
   1061   if ((pNew = new SIfrRecord) == NULL) {
   1062     return EFI_IFR_RECORDINFO_IDX_INVALUD;
   1063   }
   1064 
   1065   if (mIfrRecordListHead == NULL) {
   1066     mIfrRecordListHead = pNew;
   1067     mIfrRecordListTail = pNew;
   1068   } else {
   1069     mIfrRecordListTail->mNext = pNew;
   1070     mIfrRecordListTail = pNew;
   1071   }
   1072   mRecordCount++;
   1073 
   1074   return mRecordCount;
   1075 }
   1076 
   1077 VOID
   1078 CIfrRecordInfoDB::IfrRecordInfoUpdate (
   1079   IN UINT32 RecordIdx,
   1080   IN UINT32 LineNo,
   1081   IN CHAR8  *BinBuf,
   1082   IN UINT8  BinBufLen,
   1083   IN UINT32 Offset
   1084   )
   1085 {
   1086   SIfrRecord *pNode;
   1087   SIfrRecord *Prev;
   1088 
   1089   if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
   1090     return;
   1091   }
   1092 
   1093   if (LineNo == 0) {
   1094     //
   1095     // Line number is not specified explicitly, try to use line number of previous opcode
   1096     //
   1097     Prev = GetRecordInfoFromIdx (RecordIdx - 1);
   1098     if (Prev != NULL) {
   1099       LineNo = Prev->mLineNo;
   1100     }
   1101   }
   1102 
   1103   pNode->mLineNo    = LineNo;
   1104   pNode->mOffset    = Offset;
   1105   pNode->mBinBufLen = BinBufLen;
   1106   pNode->mIfrBinBuf = BinBuf;
   1107 
   1108 }
   1109 
   1110 VOID
   1111 CIfrRecordInfoDB::IfrRecordOutput (
   1112   OUT PACKAGE_DATA &TBuffer
   1113   )
   1114 {
   1115   CHAR8      *Temp;
   1116   SIfrRecord *pNode;
   1117 
   1118   if (TBuffer.Buffer != NULL) {
   1119     delete TBuffer.Buffer;
   1120   }
   1121 
   1122   TBuffer.Size = 0;
   1123   TBuffer.Buffer = NULL;
   1124 
   1125 
   1126   if (mSwitch == FALSE) {
   1127     return;
   1128   }
   1129 
   1130   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
   1131     TBuffer.Size += pNode->mBinBufLen;
   1132   }
   1133 
   1134   if (TBuffer.Size != 0) {
   1135     TBuffer.Buffer = new CHAR8[TBuffer.Size];
   1136   } else {
   1137     return;
   1138   }
   1139 
   1140   Temp = TBuffer.Buffer;
   1141 
   1142   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
   1143     if (pNode->mIfrBinBuf != NULL) {
   1144       memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
   1145       Temp += pNode->mBinBufLen;
   1146     }
   1147   }
   1148 
   1149   return;
   1150 }
   1151 
   1152 VOID
   1153 CIfrRecordInfoDB::IfrRecordOutput (
   1154   IN FILE   *File,
   1155   IN UINT32 LineNo
   1156   )
   1157 {
   1158   SIfrRecord *pNode;
   1159   UINT8      Index;
   1160   UINT32     TotalSize;
   1161 
   1162   if (mSwitch == FALSE) {
   1163     return;
   1164   }
   1165 
   1166   if (File == NULL) {
   1167     return;
   1168   }
   1169 
   1170   TotalSize = 0;
   1171 
   1172   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
   1173     if (pNode->mLineNo == LineNo || LineNo == 0) {
   1174       fprintf (File, ">%08X: ", pNode->mOffset);
   1175       TotalSize += pNode->mBinBufLen;
   1176       if (pNode->mIfrBinBuf != NULL) {
   1177         for (Index = 0; Index < pNode->mBinBufLen; Index++) {
   1178           fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
   1179         }
   1180       }
   1181       fprintf (File, "\n");
   1182     }
   1183   }
   1184 
   1185   if (LineNo == 0) {
   1186     fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
   1187   }
   1188 }
   1189 
   1190 //
   1191 // for framework vfr file
   1192 // adjust opcode sequence for uefi IFR format
   1193 // adjust inconsistent and varstore into the right position.
   1194 //
   1195 BOOLEAN
   1196 CIfrRecordInfoDB::CheckQuestionOpCode (
   1197   IN UINT8 OpCode
   1198   )
   1199 {
   1200   switch (OpCode) {
   1201   case EFI_IFR_CHECKBOX_OP:
   1202   case EFI_IFR_NUMERIC_OP:
   1203   case EFI_IFR_PASSWORD_OP:
   1204   case EFI_IFR_ONE_OF_OP:
   1205   case EFI_IFR_ACTION_OP:
   1206   case EFI_IFR_STRING_OP:
   1207   case EFI_IFR_DATE_OP:
   1208   case EFI_IFR_TIME_OP:
   1209   case EFI_IFR_ORDERED_LIST_OP:
   1210   case EFI_IFR_REF_OP:
   1211     return TRUE;
   1212   default:
   1213     return FALSE;
   1214   }
   1215 }
   1216 
   1217 BOOLEAN
   1218 CIfrRecordInfoDB::CheckIdOpCode (
   1219   IN UINT8 OpCode
   1220   )
   1221 {
   1222   switch (OpCode) {
   1223   case EFI_IFR_EQ_ID_VAL_OP:
   1224   case EFI_IFR_EQ_ID_ID_OP:
   1225   case EFI_IFR_EQ_ID_VAL_LIST_OP:
   1226   case EFI_IFR_QUESTION_REF1_OP:
   1227     return TRUE;
   1228   default:
   1229     return FALSE;
   1230   }
   1231 }
   1232 
   1233 EFI_QUESTION_ID
   1234 CIfrRecordInfoDB::GetOpcodeQuestionId (
   1235   IN EFI_IFR_OP_HEADER *OpHead
   1236   )
   1237 {
   1238   EFI_IFR_QUESTION_HEADER *QuestionHead;
   1239 
   1240   QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
   1241 
   1242   return QuestionHead->QuestionId;
   1243 }
   1244 
   1245 SIfrRecord *
   1246 CIfrRecordInfoDB::GetRecordInfoFromOffset (
   1247   IN UINT32 Offset
   1248   )
   1249 {
   1250   SIfrRecord *pNode = NULL;
   1251 
   1252   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
   1253     if (pNode->mOffset == Offset) {
   1254       return pNode;
   1255     }
   1256   }
   1257 
   1258   return pNode;
   1259 }
   1260 
   1261 /**
   1262   Add just the op code position.
   1263 
   1264   Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
   1265   so pDynamicOpcodeNodes is before mIfrRecordListTail.
   1266 
   1267   From
   1268 
   1269   |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
   1270 
   1271   To
   1272 
   1273   |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
   1274 
   1275   Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
   1276   so new records are appennded to the end of OriginalIfrRecordListTail.
   1277 
   1278   From
   1279 
   1280   |mIfrRecordListHead + ...+ pAdjustNode +  ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
   1281 
   1282   To
   1283 
   1284   |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode +  ... + OriginalIfrRecordListTail|
   1285 
   1286 
   1287   @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.
   1288 
   1289 **/
   1290 BOOLEAN
   1291 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
   1292   IN BOOLEAN  CreateOpcodeAfterParsingVfr
   1293   )
   1294 {
   1295   UINT32             OpcodeOffset;
   1296   SIfrRecord         *pNode, *pPreNode;
   1297   SIfrRecord         *pAdjustNode, *pNodeBeforeAdjust;
   1298   SIfrRecord         *pNodeBeforeDynamic;
   1299 
   1300   pPreNode            = NULL;
   1301   pAdjustNode         = NULL;
   1302   pNodeBeforeDynamic  = NULL;
   1303   OpcodeOffset        = 0;
   1304 
   1305   //
   1306   // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
   1307   // and the node before pDynamicOpcodeNode.
   1308   //
   1309   for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {
   1310     if (OpcodeOffset == gAdjustOpcodeOffset) {
   1311       pAdjustNode       = pNode;
   1312       pNodeBeforeAdjust = pPreNode;
   1313     } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
   1314       pNodeBeforeDynamic = pPreNode;
   1315     }
   1316     if (pNode->mNext != NULL) {
   1317       pPreNode = pNode;
   1318     }
   1319     OpcodeOffset += pNode->mBinBufLen;
   1320   }
   1321 
   1322   //
   1323   // Check the nodes whether exist.
   1324   //
   1325   if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {
   1326     return FALSE;
   1327   }
   1328 
   1329   //
   1330   // Adjust the node. pPreNode save the Node before mIfrRecordListTail
   1331   //
   1332   pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;
   1333   if (CreateOpcodeAfterParsingVfr) {
   1334     //
   1335     // mIfrRecordListTail is the end of pDynamicNode (Case2).
   1336     //
   1337     mIfrRecordListTail->mNext = pAdjustNode;
   1338     mIfrRecordListTail = pNodeBeforeDynamic;
   1339     mIfrRecordListTail->mNext = NULL;
   1340   } else {
   1341     //
   1342     //pPreNode is the end of pDynamicNode(Case1).
   1343     //
   1344     pPreNode->mNext = pAdjustNode;
   1345     pNodeBeforeDynamic->mNext = mIfrRecordListTail;
   1346   }
   1347 
   1348   return TRUE;
   1349 }
   1350 
   1351 /**
   1352   Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
   1353 
   1354   @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.
   1355 
   1356 **/
   1357 VOID
   1358 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
   1359   IN BOOLEAN  CreateOpcodeAfterParsingVfr
   1360   )
   1361 {
   1362   SIfrRecord          *pRecord;
   1363 
   1364   //
   1365   // Base on the original offset info to update the record list.
   1366   //
   1367   if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {
   1368     gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");
   1369   }
   1370 
   1371   //
   1372   // Base on the opcode binary length to recalculate the offset for each opcode.
   1373   //
   1374   IfrAdjustOffsetForRecord();
   1375 
   1376   //
   1377   // Base on the offset to find the binary address.
   1378   //
   1379   pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);
   1380   while (pRecord != NULL) {
   1381     pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);
   1382     pRecord = pRecord->mNext;
   1383   }
   1384 }
   1385 
   1386 
   1387 VOID
   1388 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
   1389   VOID
   1390   )
   1391 {
   1392   UINT32             OpcodeOffset;
   1393   SIfrRecord         *pNode;
   1394 
   1395   OpcodeOffset = 0;
   1396   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
   1397     pNode->mOffset = OpcodeOffset;
   1398     OpcodeOffset += pNode->mBinBufLen;
   1399   }
   1400 }
   1401 
   1402 EFI_VFR_RETURN_CODE
   1403 CIfrRecordInfoDB::IfrRecordAdjust (
   1404   VOID
   1405   )
   1406 {
   1407   SIfrRecord *pNode, *preNode;
   1408   SIfrRecord *uNode, *tNode;
   1409   EFI_IFR_OP_HEADER  *OpHead, *tOpHead;
   1410   EFI_QUESTION_ID    QuestionId;
   1411   UINT32             StackCount;
   1412   UINT32             QuestionScope;
   1413   CHAR8              ErrorMsg[MAX_STRING_LEN] = {0, };
   1414   EFI_VFR_RETURN_CODE  Status;
   1415 
   1416   //
   1417   // Init local variable
   1418   //
   1419   Status = VFR_RETURN_SUCCESS;
   1420   pNode = mIfrRecordListHead;
   1421   preNode = pNode;
   1422   QuestionScope = 0;
   1423   while (pNode != NULL) {
   1424     OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
   1425 
   1426     //
   1427     // make sure the inconsistent opcode in question scope
   1428     //
   1429     if (QuestionScope > 0) {
   1430       QuestionScope += OpHead->Scope;
   1431       if (OpHead->OpCode == EFI_IFR_END_OP) {
   1432         QuestionScope --;
   1433       }
   1434     }
   1435 
   1436     if (CheckQuestionOpCode (OpHead->OpCode)) {
   1437       QuestionScope = 1;
   1438     }
   1439     //
   1440     // for the inconsistent opcode not in question scope, adjust it
   1441     //
   1442     if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
   1443       //
   1444       // for inconsistent opcode not in question scope
   1445       //
   1446 
   1447       //
   1448       // Count inconsistent opcode Scope
   1449       //
   1450       StackCount = OpHead->Scope;
   1451       QuestionId = EFI_QUESTION_ID_INVALID;
   1452       tNode = pNode;
   1453       while (tNode != NULL && StackCount > 0) {
   1454         tNode = tNode->mNext;
   1455         tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
   1456         //
   1457         // Calculate Scope Number
   1458         //
   1459         StackCount += tOpHead->Scope;
   1460         if (tOpHead->OpCode == EFI_IFR_END_OP) {
   1461           StackCount --;
   1462         }
   1463         //
   1464         // by IdEqual opcode to get QuestionId
   1465         //
   1466         if (QuestionId == EFI_QUESTION_ID_INVALID &&
   1467             CheckIdOpCode (tOpHead->OpCode)) {
   1468           QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
   1469         }
   1470       }
   1471       if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
   1472         //
   1473         // report error; not found
   1474         //
   1475         sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
   1476         gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
   1477         Status = VFR_RETURN_MISMATCHED;
   1478         break;
   1479       }
   1480       //
   1481       // extract inconsistent opcode list
   1482       // pNode is Incosistent opcode, tNode is End Opcode
   1483       //
   1484 
   1485       //
   1486       // insert inconsistent opcode list into the right question scope by questionid
   1487       //
   1488       for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
   1489         tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
   1490         if (CheckQuestionOpCode (tOpHead->OpCode) &&
   1491             (QuestionId == GetOpcodeQuestionId (tOpHead))) {
   1492           break;
   1493         }
   1494       }
   1495       //
   1496       // insert inconsistent opcode list and check LATE_CHECK flag
   1497       //
   1498       if (uNode != NULL) {
   1499         if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
   1500           //
   1501           // if LATE_CHECK flag is set, change inconsistent to nosumbit
   1502           //
   1503           OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
   1504         }
   1505 
   1506         //
   1507         // skip the default storage for Date and Time
   1508         //
   1509         if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
   1510           uNode = uNode->mNext;
   1511         }
   1512 
   1513         preNode->mNext = tNode->mNext;
   1514         tNode->mNext = uNode->mNext;
   1515         uNode->mNext = pNode;
   1516         //
   1517         // reset pNode to head list, scan the whole list again.
   1518         //
   1519         pNode = mIfrRecordListHead;
   1520         preNode = pNode;
   1521         QuestionScope = 0;
   1522         continue;
   1523       } else {
   1524         //
   1525         // not found matched question id, report error
   1526         //
   1527         sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
   1528         gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
   1529         Status = VFR_RETURN_MISMATCHED;
   1530         break;
   1531       }
   1532     } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
   1533                OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
   1534       //
   1535       // for new added group of varstore opcode
   1536       //
   1537       tNode = pNode;
   1538       while (tNode->mNext != NULL) {
   1539         tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
   1540         if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
   1541             tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
   1542           break;
   1543         }
   1544         tNode = tNode->mNext;
   1545       }
   1546 
   1547       if (tNode->mNext == NULL) {
   1548         //
   1549         // invalid IfrCode, IfrCode end by EndOpCode
   1550         //
   1551         gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
   1552         Status = VFR_RETURN_MISMATCHED;
   1553         break;
   1554       }
   1555 
   1556       if (tOpHead->OpCode != EFI_IFR_END_OP) {
   1557           //
   1558           // not new added varstore, which are not needed to be adjust.
   1559           //
   1560           preNode = tNode;
   1561           pNode   = tNode->mNext;
   1562           continue;
   1563       } else {
   1564         //
   1565         // move new added varstore opcode to the position befor form opcode
   1566         // varstore opcode between pNode and tNode
   1567         //
   1568 
   1569         //
   1570         // search form opcode from begin
   1571         //
   1572         for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
   1573           tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
   1574           if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
   1575             break;
   1576           }
   1577         }
   1578         //
   1579         // Insert varstore opcode beform form opcode if form opcode is found
   1580         //
   1581         if (uNode->mNext != NULL) {
   1582           preNode->mNext = tNode->mNext;
   1583           tNode->mNext = uNode->mNext;
   1584           uNode->mNext = pNode;
   1585           //
   1586           // reset pNode to head list, scan the whole list again.
   1587           //
   1588           pNode = mIfrRecordListHead;
   1589           preNode = pNode;
   1590           QuestionScope = 0;
   1591           continue;
   1592         } else {
   1593           //
   1594           // not found form, continue scan IfrRecord list
   1595           //
   1596           preNode = tNode;
   1597           pNode   = tNode->mNext;
   1598           continue;
   1599         }
   1600       }
   1601     }
   1602     //
   1603     // next node
   1604     //
   1605     preNode = pNode;
   1606     pNode = pNode->mNext;
   1607   }
   1608 
   1609   //
   1610   // Update Ifr Opcode Offset
   1611   //
   1612   if (Status == VFR_RETURN_SUCCESS) {
   1613     IfrAdjustOffsetForRecord ();
   1614   }
   1615   return Status;
   1616 }
   1617 
   1618 /**
   1619   When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
   1620   given by expression, should save the default info for the Buffer VarStore.
   1621 
   1622   @param  DefaultId           The default id.
   1623   @param  pQuestionNode       Point to the question opcode node.
   1624   @param  Value               The default value.
   1625 **/
   1626 VOID
   1627 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
   1628   IN  UINT16                  DefaultId,
   1629   IN  SIfrRecord              *pQuestionNode,
   1630   IN  EFI_IFR_TYPE_VALUE      Value
   1631   )
   1632 {
   1633   CHAR8                   *VarStoreName = NULL;
   1634   EFI_VFR_VARSTORE_TYPE    VarStoreType  = EFI_VFR_VARSTORE_INVALID;
   1635   EFI_GUID                 *VarGuid      = NULL;
   1636   EFI_VARSTORE_INFO        VarInfo;
   1637   EFI_IFR_QUESTION_HEADER  *QuestionHead;
   1638   EFI_IFR_OP_HEADER        *pQuestionOpHead;
   1639 
   1640   pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
   1641   QuestionHead    = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);
   1642 
   1643   //
   1644   // Get the Var Store name and type.
   1645   //
   1646   gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);
   1647   VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);
   1648   VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);
   1649 
   1650   //
   1651   // Only for Buffer storage need to save the default info in the storage.
   1652   // Other type storage, just return.
   1653   //
   1654   if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {
   1655     return;
   1656   } else {
   1657     VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;
   1658     VarInfo.mVarStoreId = QuestionHead->VarStoreId;
   1659   }
   1660 
   1661   //
   1662   // Get the buffer storage info about this question.
   1663   //
   1664   gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);
   1665 
   1666   //
   1667   // Add action.
   1668   //
   1669   gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
   1670     DefaultId,
   1671     VarInfo,
   1672     VarStoreName,
   1673     VarGuid,
   1674     VarInfo.mVarType,
   1675     Value
   1676     );
   1677 }
   1678 
   1679 /**
   1680   Record the number and default id of all defaultstore opcode.
   1681 
   1682 **/
   1683 VOID
   1684 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
   1685   VOID
   1686   )
   1687 {
   1688   SIfrRecord             *pNode;
   1689   EFI_IFR_OP_HEADER      *pOpHead;
   1690   EFI_IFR_DEFAULTSTORE   *DefaultStore;
   1691 
   1692   pNode                = mIfrRecordListHead;
   1693   mAllDefaultTypeCount = 0;
   1694 
   1695   while (pNode != NULL) {
   1696     pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
   1697 
   1698     if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){
   1699       DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;
   1700       mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;
   1701     }
   1702     pNode = pNode->mNext;
   1703   }
   1704 }
   1705 
   1706 /**
   1707   Create new default opcode record.
   1708 
   1709   @param    Size            The new default opcode size.
   1710   @param    DefaultId       The new default id.
   1711   @param    Type            The new default type.
   1712   @param    LineNo          The line number of the new record.
   1713   @param    Value           The new default value.
   1714 
   1715 **/
   1716 VOID
   1717 CIfrRecordInfoDB::IfrCreateDefaultRecord(
   1718   IN UINT8               Size,
   1719   IN UINT16              DefaultId,
   1720   IN UINT8               Type,
   1721   IN UINT32              LineNo,
   1722   IN EFI_IFR_TYPE_VALUE  Value
   1723   )
   1724 {
   1725   CIfrDefault   *DObj;
   1726   CIfrDefault2  *DObj2;
   1727 
   1728   DObj  = NULL;
   1729   DObj2 = NULL;
   1730 
   1731   if (Type == EFI_IFR_TYPE_OTHER) {
   1732     DObj2 = new CIfrDefault2 (Size);
   1733     DObj2->SetDefaultId(DefaultId);
   1734     DObj2->SetType(Type);
   1735     DObj2->SetLineNo(LineNo);
   1736     DObj2->SetScope (1);
   1737     delete DObj2;
   1738   } else {
   1739     DObj = new CIfrDefault (Size);
   1740     DObj->SetDefaultId(DefaultId);
   1741     DObj->SetType(Type);
   1742     DObj->SetLineNo(LineNo);
   1743     DObj->SetValue (Value);
   1744     delete DObj;
   1745   }
   1746 }
   1747 
   1748 /**
   1749   Create new default opcode for question base on the QuestionDefaultInfo.
   1750 
   1751   @param  pQuestionNode              Point to the question opcode Node.
   1752   @param  QuestionDefaultInfo        Point to the QuestionDefaultInfo for current question.
   1753 
   1754 **/
   1755 VOID
   1756 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
   1757   IN  SIfrRecord              *pQuestionNode,
   1758   IN  QuestionDefaultRecord   *QuestionDefaultInfo
   1759   )
   1760 {
   1761   EFI_IFR_OP_HEADER      *pOpHead;
   1762   EFI_IFR_DEFAULT        *Default;
   1763   SIfrRecord             *pSNode;
   1764   SIfrRecord             *pENode;
   1765   SIfrRecord             *pDefaultNode;
   1766   CIfrObj                *Obj;
   1767   CHAR8                  *ObjBinBuf;
   1768   UINT8                  ScopeCount;
   1769   UINT8                  OpcodeNumber;
   1770   UINT8                  OpcodeCount;
   1771   UINT8                  DefaultSize;
   1772   EFI_IFR_ONE_OF_OPTION  *DefaultOptionOpcode;
   1773   EFI_IFR_TYPE_VALUE     CheckBoxDefaultValue;
   1774 
   1775   CheckBoxDefaultValue.b = 1;
   1776   pOpHead                = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
   1777   ScopeCount             = 0;
   1778   OpcodeCount            = 0;
   1779   Obj                    = NULL;
   1780 
   1781   //
   1782   // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
   1783   //
   1784   gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;
   1785   //
   1786   // Case 1:
   1787   // For oneof, the default with smallest default id is given by the option flag.
   1788   // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
   1789   //
   1790   if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
   1791     DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;
   1792     DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
   1793     DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);
   1794     for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   1795       if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   1796         IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);
   1797         //
   1798         // Save the new created default in the buffer storage.
   1799         //
   1800         IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);
   1801       }
   1802     }
   1803     return;
   1804   }
   1805 
   1806   //
   1807   // Case2:
   1808   // For checkbox, the default with smallest default id is given by the question flag.
   1809   // And create the missing defaults with true value.
   1810   //
   1811   if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
   1812     DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);
   1813     for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   1814       if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   1815         IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);
   1816         //
   1817         // Save the new created default.
   1818         //
   1819         IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);
   1820       }
   1821     }
   1822     return;
   1823   }
   1824 
   1825   //
   1826   // Case3:
   1827   // The default with smallest default id is given by the default opcode.
   1828   // So create the missing defaults base on the value in the default opcode.
   1829   //
   1830 
   1831   //
   1832   // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
   1833   //
   1834   pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;
   1835   Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;
   1836   //
   1837   // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
   1838   //
   1839   gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;
   1840 
   1841   if (Default->Type == EFI_IFR_TYPE_OTHER) {
   1842     //
   1843     // EFI_IFR_DEFAULT_2 opcode.
   1844     //
   1845     // Point to the first expression opcode.
   1846     //
   1847     pSNode = pDefaultNode->mNext;
   1848     pENode = NULL;
   1849     ScopeCount++;
   1850     //
   1851     // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
   1852     //
   1853     while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {
   1854       pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
   1855       if (pOpHead->Scope == 1) {
   1856         ScopeCount++;
   1857       }
   1858       if (pOpHead->OpCode == EFI_IFR_END_OP) {
   1859         ScopeCount--;
   1860       }
   1861       pENode = pSNode;
   1862       pSNode = pSNode->mNext;
   1863       OpcodeCount++;
   1864     }
   1865 
   1866     assert (pSNode);
   1867     assert (pENode);
   1868 
   1869     //
   1870     // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
   1871     //
   1872     gAdjustOpcodeOffset = pSNode->mOffset;
   1873     //
   1874     // Create new default opcode node for missing default.
   1875     //
   1876     for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   1877       OpcodeNumber = OpcodeCount;
   1878       if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   1879         IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);
   1880         //
   1881         // Point to the first expression opcode node.
   1882         //
   1883         pSNode = pDefaultNode->mNext;
   1884         //
   1885         // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
   1886         //
   1887         while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {
   1888           pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
   1889           Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);
   1890           assert (Obj != NULL);
   1891           Obj->SetLineNo (pSNode->mLineNo);
   1892           ObjBinBuf = Obj->GetObjBinAddr();
   1893           memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);
   1894           delete Obj;
   1895           pSNode = pSNode->mNext;
   1896         }
   1897       }
   1898     }
   1899   } else {
   1900     //
   1901     // EFI_IFR_DEFAULT opcode.
   1902     //
   1903     // Create new default opcode node for missing default.
   1904     //
   1905     for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   1906       if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   1907         IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);
   1908         //
   1909         // Save the new created default in the buffer storage..
   1910         //
   1911         IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);
   1912       }
   1913     }
   1914   }
   1915 }
   1916 
   1917 /**
   1918   Parse the default information in a question, get the QuestionDefaultInfo.
   1919 
   1920   @param  pQuestionNode          Point to the question record Node.
   1921   @param  QuestionDefaultInfo    On return, point to the QuestionDefaultInfo.
   1922 **/
   1923 VOID
   1924 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
   1925   IN  SIfrRecord              *pQuestionNode,
   1926   OUT QuestionDefaultRecord   *QuestionDefaultInfo
   1927   )
   1928 {
   1929   SIfrRecord              *pSNode;
   1930   EFI_IFR_ONE_OF_OPTION   *OneofOptionOpcode;
   1931   EFI_IFR_OP_HEADER       *pSOpHead;
   1932   EFI_IFR_CHECKBOX        *CheckBoxOpcode;
   1933   EFI_IFR_DEFAULT         *DefaultOpcode;
   1934   BOOLEAN                 IsOneOfOpcode;
   1935   UINT16                  SmallestDefaultId;
   1936   UINT8                   ScopeCount;
   1937 
   1938   SmallestDefaultId  = 0xffff;
   1939   IsOneOfOpcode      = FALSE;
   1940   ScopeCount         = 0;
   1941   pSNode             = pQuestionNode;
   1942 
   1943   //
   1944   // Parse all the opcodes in the Question.
   1945   //
   1946   while (pSNode != NULL) {
   1947     pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
   1948     //
   1949     // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
   1950     // Scopes may be nested within other scopes.
   1951     // When finishing parsing a question, the scope count must be zero.
   1952     //
   1953     if (pSOpHead->Scope == 1) {
   1954       ScopeCount++;
   1955     }
   1956     if (pSOpHead->OpCode == EFI_IFR_END_OP) {
   1957       ScopeCount--;
   1958     }
   1959     //
   1960     // Check whether finishing parsing a question.
   1961     //
   1962     if (ScopeCount == 0) {
   1963       break;
   1964     }
   1965 
   1966     //
   1967     // Record the default information in the question.
   1968     //
   1969     switch (pSOpHead->OpCode) {
   1970     case EFI_IFR_ONE_OF_OP:
   1971       IsOneOfOpcode = TRUE;
   1972       break;
   1973     case EFI_IFR_CHECKBOX_OP:
   1974       //
   1975       // The default info of check box may be given by flag.
   1976       // So need to check the flag of check box.
   1977       //
   1978       CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;
   1979       if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {
   1980         //
   1981         // Check whether need to update the smallest default id.
   1982         //
   1983         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
   1984           SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
   1985         }
   1986         //
   1987         // Update the QuestionDefaultInfo.
   1988         //
   1989         for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   1990           if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
   1991             if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   1992               QuestionDefaultInfo->mDefaultNumber ++;
   1993               QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
   1994             }
   1995             break;
   1996           }
   1997         }
   1998       }
   1999       if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {
   2000         //
   2001         // Check whether need to update the smallest default id.
   2002         //
   2003         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
   2004           SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
   2005         }
   2006         //
   2007         // Update the QuestionDefaultInfo.
   2008         //
   2009         for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   2010           if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
   2011             if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   2012               QuestionDefaultInfo->mDefaultNumber ++;
   2013               QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
   2014             }
   2015             break;
   2016           }
   2017         }
   2018       }
   2019       break;
   2020     case EFI_IFR_ONE_OF_OPTION_OP:
   2021       if (!IsOneOfOpcode) {
   2022         //
   2023         // Only check the option in oneof.
   2024         //
   2025         break;
   2026       }
   2027       OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;
   2028       if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
   2029         //
   2030         // The option is used as the standard default.
   2031         // Check whether need to update the smallest default id and QuestionDefaultInfo.
   2032         //
   2033         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
   2034           SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
   2035           QuestionDefaultInfo->mDefaultValueRecord = pSNode;
   2036         }
   2037         //
   2038         // Update the IsDefaultIdExist array in QuestionDefaultInfo.
   2039         //
   2040         for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   2041           if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
   2042             if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   2043               QuestionDefaultInfo->mDefaultNumber ++;
   2044               QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
   2045             }
   2046             break;
   2047           }
   2048         }
   2049       }
   2050       if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {
   2051         //
   2052         // This option is used as the manufacture default.
   2053         // Check whether need to update the smallest default id and QuestionDefaultInfo.
   2054         //
   2055         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
   2056           SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
   2057           QuestionDefaultInfo->mDefaultValueRecord = pSNode;
   2058         }
   2059         //
   2060         // Update the QuestionDefaultInfo.
   2061         //
   2062         for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
   2063           if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
   2064             if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   2065               QuestionDefaultInfo->mDefaultNumber ++;
   2066               QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
   2067             }
   2068             break;
   2069           }
   2070         }
   2071       }
   2072       break;
   2073     case EFI_IFR_DEFAULT_OP:
   2074       DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;
   2075       //
   2076       // Check whether need to update the smallest default id and QuestionDefaultInfo.
   2077       //
   2078       if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {
   2079         SmallestDefaultId = DefaultOpcode->DefaultId;
   2080         QuestionDefaultInfo->mDefaultValueRecord= pSNode;
   2081         QuestionDefaultInfo->mIsDefaultOpcode= TRUE;
   2082       }
   2083       //
   2084       // Update the QuestionDefaultInfo.
   2085       //
   2086       for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){
   2087         if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {
   2088           if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
   2089             QuestionDefaultInfo->mDefaultNumber ++;
   2090             QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
   2091           }
   2092           break;
   2093         }
   2094       }
   2095       break;
   2096     default:
   2097       break;
   2098     }
   2099     //
   2100     // Parse next opcode in this question.
   2101     //
   2102     pSNode = pSNode->mNext;
   2103   }
   2104 }
   2105 
   2106 /**
   2107   Check or add default for question if need.
   2108 
   2109   This function will check the default info for question.
   2110   If the question has default, but the default number < defaultstore opcode number.
   2111   will do following two action :
   2112 
   2113   1. if (AutoDefault) will add default for question to support all kinds of defaults.
   2114   2. if (CheckDefault) will generate an error to tell user the question misses some default value.
   2115 
   2116   We assume that the two options can not be TRUE at same time.
   2117   If they are TRUE at same time, only do the action corresponding to AutoDefault option.
   2118 
   2119   @param  AutoDefault          Add default for question if needed
   2120   @param  CheckDefault         Check the default info, if missing default, generates an error.
   2121 
   2122 **/
   2123 VOID
   2124 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
   2125   BOOLEAN  AutoDefault,
   2126   BOOLEAN  CheckDefault
   2127   )
   2128 {
   2129   SIfrRecord            *pNode;
   2130   SIfrRecord            *pTailNode;
   2131   SIfrRecord            *pStartAdjustNode;
   2132   EFI_IFR_OP_HEADER     *pOpHead;
   2133   QuestionDefaultRecord  QuestionDefaultInfo;
   2134   UINT8                  MissingDefaultCount;
   2135   CHAR8                  Msg[MAX_STRING_LEN] = {0, };
   2136 
   2137   pNode               = mIfrRecordListHead;
   2138 
   2139   //
   2140   // Record the number and default id of all defaultstore opcode.
   2141   //
   2142   IfrGetDefaultStoreInfo ();
   2143 
   2144   while (pNode != NULL) {
   2145     pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
   2146     //
   2147     // Check whether is question opcode.
   2148     //
   2149     if (CheckQuestionOpCode (pOpHead->OpCode)) {
   2150       //
   2151       // Initialize some local variables here, because they vary with question.
   2152       // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
   2153       //
   2154       memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));
   2155       pTailNode = mIfrRecordListTail;
   2156       //
   2157       // Get the QuestionDefaultInfo for current question.
   2158       //
   2159       IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);
   2160 
   2161       if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {
   2162         if (AutoDefault) {
   2163           //
   2164           // Create default for question which misses default.
   2165           //
   2166           IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);
   2167 
   2168           //
   2169           // Adjust the buffer content.
   2170           // pStartAdjustNode->mIfrBinBuf points to the insert position.
   2171           // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
   2172           //
   2173           pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);
   2174           gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);
   2175 
   2176           //
   2177           // Update the record info.
   2178           //
   2179           IfrUpdateRecordInfoForDynamicOpcode (TRUE);
   2180         } else if (CheckDefault) {
   2181           //
   2182           // Generate an error for question which misses default.
   2183           //
   2184           MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;
   2185           sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);
   2186           gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);
   2187         }
   2188       }
   2189     }
   2190     //
   2191     // parse next opcode.
   2192     //
   2193     pNode = pNode->mNext;
   2194   }
   2195 }
   2196 
   2197 CIfrRecordInfoDB gCIfrRecordInfoDB;
   2198 
   2199 VOID
   2200 CIfrObj::_EMIT_PENDING_OBJ (
   2201   VOID
   2202   )
   2203 {
   2204   CHAR8  *ObjBinBuf = NULL;
   2205 
   2206   //
   2207   // do nothing
   2208   //
   2209   if (!mDelayEmit || !gCreateOp) {
   2210     return;
   2211   }
   2212 
   2213   mPkgOffset = gCFormPkg.GetPkgLength ();
   2214   //
   2215   // update data buffer to package data
   2216   //
   2217   ObjBinBuf  = gCFormPkg.IfrBinBufferGet (mObjBinLen);
   2218   if (ObjBinBuf != NULL) {
   2219     memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
   2220   }
   2221 
   2222   //
   2223   // update bin buffer to package data buffer
   2224   //
   2225   if (mObjBinBuf != NULL) {
   2226     delete mObjBinBuf;
   2227     mObjBinBuf = ObjBinBuf;
   2228   }
   2229 
   2230   mDelayEmit = FALSE;
   2231 }
   2232 
   2233 /*
   2234  * The definition of CIfrObj's member function
   2235  */
   2236 static struct {
   2237   UINT8  mSize;
   2238   UINT8  mScope;
   2239 } gOpcodeSizesScopeTable[] = {
   2240   { 0, 0 },                                    // EFI_IFR_INVALID - 0x00
   2241   { sizeof (EFI_IFR_FORM), 1 },                // EFI_IFR_FORM_OP
   2242   { sizeof (EFI_IFR_SUBTITLE), 1 },            // EFI_IFR_SUBTITLE_OP
   2243   { sizeof (EFI_IFR_TEXT), 0 },                // EFI_IFR_TEXT_OP
   2244   { sizeof (EFI_IFR_IMAGE), 0 },               // EFI_IFR_IMAGE_OP
   2245   { sizeof (EFI_IFR_ONE_OF), 1 },              // EFI_IFR_ONE_OF_OP - 0x05
   2246   { sizeof (EFI_IFR_CHECKBOX), 1},             // EFI_IFR_CHECKBOX_OP
   2247   { sizeof (EFI_IFR_NUMERIC), 1 },             // EFI_IFR_NUMERIC_OP
   2248   { sizeof (EFI_IFR_PASSWORD), 1 },            // EFI_IFR_PASSWORD_OP
   2249   { sizeof (EFI_IFR_ONE_OF_OPTION), 0 },       // EFI_IFR_ONE_OF_OPTION_OP
   2250   { sizeof (EFI_IFR_SUPPRESS_IF), 1 },         // EFI_IFR_SUPPRESS_IF - 0x0A
   2251   { sizeof (EFI_IFR_LOCKED), 0 },              // EFI_IFR_LOCKED_OP
   2252   { sizeof (EFI_IFR_ACTION), 1 },              // EFI_IFR_ACTION_OP
   2253   { sizeof (EFI_IFR_RESET_BUTTON), 1 },        // EFI_IFR_RESET_BUTTON_OP
   2254   { sizeof (EFI_IFR_FORM_SET), 1 },            // EFI_IFR_FORM_SET_OP -0xE
   2255   { sizeof (EFI_IFR_REF), 0 },                 // EFI_IFR_REF_OP
   2256   { sizeof (EFI_IFR_NO_SUBMIT_IF), 1},         // EFI_IFR_NO_SUBMIT_IF_OP -0x10
   2257   { sizeof (EFI_IFR_INCONSISTENT_IF), 1 },     // EFI_IFR_INCONSISTENT_IF_OP
   2258   { sizeof (EFI_IFR_EQ_ID_VAL), 0 },           // EFI_IFR_EQ_ID_VAL_OP
   2259   { sizeof (EFI_IFR_EQ_ID_ID), 0 },            // EFI_IFR_EQ_ID_ID_OP
   2260   { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 },      // EFI_IFR_EQ_ID_LIST_OP - 0x14
   2261   { sizeof (EFI_IFR_AND), 0 },                 // EFI_IFR_AND_OP
   2262   { sizeof (EFI_IFR_OR), 0 },                  // EFI_IFR_OR_OP
   2263   { sizeof (EFI_IFR_NOT), 0 },                 // EFI_IFR_NOT_OP
   2264   { sizeof (EFI_IFR_RULE), 1 },                // EFI_IFR_RULE_OP
   2265   { sizeof (EFI_IFR_GRAY_OUT_IF), 1 },         // EFI_IFR_GRAYOUT_IF_OP - 0x19
   2266   { sizeof (EFI_IFR_DATE), 1 },                // EFI_IFR_DATE_OP
   2267   { sizeof (EFI_IFR_TIME), 1 },                // EFI_IFR_TIME_OP
   2268   { sizeof (EFI_IFR_STRING), 1 },              // EFI_IFR_STRING_OP
   2269   { sizeof (EFI_IFR_REFRESH), 0 },             // EFI_IFR_REFRESH_OP
   2270   { sizeof (EFI_IFR_DISABLE_IF), 1 },          // EFI_IFR_DISABLE_IF_OP - 0x1E
   2271   { 0, 0 },                                    // 0x1F
   2272   { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20
   2273   { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21
   2274   { sizeof (EFI_IFR_MAP), 1 },                 // EFI_IFR_MAP - 0x22
   2275   { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23
   2276   { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP
   2277   { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
   2278   { sizeof (EFI_IFR_VARSTORE_EFI), 0 },        // EFI_IFR_VARSTORE_EFI_OP
   2279   { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP
   2280   { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28
   2281   { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP
   2282   { sizeof (EFI_IFR_MATCH), 0 },               // EFI_IFR_MATCH_OP - 0x2A
   2283   { sizeof (EFI_IFR_GET), 0 },                 // EFI_IFR_GET - 0x2B
   2284   { sizeof (EFI_IFR_SET), 0 },                 // EFI_IFR_SET - 0x2C
   2285   { sizeof (EFI_IFR_READ), 0 },                // EFI_IFR_READ - 0x2D
   2286   { sizeof (EFI_IFR_WRITE), 0 },               // EFI_IFR_WRITE - 0x2E
   2287   { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F
   2288   { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP
   2289   { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP
   2290   { sizeof (EFI_IFR_GREATER_EQUAL), 0 },       // EFI_IFR_GREATER_EQUAL_OP
   2291   { sizeof (EFI_IFR_LESS_THAN), 0 },           // EFI_IFR_LESS_THAN_OP
   2292   { sizeof (EFI_IFR_LESS_EQUAL), 0 },          // EFI_IFR_LESS_EQUAL_OP - 0x34
   2293   { sizeof (EFI_IFR_BITWISE_AND), 0 },         // EFI_IFR_BITWISE_AND_OP
   2294   { sizeof (EFI_IFR_BITWISE_OR), 0 },          // EFI_IFR_BITWISE_OR_OP
   2295   { sizeof (EFI_IFR_BITWISE_NOT), 0 },         // EFI_IFR_BITWISE_NOT_OP
   2296   { sizeof (EFI_IFR_SHIFT_LEFT), 0 },          // EFI_IFR_SHIFT_LEFT_OP
   2297   { sizeof (EFI_IFR_SHIFT_RIGHT), 0 },         // EFI_IFR_SHIFT_RIGHT_OP
   2298   { sizeof (EFI_IFR_ADD), 0 },                 // EFI_IFR_ADD_OP - 0x3A
   2299   { sizeof (EFI_IFR_SUBTRACT), 0 },            // EFI_IFR_SUBTRACT_OP
   2300   { sizeof (EFI_IFR_MULTIPLY), 0 },            // EFI_IFR_MULTIPLY_OP
   2301   { sizeof (EFI_IFR_DIVIDE), 0 },              // EFI_IFR_DIVIDE_OP
   2302   { sizeof (EFI_IFR_MODULO), 0 },              // EFI_IFR_MODULO_OP - 0x3E
   2303   { sizeof (EFI_IFR_RULE_REF), 0 },            // EFI_IFR_RULE_REF_OP
   2304   { sizeof (EFI_IFR_QUESTION_REF1), 0 },       // EFI_IFR_QUESTION_REF1_OP
   2305   { sizeof (EFI_IFR_QUESTION_REF2), 0 },       // EFI_IFR_QUESTION_REF2_OP - 0x41
   2306   { sizeof (EFI_IFR_UINT8), 0},                // EFI_IFR_UINT8
   2307   { sizeof (EFI_IFR_UINT16), 0},               // EFI_IFR_UINT16
   2308   { sizeof (EFI_IFR_UINT32), 0},               // EFI_IFR_UINT32
   2309   { sizeof (EFI_IFR_UINT64), 0},               // EFI_IFR_UTNT64
   2310   { sizeof (EFI_IFR_TRUE), 0 },                // EFI_IFR_TRUE_OP - 0x46
   2311   { sizeof (EFI_IFR_FALSE), 0 },               // EFI_IFR_FALSE_OP
   2312   { sizeof (EFI_IFR_TO_UINT), 0 },             // EFI_IFR_TO_UINT_OP
   2313   { sizeof (EFI_IFR_TO_STRING), 0 },           // EFI_IFR_TO_STRING_OP
   2314   { sizeof (EFI_IFR_TO_BOOLEAN), 0 },          // EFI_IFR_TO_BOOLEAN_OP
   2315   { sizeof (EFI_IFR_MID), 0 },                 // EFI_IFR_MID_OP
   2316   { sizeof (EFI_IFR_FIND), 0 },                // EFI_IFR_FIND_OP
   2317   { sizeof (EFI_IFR_TOKEN), 0 },               // EFI_IFR_TOKEN_OP
   2318   { sizeof (EFI_IFR_STRING_REF1), 0 },         // EFI_IFR_STRING_REF1_OP - 0x4E
   2319   { sizeof (EFI_IFR_STRING_REF2), 0 },         // EFI_IFR_STRING_REF2_OP
   2320   { sizeof (EFI_IFR_CONDITIONAL), 0 },         // EFI_IFR_CONDITIONAL_OP
   2321   { sizeof (EFI_IFR_QUESTION_REF3), 0 },       // EFI_IFR_QUESTION_REF3_OP
   2322   { sizeof (EFI_IFR_ZERO), 0 },                // EFI_IFR_ZERO_OP
   2323   { sizeof (EFI_IFR_ONE), 0 },                 // EFI_IFR_ONE_OP
   2324   { sizeof (EFI_IFR_ONES), 0 },                // EFI_IFR_ONES_OP
   2325   { sizeof (EFI_IFR_UNDEFINED), 0 },           // EFI_IFR_UNDEFINED_OP
   2326   { sizeof (EFI_IFR_LENGTH), 0 },              // EFI_IFR_LENGTH_OP
   2327   { sizeof (EFI_IFR_DUP), 0 },                 // EFI_IFR_DUP_OP - 0x57
   2328   { sizeof (EFI_IFR_THIS), 0 },                // EFI_IFR_THIS_OP
   2329   { sizeof (EFI_IFR_SPAN), 0 },                // EFI_IFR_SPAN_OP
   2330   { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP
   2331   { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP
   2332   { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C
   2333   { sizeof (EFI_IFR_FORM_MAP), 1},             // EFI_IFR_FORM_MAP_OP - 0x5D
   2334   { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP
   2335   { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP
   2336   { sizeof (EFI_IFR_SECURITY), 0 },            // EFI_IFR_SECURITY_OP - 0x60
   2337   { sizeof (EFI_IFR_MODAL_TAG), 0},            // EFI_IFR_MODAL_TAG_OP - 0x61
   2338   { sizeof (EFI_IFR_REFRESH_ID), 0},           // EFI_IFR_REFRESH_ID_OP - 0x62
   2339   { sizeof (EFI_IFR_WARNING_IF), 1},           // EFI_IFR_WARNING_IF_OP - 0x63
   2340   { sizeof (EFI_IFR_MATCH2), 0 },              // EFI_IFR_MATCH2_OP - 0x64
   2341 };
   2342 
   2343 #ifdef CIFROBJ_DEUBG
   2344 static struct {
   2345   CHAR8 *mIfrName;
   2346 } gIfrObjPrintDebugTable[] = {
   2347   "EFI_IFR_INVALID",    "EFI_IFR_FORM",                 "EFI_IFR_SUBTITLE",      "EFI_IFR_TEXT",            "EFI_IFR_IMAGE",         "EFI_IFR_ONE_OF",
   2348   "EFI_IFR_CHECKBOX",   "EFI_IFR_NUMERIC",              "EFI_IFR_PASSWORD",      "EFI_IFR_ONE_OF_OPTION",   "EFI_IFR_SUPPRESS_IF",   "EFI_IFR_LOCKED",
   2349   "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",
   2350   "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",
   2351   "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",
   2352   "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_MAP",           "EFI_IFR_ORDERED_LIST",
   2353   "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",
   2354   "EFI_IFR_MATCH",      "EFI_IFR_GET",                  "EFI_IFR_SET",           "EFI_IFR_READ",            "EFI_IFR_WRITE",         "EFI_IFR_EQUAL",
   2355   "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",
   2356   "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",
   2357   "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
   2358   "EFI_IFR_UINT8",      "EFI_IFR_UINT16",               "EFI_IFR_UINT32",        "EFI_IFR_UINT64",          "EFI_IFR_TRUE",          "EFI_IFR_FALSE",
   2359   "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",
   2360   "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2",          "EFI_IFR_CONDITIONAL",   "EFI_IFR_QUESTION_REF3",   "EFI_IFR_ZERO",          "EFI_IFR_ONE",
   2361   "EFI_IFR_ONES",       "EFI_IFR_UNDEFINED",            "EFI_IFR_LENGTH",        "EFI_IFR_DUP",             "EFI_IFR_THIS",          "EFI_IFR_SPAN",
   2362   "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_FORM_MAP",        "EFI_IFR_CATENATE",      "EFI_IFR_GUID",
   2363   "EFI_IFR_SECURITY",   "EFI_IFR_MODAL_TAG",            "EFI_IFR_REFRESH_ID",    "EFI_IFR_WARNING_IF",      "EFI_IFR_MATCH2",
   2364 };
   2365 
   2366 VOID
   2367 CIFROBJ_DEBUG_PRINT (
   2368   IN UINT8 OpCode
   2369   )
   2370 {
   2371   printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
   2372 }
   2373 #else
   2374 
   2375 #define CIFROBJ_DEBUG_PRINT(OpCode)
   2376 
   2377 #endif
   2378 
   2379 BOOLEAN gCreateOp = TRUE;
   2380 
   2381 CIfrObj::CIfrObj (
   2382   IN  UINT8   OpCode,
   2383   OUT CHAR8   **IfrObj,
   2384   IN  UINT8   ObjBinLen,
   2385   IN  BOOLEAN DelayEmit
   2386   )
   2387 {
   2388   mDelayEmit   = DelayEmit;
   2389   mPkgOffset   = gCFormPkg.GetPkgLength ();
   2390   mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
   2391   mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
   2392   mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
   2393 
   2394   assert (mObjBinBuf != NULL);
   2395 
   2396   if (IfrObj != NULL) {
   2397     *IfrObj    = mObjBinBuf;
   2398   }
   2399 
   2400   CIFROBJ_DEBUG_PRINT (OpCode);
   2401 }
   2402 
   2403 CIfrObj::~CIfrObj (
   2404   VOID
   2405   )
   2406 {
   2407   if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
   2408     _EMIT_PENDING_OBJ ();
   2409   }
   2410 
   2411   gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
   2412 }
   2413 
   2414 /*
   2415  * The definition of CIfrObj's member function
   2416  */
   2417 UINT8 gScopeCount = 0;
   2418 
   2419 CIfrOpHeader::CIfrOpHeader (
   2420   IN UINT8 OpCode,
   2421   IN VOID *StartAddr,
   2422   IN UINT8 Length
   2423   ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
   2424 {
   2425   mHeader->OpCode = OpCode;
   2426   mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
   2427   mHeader->Scope  = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
   2428 }
   2429 
   2430 CIfrOpHeader::CIfrOpHeader (
   2431   IN CIfrOpHeader &OpHdr
   2432   )
   2433 {
   2434   mHeader = OpHdr.mHeader;
   2435 }
   2436 
   2437 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };
   2438