]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiVfrCompile / VfrFormPkg.cpp
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp b/EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp
new file mode 100644 (file)
index 0000000..2ac1b68
--- /dev/null
@@ -0,0 +1,830 @@
+#include "stdio.h"\r
+#include "VfrFormPkg.h"\r
+\r
+/*\r
+ * The definition of CFormPkg's member function\r
+ */\r
+\r
+SPendingAssign::SPendingAssign (\r
+  IN INT8   *Key, \r
+  IN VOID   *Addr, \r
+  IN UINT32 Len, \r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  if (Key != NULL) {\r
+    mKey = new INT8[strlen (Key) + 1];\r
+    if (mKey != NULL) {\r
+      strcpy (mKey, Key);\r
+    }\r
+  } else {\r
+    mKey = NULL;\r
+  }\r
+  mAddr   = Addr;\r
+  mLen    = Len;\r
+  mFlag   = PENDING;\r
+  mLineNo = LineNo;\r
+  mNext   = NULL;\r
+}\r
+\r
+SPendingAssign::~SPendingAssign (\r
+  VOID\r
+  )\r
+{\r
+  if (mKey != NULL) {\r
+    delete mKey;\r
+  }\r
+  mAddr   = NULL;\r
+  mLen    = 0;\r
+  mLineNo = 0;\r
+  mNext   = NULL;\r
+}\r
+\r
+VOID\r
+SPendingAssign::SetAddrAndLen (\r
+  IN VOID   *Addr, \r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  mAddr   = Addr;\r
+  mLineNo = LineNo;\r
+}\r
+\r
+VOID\r
+SPendingAssign::AssignValue (\r
+  IN VOID   *Addr, \r
+  IN UINT32 Len\r
+  )\r
+{\r
+  memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));\r
+  mFlag = ASSIGNED;\r
+}\r
+\r
+INT8 *\r
+SPendingAssign::GetKey (\r
+  VOID\r
+  )\r
+{\r
+  return mKey;\r
+}\r
+\r
+CFormPkg::CFormPkg (\r
+  IN UINT32 BufferSize = 4096\r
+  )\r
+{\r
+  CHAR8       *BufferStart;\r
+  CHAR8       *BufferEnd;\r
+  SBufferNode *Node;\r
+\r
+  mPkgLength           = 0;\r
+  mBufferNodeQueueHead = NULL;\r
+  mCurrBufferNode      = NULL;\r
+\r
+  Node = new SBufferNode;\r
+  if (Node == NULL) {\r
+    return ;\r
+  }\r
+  BufferStart = new CHAR8[BufferSize];\r
+  if (BufferStart == NULL) {\r
+    return;\r
+  }\r
+  BufferEnd   = BufferStart + BufferSize;\r
+\r
+  memset (BufferStart, 0, BufferSize);\r
+  Node->mBufferStart   = BufferStart;\r
+  Node->mBufferEnd     = BufferEnd;\r
+  Node->mBufferFree    = BufferStart;\r
+  Node->mNext          = NULL;\r
+\r
+  mBufferSize          = BufferSize;\r
+  mBufferNodeQueueHead = Node;\r
+  mBufferNodeQueueTail = Node;\r
+  mCurrBufferNode      = Node;\r
+}\r
+\r
+CFormPkg::~CFormPkg ()\r
+{\r
+  SBufferNode    *pBNode;\r
+  SPendingAssign *pPNode;\r
+\r
+  while (mBufferNodeQueueHead != NULL) {\r
+    pBNode = mBufferNodeQueueHead;\r
+    mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
+    if (pBNode->mBufferStart != NULL) {\r
+      delete pBNode->mBufferStart;\r
+      delete pBNode;\r
+    }\r
+  }\r
+  mBufferNodeQueueTail = NULL;\r
+  mCurrBufferNode      = NULL;\r
+\r
+  while (PendingAssignList != NULL) {\r
+    pPNode = PendingAssignList;\r
+    PendingAssignList = PendingAssignList->mNext;\r
+    delete pPNode;\r
+  }\r
+  PendingAssignList = NULL;\r
+}\r
+\r
+CHAR8 *\r
+CFormPkg::IfrBinBufferGet (\r
+  IN UINT32 Len\r
+  )\r
+{\r
+  CHAR8 *BinBuffer = NULL;\r
+\r
+  if ((Len == 0) || (Len > mBufferSize)) {\r
+    return NULL;\r
+  }\r
+\r
+  if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
+    BinBuffer = mCurrBufferNode->mBufferFree;\r
+    mCurrBufferNode->mBufferFree += Len;\r
+  } else {\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
+    if (mBufferNodeQueueTail == NULL) {\r
+      mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
+    } else {\r
+      mBufferNodeQueueTail->mNext = Node;\r
+      mBufferNodeQueueTail = Node;\r
+    }\r
+    mCurrBufferNode = Node;\r
+\r
+    //\r
+    // Now try again.\r
+    //\r
+    BinBuffer = mCurrBufferNode->mBufferFree;\r
+    mCurrBufferNode->mBufferFree += Len;\r
+  }\r
+\r
+  mPkgLength += Len;\r
+\r
+  return BinBuffer;\r
+}\r
+\r
+inline\r
+UINT32\r
+CFormPkg::GetPkgLength (\r
+  VOID\r
+  )\r
+{\r
+  return mPkgLength;\r
+}\r
+\r
+VOID\r
+CFormPkg::Open (\r
+  VOID\r
+  )\r
+{\r
+  mReadBufferNode   = mBufferNodeQueueHead;\r
+  mReadBufferOffset = 0;\r
+}\r
+\r
+VOID\r
+CFormPkg::Close (\r
+  VOID\r
+  )\r
+{\r
+  mReadBufferNode   = NULL;\r
+  mReadBufferOffset = 0;\r
+}\r
+\r
+UINT32\r
+CFormPkg::Read (\r
+  IN CHAR8     *Buffer, \r
+  IN UINT32    Size\r
+  )\r
+{\r
+  UINT32       Index;\r
+\r
+  if ((Size == 0) || (Buffer == NULL)) {\r
+    return 0;\r
+  }\r
+\r
+  if (mReadBufferNode == NULL) {\r
+       return 0;\r
+  }\r
+\r
+  for (Index = 0; Index < Size; Index++) {\r
+    if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
+      Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+    } else {\r
+      if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
+        return Index;\r
+      } else {\r
+        mReadBufferOffset = 0;\r
+        Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+      }\r
+    }\r
+  }\r
+\r
+  return Size;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::BuildPkgHdr (\r
+  OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
+  )\r
+{\r
+  if (PkgHdr == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
+  (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::BuildPkg (\r
+  IN FILE  *Output\r
+  )\r
+{\r
+  EFI_VFR_RETURN_CODE     Ret;\r
+  CHAR8                   Buffer[1024];\r
+  UINT32                  Size;\r
+  EFI_HII_PACKAGE_HEADER  *PkgHdr;\r
+\r
+  if (Output == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
+    return Ret;\r
+  }\r
+  fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
+  delete PkgHdr;\r
+\r
+  Open ();\r
+  while ((Size = Read (Buffer, 1024)) != 0) {\r
+    fwrite (Buffer, Size, 1, Output);\r
+  }\r
+  Close ();\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CFormPkg::_WRITE_PKG_LINE (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+}\r
+\r
+VOID\r
+CFormPkg::_WRITE_PKG_END (\r
+  IN FILE   *pFile,\r
+  IN UINT32 LineBytes,\r
+  IN INT8   *LineHeader,\r
+  IN INT8   *BlkBuf,\r
+  IN UINT32 BlkSize\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; Index < BlkSize - 1; Index++) {\r
+    if ((Index % LineBytes) == 0) {\r
+      fprintf (pFile, "\n%s", LineHeader);\r
+    }\r
+    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
+  }\r
+\r
+  if ((Index % LineBytes) == 0) {\r
+    fprintf (pFile, "\n%s", LineHeader);\r
+  }\r
+  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
+}\r
+\r
+#define BYTES_PRE_LINE 0x10\r
+\r
+EFI_VFR_RETURN_CODE \r
+CFormPkg::GenCFile (\r
+  IN INT8 *BaseName,\r
+  IN FILE *pFile\r
+  )\r
+{\r
+  EFI_VFR_RETURN_CODE          Ret;\r
+  INT8                         Buffer[BYTES_PRE_LINE * 8];\r
+  EFI_HII_PACKAGE_HEADER       *PkgHdr;\r
+  UINT32                       PkgLength  = 0;\r
+  UINT32                       ReadSize   = 0;\r
+\r
+  if ((BaseName == NULL) || (pFile == NULL)) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
+\r
+  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
+    return Ret;\r
+  }\r
+\r
+  fprintf (pFile, "  // ARRAY LENGTH\n");\r
+  PkgLength = PkgHdr->Length + sizeof (UINT32);\r
+  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)&PkgLength, sizeof (UINT32));\r
+\r
+  fprintf (pFile, "\n\n  // PACKAGE HEADER\n");\r
+  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
+  PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  fprintf (pFile, "\n\n  // PACKAGE DATA\n");\r
+  Open ();\r
+  while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
+    PkgLength += ReadSize;\r
+    if (PkgLength < PkgHdr->Length) {\r
+      _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);\r
+    } else {\r
+      _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);\r
+    }\r
+  }\r
+  Close ();\r
+\r
+  delete PkgHdr;\r
+  fprintf (pFile, "\n};\n");\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::AssignPending (\r
+  IN INT8   *Key, \r
+  IN VOID   *ValAddr, \r
+  IN UINT32 ValLen,\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  SPendingAssign *pNew;\r
+\r
+  pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo);\r
+  if (pNew == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  pNew->mNext       = PendingAssignList;\r
+  PendingAssignList = pNew;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+VOID\r
+CFormPkg::DoPendingAssign (\r
+  IN INT8   *Key, \r
+  IN VOID   *ValAddr, \r
+  IN UINT32 ValLen\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  if ((Key == NULL) || (ValAddr == NULL)) {\r
+    return;\r
+  }\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mKey, Key) == 0) {\r
+      pNode->AssignValue (ValAddr, ValLen);\r
+    }\r
+  }\r
+}\r
+\r
+bool\r
+CFormPkg::HavePendingUnassigned (\r
+  VOID\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mFlag == PENDING) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+CFormPkg::PendingAssignPrintAll (\r
+  VOID\r
+  )\r
+{\r
+  SPendingAssign *pNode;\r
+\r
+  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mFlag == PENDING) {\r
+      gCVfrErrorHandle.PrintError (pNode->mLineNo, pNode->mKey, "can not assign value because not defined");\r
+    }\r
+  }\r
+}\r
+\r
+CFormPkg gCFormPkg;\r
+\r
+SIfrRecord::SIfrRecord (\r
+  VOID\r
+  )\r
+{\r
+  mIfrBinBuf = NULL;\r
+  mBinBufLen = 0;\r
+  mLineNo    = 0xFFFFFFFF;\r
+  mOffset    = 0xFFFFFFFF;\r
+  mNext      = NULL;\r
+}\r
+\r
+SIfrRecord::~SIfrRecord (\r
+  VOID\r
+  )\r
+{\r
+  if (mIfrBinBuf != NULL) {\r
+    delete mIfrBinBuf;\r
+    mIfrBinBuf = NULL;\r
+  }\r
+  mLineNo      = 0xFFFFFFFF;\r
+  mOffset      = 0xFFFFFFFF;\r
+  mBinBufLen   = 0;\r
+  mNext        = NULL;\r
+}\r
+\r
+CIfrRecordInfoDB::CIfrRecordInfoDB (\r
+  VOID\r
+  )\r
+{\r
+  mSwitch            = FALSE;\r
+  mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;\r
+  mIfrRecordListHead = NULL;\r
+  mIfrRecordListTail = NULL;\r
+}\r
+\r
+CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
+  VOID\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+\r
+  while (mIfrRecordListHead != NULL) {\r
+    pNode = mIfrRecordListHead;\r
+    mIfrRecordListHead = mIfrRecordListHead->mNext;\r
+    delete pNode;\r
+  }\r
+}\r
+\r
+SIfrRecord *\r
+CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
+  IN UINT32 RecordIdx\r
+  )\r
+{\r
+  UINT32     Idx;\r
+  SIfrRecord *pNode = NULL;\r
+\r
+  if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
+    return NULL;\r
+  }\r
+\r
+  for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead; \r
+       (Idx != RecordIdx) && (pNode != NULL); \r
+       Idx++, pNode = pNode->mNext)\r
+  ;\r
+\r
+  return pNode;\r
+}\r
+\r
+UINT32\r
+CIfrRecordInfoDB::IfrRecordRegister (\r
+  IN UINT32 LineNo, \r
+  IN CHAR8  *IfrBinBuf, \r
+  IN UINT8  BinBufLen,\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNew;\r
+\r
+  if (mSwitch == FALSE) {\r
+    return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+  }\r
+\r
+  if ((pNew = new SIfrRecord) == NULL) {\r
+    return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+  }\r
+\r
+  if (mIfrRecordListHead == NULL) {\r
+    mIfrRecordListHead = pNew;\r
+    mIfrRecordListTail = pNew;\r
+  } else {\r
+    mIfrRecordListTail->mNext = pNew;\r
+    mIfrRecordListTail = pNew;\r
+  }\r
+  mRecordCount++;\r
+\r
+  return mRecordCount;\r
+}\r
+\r
+VOID\r
+CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
+  IN UINT32 RecordIdx, \r
+  IN UINT32 LineNo,\r
+  IN CHAR8  *BinBuf,\r
+  IN UINT8  BinBufLen,\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+\r
+  if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
+    return;\r
+  }\r
+\r
+  pNode->mLineNo    = LineNo;\r
+  pNode->mOffset    = Offset;\r
+  pNode->mBinBufLen = BinBufLen;\r
+  if (BinBuf != NULL) {\r
+    if (pNode->mIfrBinBuf != NULL) {\r
+      delete pNode->mIfrBinBuf;\r
+    }\r
+    pNode->mIfrBinBuf = new CHAR8[BinBufLen];\r
+    if (pNode->mIfrBinBuf != NULL) {\r
+      memcpy (pNode->mIfrBinBuf, BinBuf, BinBufLen);\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+CIfrRecordInfoDB::IfrRecordOutput (\r
+  IN FILE   *File,\r
+  IN UINT32 LineNo\r
+  )\r
+{\r
+  SIfrRecord *pNode;\r
+  UINT8      Index;\r
+\r
+  if (mSwitch == FALSE) {\r
+    return;\r
+  }\r
+\r
+  if (File == NULL) {\r
+    return;\r
+  }\r
+\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mLineNo == LineNo) {\r
+      fprintf (File, ">%08X: ", pNode->mOffset);\r
+      if (pNode->mIfrBinBuf != NULL) {\r
+        for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
+          fprintf (File, "%02X ", pNode->mIfrBinBuf[Index]);\r
+        }\r
+      }\r
+      fprintf (File, "\n");\r
+    }\r
+  }\r
+}\r
+\r
+CIfrRecordInfoDB gCIfrRecordInfoDB;\r
+\r
+VOID\r
+CIfrObj::_EMIT_PENDING_OBJ (\r
+  VOID\r
+  )\r
+{\r
+  CHAR8  *ObjBinBuf = NULL;\r
+\r
+  ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
+  if (ObjBinBuf != NULL) {\r
+    memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
+  }\r
+\r
+  if (mObjBinBuf != NULL) {\r
+    delete mObjBinBuf;\r
+  }\r
+}\r
+\r
+/*\r
+ * The definition of CIfrObj's member function\r
+ */\r
+static struct {\r
+  UINT8  mSize;\r
+  UINT8  mScope;\r
+} gOpcodeSizesScopeTable[] = {\r
+  { 0, 0 },                                    // EFI_IFR_INVALID - 0x00\r
+  { sizeof (EFI_IFR_FORM), 1 },                // EFI_IFR_FORM_OP\r
+  { sizeof (EFI_IFR_SUBTITLE), 1 },            // EFI_IFR_SUBTITLE_OP\r
+  { sizeof (EFI_IFR_TEXT), 0 },                // EFI_IFR_TEXT_OP\r
+  { sizeof (EFI_IFR_IMAGE), 0 },               // EFI_IFR_IMAGE_OP\r
+  { sizeof (EFI_IFR_ONE_OF), 1 },              // EFI_IFR_ONE_OF_OP - 0x05\r
+  { sizeof (EFI_IFR_CHECKBOX), 1},             // EFI_IFR_CHECKBOX_OP\r
+  { sizeof (EFI_IFR_NUMERIC), 1 },             // EFI_IFR_NUMERIC_OP\r
+  { sizeof (EFI_IFR_PASSWORD), 1 },            // EFI_IFR_PASSWORD_OP\r
+  { sizeof (EFI_IFR_ONE_OF_OPTION), 0 },       // EFI_IFR_ONE_OF_OPTION_OP\r
+  { sizeof (EFI_IFR_SUPPRESS_IF), 1 },         // EFI_IFR_SUPPRESS_IF - 0x0A\r
+  { sizeof (EFI_IFR_LOCKED), 0 },              // EFI_IFR_LOCKED_OP\r
+  { sizeof (EFI_IFR_ACTION), 1 },              // EFI_IFR_ACTION_OP\r
+  { sizeof (EFI_IFR_RESET_BUTTON), 1 },        // EFI_IFR_RESET_BUTTON_OP\r
+  { sizeof (EFI_IFR_FORM_SET), 1 },            // EFI_IFR_FORM_SET_OP -0xE\r
+  { sizeof (EFI_IFR_REF), 0 },                 // EFI_IFR_REF_OP\r
+  { sizeof (EFI_IFR_NO_SUBMIT_IF), 1},         // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
+  { sizeof (EFI_IFR_INCONSISTENT_IF), 1 },     // EFI_IFR_INCONSISTENT_IF_OP\r
+  { sizeof (EFI_IFR_EQ_ID_VAL), 0 },           // EFI_IFR_EQ_ID_VAL_OP\r
+  { sizeof (EFI_IFR_EQ_ID_ID), 0 },            // EFI_IFR_EQ_ID_ID_OP\r
+  { sizeof (EFI_IFR_EQ_ID_LIST), 0 },          // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
+  { sizeof (EFI_IFR_AND), 0 },                 // EFI_IFR_AND_OP\r
+  { sizeof (EFI_IFR_OR), 0 },                  // EFI_IFR_OR_OP\r
+  { sizeof (EFI_IFR_NOT), 0 },                 // EFI_IFR_NOT_OP\r
+  { sizeof (EFI_IFR_RULE), 1 },                // EFI_IFR_RULE_OP\r
+  { sizeof (EFI_IFR_GRAY_OUT_IF), 1 },         // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
+  { sizeof (EFI_IFR_DATE), 1 },                // EFI_IFR_DATE_OP\r
+  { sizeof (EFI_IFR_TIME), 1 },                // EFI_IFR_TIME_OP\r
+  { sizeof (EFI_IFR_STRING), 1 },              // EFI_IFR_STRING_OP\r
+  { sizeof (EFI_IFR_REFRESH), 1 },             // EFI_IFR_REFRESH_OP\r
+  { sizeof (EFI_IFR_DISABLE_IF), 1 },          // EFI_IFR_DISABLE_IF_OP - 0x1E\r
+  { 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_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
+  { sizeof (EFI_IFR_VARSTORE_EFI), 0 },        // EFI_IFR_VARSTORE_EFI_OP\r
+  { 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_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
+  { sizeof (EFI_IFR_GREATER_EQUAL), 0 },       // EFI_IFR_GREATER_EQUAL_OP\r
+  { sizeof (EFI_IFR_LESS_THAN), 0 },           // EFI_IFR_LESS_THAN_OP\r
+  { sizeof (EFI_IFR_LESS_EQUAL), 0 },          // EFI_IFR_LESS_EQUAL_OP - 0x34\r
+  { sizeof (EFI_IFR_BITWISE_AND), 0 },         // EFI_IFR_BITWISE_AND_OP\r
+  { sizeof (EFI_IFR_BITWISE_OR), 0 },          // EFI_IFR_BITWISE_OR_OP\r
+  { sizeof (EFI_IFR_BITWISE_NOT), 0 },         // EFI_IFR_BITWISE_NOT_OP\r
+  { sizeof (EFI_IFR_SHIFT_LEFT), 0 },          // EFI_IFR_SHIFT_LEFT_OP\r
+  { sizeof (EFI_IFR_SHIFT_RIGHT), 0 },         // EFI_IFR_SHIFT_RIGHT_OP\r
+  { sizeof (EFI_IFR_ADD), 0 },                 // EFI_IFR_ADD_OP - 0x3A\r
+  { sizeof (EFI_IFR_SUBTRACT), 0 },            // EFI_IFR_SUBTRACT_OP\r
+  { sizeof (EFI_IFR_MULTIPLY), 0 },            // EFI_IFR_MULTIPLY_OP\r
+  { sizeof (EFI_IFR_DIVIDE), 0 },              // EFI_IFR_DIVIDE_OP\r
+  { sizeof (EFI_IFR_MODULO), 0 },              // EFI_IFR_MODULO_OP - 0x3E\r
+  { sizeof (EFI_IFR_RULE_REF), 0 },            // EFI_IFR_RULE_REF_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF1), 0 },       // EFI_IFR_QUESTION_REF1_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF2), 0 },       // EFI_IFR_QUESTION_REF2_OP - 0x41\r
+  { sizeof (EFI_IFR_UINT8), 0},                // EFI_IFR_UINT8\r
+  { sizeof (EFI_IFR_UINT16), 0},               // EFI_IFR_UINT16\r
+  { sizeof (EFI_IFR_UINT32), 0},               // EFI_IFR_UINT32\r
+  { sizeof (EFI_IFR_UINT64), 0},               // EFI_IFR_UTNT64\r
+  { sizeof (EFI_IFR_TRUE), 0 },                // EFI_IFR_TRUE_OP - 0x46\r
+  { sizeof (EFI_IFR_FALSE), 0 },               // EFI_IFR_FALSE_OP\r
+  { sizeof (EFI_IFR_TO_UINT), 0 },             // EFI_IFR_TO_UINT_OP\r
+  { sizeof (EFI_IFR_TO_STRING), 0 },           // EFI_IFR_TO_STRING_OP\r
+  { sizeof (EFI_IFR_TO_BOOLEAN), 0 },          // EFI_IFR_TO_BOOLEAN_OP\r
+  { sizeof (EFI_IFR_MID), 0 },                 // EFI_IFR_MID_OP\r
+  { sizeof (EFI_IFR_FIND), 0 },                // EFI_IFR_FIND_OP\r
+  { sizeof (EFI_IFR_TOKEN), 0 },               // EFI_IFR_TOKEN_OP\r
+  { sizeof (EFI_IFR_STRING_REF1), 0 },         // EFI_IFR_STRING_REF1_OP - 0x4E\r
+  { sizeof (EFI_IFR_STRING_REF2), 0 },         // EFI_IFR_STRING_REF2_OP\r
+  { sizeof (EFI_IFR_CONDITIONAL), 0 },         // EFI_IFR_CONDITIONAL_OP\r
+  { sizeof (EFI_IFR_QUESTION_REF3), 0 },       // EFI_IFR_QUESTION_REF3_OP\r
+  { sizeof (EFI_IFR_ZERO), 0 },                // EFI_IFR_ZERO_OP\r
+  { sizeof (EFI_IFR_ONE), 0 },                 // EFI_IFR_ONE_OP\r
+  { sizeof (EFI_IFR_ONES), 0 },                // EFI_IFR_ONES_OP\r
+  { sizeof (EFI_IFR_UNDEFINED), 0 },           // EFI_IFR_UNDEFINED_OP\r
+  { sizeof (EFI_IFR_LENGTH), 0 },              // EFI_IFR_LENGTH_OP\r
+  { sizeof (EFI_IFR_DUP), 0 },                 // EFI_IFR_DUP_OP - 0x57\r
+  { sizeof (EFI_IFR_THIS), 0 },                // EFI_IFR_THIS_OP\r
+  { sizeof (EFI_IFR_SPAN), 0 },                // EFI_IFR_SPAN_OP\r
+  { 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_CATENATE), 0 },            // EFI_IFR_CATENATE_OP\r
+  { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP\r
+};\r
+\r
+#ifdef CIFROBJ_DEUBG\r
+static struct {\r
+  INT8 *mIfrName;\r
+} gIfrObjPrintDebugTable[] = {\r
+  "EFI_IFR_INVALID",    "EFI_IFR_FORM",                 "EFI_IFR_SUBTITLE",      "EFI_IFR_TEXT",            "EFI_IFR_IMAGE",         "EFI_IFR_ONE_OF",\r
+  "EFI_IFR_CHECKBOX",   "EFI_IFR_NUMERIC",              "EFI_IFR_PASSWORD",      "EFI_IFR_ONE_OF_OPTION",   "EFI_IFR_SUPPRESS_IF",   "EFI_IFR_LOCKED",\r
+  "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_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_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
+  "EFI_IFR_UINT8",      "EFI_IFR_UINT16",               "EFI_IFR_UINT32",        "EFI_IFR_UINT64",          "EFI_IFR_TRUE",          "EFI_IFR_FALSE",\r
+  "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
+};\r
+\r
+VOID\r
+CIFROBJ_DEBUG_PRINT (\r
+  IN UINT8 OpCode\r
+  )\r
+{\r
+  printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
+}\r
+#else\r
+\r
+#define CIFROBJ_DEBUG_PRINT(OpCode)\r
+\r
+#endif\r
+\r
+bool gCreateOp = TRUE;\r
+\r
+CIfrObj::CIfrObj (\r
+  IN  UINT8   OpCode,\r
+  OUT CHAR8   **IfrObj,\r
+  IN  UINT8   ObjBinLen,\r
+  IN  BOOLEAN DelayEmit\r
+  )\r
+{\r
+  mDelayEmit   = DelayEmit;\r
+  mPkgOffset   = gCFormPkg.GetPkgLength ();\r
+  mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
+  mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
+  mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+\r
+  if (IfrObj != NULL) {\r
+    *IfrObj    = mObjBinBuf;\r
+  }\r
+\r
+  CIFROBJ_DEBUG_PRINT (OpCode);\r
+}\r
+\r
+CIfrObj::~CIfrObj (\r
+  VOID\r
+  )\r
+{\r
+  if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
+    _EMIT_PENDING_OBJ ();\r
+  }\r
+\r
+  gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
+}\r
+\r
+/*\r
+ * The definition of CIfrObj's member function\r
+ */\r
+UINT8 gScopeCount = 0;\r
+\r
+CIfrOpHeader::CIfrOpHeader (\r
+  IN UINT8 OpCode, \r
+  IN VOID *StartAddr,\r
+  IN UINT8 Length \r
+  ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr) \r
+{\r
+  mHeader->OpCode = OpCode;\r
+  mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
+  mHeader->Scope  = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
+}\r
+\r
+CIfrOpHeader::CIfrOpHeader (\r
+  IN CIfrOpHeader &OpHdr\r
+  )\r
+{\r
+  mHeader = OpHdr.mHeader;\r
+}\r
+\r
+UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r