]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c
1) Fix a bug of DefaultVarStoreId of the Form Set should be used when Framework IfrSu...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / OpcodeCreation.c
index 391e698d1e8c6de2c55696a996bfec34802278fb..5b6fb7655aab6f35ba98619b66318e1395c97f50 100644 (file)
@@ -12,41 +12,226 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
+\r
 #include "HiiDatabase.h"\r
-#include "OpcodeCreation.h"\r
 #include "UefiIfrDefault.h"\r
 \r
 EFI_GUID  mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;\r
 \r
+\r
+EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = {\r
+   {EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0},\r
+   EFI_IFR_FRAMEWORK_GUID,\r
+   EFI_IFR_EXTEND_OP_OPTIONKEY,\r
+   0,\r
+   {0},\r
+   0\r
+};\r
+\r
+/**\r
+  The dynamic creation of these opcodes is supported in Framework HII modules.\r
+  Therefore, Framework HII Thunk module only map these opcode between Framework\r
+  HII's definitions to UEFI HII's.\r
+**/\r
+typedef struct { \r
+  UINT8 FrameworkIfrOp;\r
+  UINT8 UefiIfrOp;\r
+} IFR_OPCODE_MAP;\r
+  \r
+IFR_OPCODE_MAP mQuestionOpcodeMap [] = {\r
+  { FRAMEWORK_EFI_IFR_ONE_OF_OP,        EFI_IFR_ONE_OF_OP},\r
+  { FRAMEWORK_EFI_IFR_CHECKBOX_OP,      EFI_IFR_CHECKBOX_OP},\r
+  { FRAMEWORK_EFI_IFR_NUMERIC_OP,       EFI_IFR_NUMERIC_OP},\r
+  { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
+  { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP,  EFI_IFR_ORDERED_LIST_OP}\r
+};\r
+\r
+/**\r
+  Translate a Framework Question Opcode to UEFI Question Opcode.\r
+\r
+  @param FwOp     Framework Opcode.\r
+  @param UefiOp   UEFI Opcode.\r
+\r
+  @retval     EFI_SUCCESS     The UEFI opcode is found and returned.\r
+  @retval     EFI_NOT_FOUND   The UEFI opcode is not found.\r
+**/\r
+EFI_STATUS\r
+QuestionOpFwToUefi (\r
+  IN            UINT8   FwOp,\r
+  OUT           UINT8   *UefiOp\r
+  )\r
+{\r
+  UINTN       Index;\r
+\r
+  for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {\r
+    if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {\r
+      *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  *UefiOp = (UINT8) (FRAMEWORK_EFI_IFR_LAST_OPCODE + 1);\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Translate a Framework Question Opcode to UEFI Question Opcode.\r
+\r
+  @param FwOp     Framework Opcode.\r
+  @param UefiOp   UEFI Opcode.\r
+\r
+  @retval     EFI_SUCCESS     The UEFI opcode is found and returned.\r
+  @retval     EFI_NOT_FOUND   The UEFI opcode is not found.\r
+**/\r
+EFI_STATUS\r
+FwQIdToUefiQId (\r
+  IN  CONST FORM_BROWSER_FORMSET *FormSet,\r
+  IN  UINT8                      FwOpCode,\r
+  IN  UINT16                     FwQId,\r
+  OUT UINT16                     *UefiQId\r
+  )\r
+{\r
+  LIST_ENTRY             *FormList;\r
+  LIST_ENTRY             *StatementList;\r
+  FORM_BROWSER_FORM      *Form;\r
+  FORM_BROWSER_STATEMENT *Statement;\r
+  FORM_BROWSER_STATEMENT *StatementFound;\r
+  EFI_STATUS             Status;\r
+  UINT8                  UefiOp;\r
+  \r
+\r
+  *UefiQId = 0;\r
+  StatementFound = NULL;\r
+\r
+  FormList = GetFirstNode (&FormSet->FormListHead);\r
+\r
+  while (!IsNull (&FormSet->FormListHead, FormList)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
+\r
+    StatementList = GetFirstNode (&Form->StatementListHead);\r
+\r
+    while (!IsNull (&Form->StatementListHead, StatementList)) {\r
+      Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
+      if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+        if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
+          Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
+          ASSERT_EFI_ERROR (Status);\r
+\r
+          if ((UefiOp == Statement->Operand) && (FormSet->DefaultVarStoreId == Statement->VarStoreId)) {\r
+            //\r
+            // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:\r
+            // 1) Same Question Type, \r
+            // 2) Same Variable Storage\r
+            // 3) Refering to the Same offset in Variable Map (NvMap). \r
+            // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question \r
+            // ID to return. \r
+            //\r
+            // One possible solution is to remove the one of the duplicated questions in this Form Set.\r
+            //\r
+            ASSERT (StatementFound == NULL);\r
+            StatementFound= Statement;\r
+\r
+            //\r
+            // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes\r
+            // with same value.\r
+            //\r
+          }\r
+        }\r
+      }\r
+\r
+      StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
+    }\r
+\r
+    FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
+  }\r
+\r
+  if (StatementFound != NULL) {\r
+    *UefiQId = StatementFound->QuestionId;\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+\r
 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL   0x1000\r
+/**\r
+  Append the newly created OpCode buffer to EFI_HII_UPDATE_DATA buffer.\r
+  Increase the Data buffer in EFI_HII_UPDATE_DATA if the EFI_HII_UPDATE_DATA \r
+  buffer's Data Buffer does not have space left for the newly created\r
+  OpCode.\r
+\r
+  @param OpCodeBuf      The newly created OpCode Buffer to be appended to \r
+                        EFI_HII_UPDATE_DATA buffer.\r
+  @param OpCodeBufSize  The size of OpCodeBuf.\r
+  @param UefiUpdateData The EFI_HII_UPDATE_DATA to be appended.\r
+\r
+  @retval EFI_SUCCESS   The OpCode buffer is appended to EFI_HII_UPDATE_DATA successfull.\r
+  @retval EFI_OUT_OF_RESOURCES There is not enough memory.\r
+**/\r
 EFI_STATUS\r
 AppendToUpdateBuffer (\r
   IN CONST  UINT8                *OpCodeBuf,\r
-  IN        UINTN                BufSize,\r
-  OUT       EFI_HII_UPDATE_DATA  *UefiData\r
+  IN        UINTN                OpCodeBufSize,\r
+  IN OUT    EFI_HII_UPDATE_DATA  *UefiUpdateData\r
   )\r
 {\r
   UINT8 * NewBuff;\r
   \r
-  if (UefiData->Offset + BufSize > UefiData->BufferSize) {\r
-    NewBuff = AllocateCopyPool (UefiData->BufferSize + LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL, UefiData->Data);\r
+  if (UefiUpdateData->Offset + OpCodeBufSize > UefiUpdateData->BufferSize) {\r
+    NewBuff = AllocateCopyPool (UefiUpdateData->BufferSize + LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL, UefiUpdateData->Data);\r
     if (NewBuff == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    UefiData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
-    FreePool (UefiData->Data);\r
-    UefiData->Data = NewBuff;\r
+    UefiUpdateData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
+    FreePool (UefiUpdateData->Data);\r
+    UefiUpdateData->Data = NewBuff;\r
   }\r
   \r
-  CopyMem (UefiData->Data + UefiData->Offset, OpCodeBuf, BufSize);\r
-  UefiData->Offset += (UINT32) BufSize;\r
+  CopyMem (UefiUpdateData->Data + UefiUpdateData->Offset, OpCodeBuf, OpCodeBufSize);\r
+  UefiUpdateData->Offset += (UINT32) OpCodeBufSize;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Assign a Question ID.\r
+\r
+  If FwQuestionId is 0, then assign a new question ID. The new question ID\r
+  is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also\r
+  incremented by 1.\r
+\r
+  If FwQuestionId is not 0, then it is used as the Framework Question ID.\r
+\r
+  @return The Framework Question ID.\r
+**/\r
+EFI_QUESTION_ID\r
+AssignQuestionId (\r
+  IN  UINT16                      FwQuestionId,\r
+  IN        FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  if (FwQuestionId == 0) {\r
+    FormSet->MaxQuestionId++;\r
+    return FormSet->MaxQuestionId;\r
+  } else {\r
+    return FwQuestionId;\r
+  }\r
+}\r
+\r
+/**\r
+  Create UEFI HII "End Of" Opcode and append it to UefiUpdateData buffer.\r
+\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 UCreateEndOfOpcode (\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT      EFI_HII_UPDATE_DATA         *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_END UOpcode;\r
@@ -56,13 +241,23 @@ UCreateEndOfOpcode (
   UOpcode.Header.OpCode = EFI_IFR_END_OP;\r
   UOpcode.Header.Length = sizeof (UOpcode);\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
+/**\r
+  Create UEFI HII Subtitle Opcode from a Framework HII Subtitle Opcode.\r
+\r
+  @param FwOpcode         The input Framework Opcode.\r
+  @param UefiUpdateData   The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateSubtitleOpCode (\r
-  IN CONST FRAMEWORK_EFI_IFR_SUBTITLE  *FwSubTitle,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN CONST FRAMEWORK_EFI_IFR_SUBTITLE  *FwOpcode,\r
+  IN OUT   EFI_HII_UPDATE_DATA         *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_SUBTITLE UOpcode;\r
@@ -72,47 +267,76 @@ F2UCreateSubtitleOpCode (
   UOpcode.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
   UOpcode.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
 \r
-  UOpcode.Statement.Prompt = FwSubTitle->SubTitle;\r
+  UOpcode.Statement.Prompt = FwOpcode->SubTitle;\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
+/**\r
+  Create UEFI HII Text Opcode from a Framework HII Text Opcode.\r
+\r
+  @param FwOpcode        The input Framework Opcode.\r
+  @param UefiUpdateData  The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateTextOpCode (\r
-  IN CONST FRAMEWORK_EFI_IFR_TEXT      *FwText,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN CONST FRAMEWORK_EFI_IFR_TEXT      *FwOpcode,\r
+  IN OUT   EFI_HII_UPDATE_DATA         *UefiUpdateData\r
   )\r
 {\r
-  EFI_IFR_TEXT UOpcode;\r
+  EFI_IFR_TEXT      UTextOpCode;\r
+  EFI_IFR_ACTION    UActionOpCode;\r
 \r
-  ZeroMem (&UOpcode, sizeof(UOpcode));\r
-  \r
-  UOpcode.Header.OpCode = EFI_IFR_TEXT_OP;\r
-  UOpcode.Header.Length = sizeof (EFI_IFR_TEXT);\r
+  if ((FwOpcode->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
+    ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
+    \r
+    UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
+    UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);\r
 \r
-  UOpcode.Statement.Help   = FwText->Help;\r
+    UTextOpCode.Statement.Help   = FwOpcode->Help;\r
 \r
-  UOpcode.Statement.Prompt = FwText->Text;\r
-  UOpcode.TextTwo          = FwText->TextTwo;\r
-  \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+    UTextOpCode.Statement.Prompt = FwOpcode->Text;\r
+    UTextOpCode.TextTwo          = FwOpcode->TextTwo;\r
+    \r
+    return AppendToUpdateBuffer ((UINT8 *) &UTextOpCode, sizeof(UTextOpCode), UefiUpdateData);\r
+  } else {\r
+    //\r
+    // Iteractive Text Opcode is EFI_IFR_ACTION\r
+    //\r
+\r
+    ZeroMem (&UActionOpCode, sizeof (UActionOpCode));\r
+\r
+    UActionOpCode.Header.OpCode = EFI_IFR_ACTION_OP;\r
+    UActionOpCode.Header.Length = sizeof (EFI_IFR_ACTION);\r
+\r
+    UActionOpCode.Question.Header.Prompt = FwOpcode->Text;\r
+    UActionOpCode.Question.Header.Help  = FwOpcode->Help;\r
+    UActionOpCode.Question.Flags      = EFI_IFR_FLAG_CALLBACK;\r
+    UActionOpCode.Question.QuestionId = FwOpcode->Key;\r
+\r
+    return AppendToUpdateBuffer ((UINT8 *) &UActionOpCode, sizeof(UActionOpCode), UefiUpdateData);\r
+    \r
+  }\r
 }\r
 \r
-/*\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            FormId;\r
-  STRING_REF        Prompt;\r
-  STRING_REF        Help;   // The string Token for the context-help\r
-  UINT8             Flags;  // This is included solely for purposes of interactive/dynamic support.\r
-  UINT16            Key;    // Value to be passed to caller to identify this particular op-code\r
-} FRAMEWORK_EFI_IFR_REF;\r
-\r
-*/\r
+/**\r
+  Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.\r
+\r
+  @param FwOpcode           The input Framework Opcode.\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
-F2UCreateGotoOpCode (\r
+F2UCreateReferenceOpCode (\r
   IN CONST FRAMEWORK_EFI_IFR_REF       *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT    EFI_HII_UPDATE_DATA        *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_REF UOpcode;\r
@@ -132,47 +356,29 @@ F2UCreateGotoOpCode (
   // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to \r
   // UEFI IFR Opcode flags. The rest flags are obsolete.\r
   //\r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
   \r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
 \r
-/*\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  STRING_REF        Option;     // The string token describing the option\r
-  UINT16            Value;      // The value associated with this option that is stored in the NVRAM if chosen\r
-  UINT8             Flags;      // For now, if non-zero, means that it is the default option, - further definition likely above\r
-  UINT16            Key;        // Value to be passed to caller to identify this particular op-code\r
-} FRAMEWORK_EFI_IFR_ONE_OF_OPTION;\r
-\r
-typedef union {\r
-  UINT8           u8;\r
-  UINT16          u16;\r
-  UINT32          u32;\r
-  UINT64          u64;\r
-  BOOLEAN         b;\r
-  EFI_HII_TIME    time;\r
-  EFI_HII_DATE    date;\r
-  EFI_STRING_ID   string;\r
-} EFI_IFR_TYPE_VALUE;\r
-\r
-typedef struct _EFI_IFR_ONE_OF_OPTION {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_STRING_ID            Option;\r
-  UINT8                    Flags;\r
-  UINT8                    Type;\r
-  EFI_IFR_TYPE_VALUE       Value;\r
-} EFI_IFR_ONE_OF_OPTION;\r
-\r
-*/\r
+/**\r
+  Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.\r
+\r
+  @param FwOpcode        The input Framework Opcode.\r
+  @param Width           The size of the One Of Option. 1 bytes or 2 bytes.\r
+  @param UefiUpdateData  The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateOneOfOptionOpCode (\r
   IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION    *FwOpcode,\r
   IN       UINTN                              Width,\r
-  OUT      EFI_HII_UPDATE_DATA                *UefiData\r
+  IN OUT   EFI_HII_UPDATE_DATA                *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_ONE_OF_OPTION UOpcode;\r
@@ -186,13 +392,12 @@ F2UCreateOneOfOptionOpCode (
   CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);\r
 \r
   //\r
-  \r
-  // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT                    0x01\r
-  // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING        0x02\r
-  // #define EFI_IFR_OPTION_DEFAULT 0x10\r
-  // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
+  // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT           0x01\r
+  // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING     0x02\r
+  // #define EFI_IFR_OPTION_DEFAULT                   0x10\r
+  // #define EFI_IFR_OPTION_DEFAULT_MFG               0x20\r
   //\r
-  UOpcode.Flags |= (UINT8) ((FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
+  UOpcode.Flags = (UINT8) (UOpcode.Flags  | (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
 \r
   switch (Width) {\r
     case 1:\r
@@ -208,77 +413,75 @@ F2UCreateOneOfOptionOpCode (
       return EFI_UNSUPPORTED;\r
   }\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
+/**\r
+  Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key\r
+  to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback\r
+  function. The opcode is appened to UefiUpdateData.\r
+\r
+  @param    QuestionId      The UEFI Question ID.\r
+  @param    OptionValue     The value of the "One Of Option".\r
+  @param    KeyValue        The Framework "One Of Option" callback key.\r
+  @param    UefiDat         The UEFI Update Data buffer.\r
 \r
-/*\r
-typedef struct _EFI_IFR_QUESTION_HEADER {\r
-  EFI_IFR_STATEMENT_HEADER Header;\r
-  EFI_QUESTION_ID          QuestionId;\r
-  EFI_VARSTORE_ID          VarStoreId;\r
-  union {\r
-    EFI_STRING_ID          VarName;\r
-    UINT16                 VarOffset;\r
-  }                        VarStoreInfo;\r
-  UINT8                    Flags;\r
-} EFI_IFR_QUESTION_HEADER;\r
-\r
-typedef union {\r
-  struct {\r
-    UINT8 MinValue;\r
-    UINT8 MaxValue;\r
-    UINT8 Step;\r
-  } u8;\r
-  struct {\r
-    UINT16 MinValue;\r
-    UINT16 MaxValue;\r
-    UINT16 Step;\r
-  } u16;\r
-  struct {\r
-    UINT32 MinValue;\r
-    UINT32 MaxValue;\r
-    UINT32 Step;\r
-  } u32;\r
-  struct {\r
-    UINT64 MinValue;\r
-    UINT64 MaxValue;\r
-    UINT64 Step;\r
-  } u64;\r
-} MINMAXSTEP_DATA;\r
-\r
-typedef struct _EFI_IFR_ONE_OF {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_IFR_QUESTION_HEADER  Question;\r
-  UINT8                    Flags;\r
-  MINMAXSTEP_DATA          data;\r
-} EFI_IFR_ONE_OF;\r
-\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
-  UINT8             Width;      // The Size of the Data being saved\r
-  STRING_REF        Prompt;     // The String Token for the Prompt\r
-  STRING_REF        Help;       // The string Token for the context-help\r
-} FRAMEWORK_EFI_IFR_ONE_OF;\r
-\r
-\r
-*/\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+**/\r
 \r
+EFI_STATUS\r
+CreateGuidOptionKeyOpCode (\r
+  IN EFI_QUESTION_ID                   QuestionId,\r
+  IN UINT16                            OptionValue,\r
+  IN EFI_QUESTION_ID                   KeyValue,\r
+  IN OUT    EFI_HII_UPDATE_DATA        *UefiUpdateData\r
+  )\r
+{\r
+  EFI_IFR_GUID_OPTIONKEY              UOpcode;\r
+\r
+  CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY));\r
+\r
+  UOpcode.QuestionId  = QuestionId;\r
+  CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue)); \r
+  UOpcode.KeyValue = KeyValue;\r
+  \r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
+}\r
+\r
+/**\r
+  Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.\r
+\r
+  @param ThunkContext The HII Thunk Context.\r
+  @param FwOpcode     The input Framework Opcode.\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+  @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
+                      the "One Of Option".\r
+  @param OpcodeCount  The number of Opcode for the complete Framework "One Of" Opcode.\r
+                      \r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateOneOfOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_IFR_ONE_OF    *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData,\r
-  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode\r
+  IN OUT   EFI_HII_UPDATE_DATA         *UefiUpdateData,\r
+  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
+  OUT      UINTN                       *OpcodeCount\r
   )\r
 {\r
-  EFI_STATUS     Status;\r
-  EFI_IFR_ONE_OF UOpcode;\r
-  FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
-  FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
-  BOOLEAN        HasQuestionId;\r
+  EFI_STATUS                          Status;\r
+  EFI_IFR_ONE_OF                      UOpcode;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER         *FwOpHeader;\r
+  FRAMEWORK_EFI_IFR_ONE_OF_OPTION     *FwOneOfOp;\r
+\r
+  ASSERT (NextFwOpcode != NULL);\r
+  ASSERT (OpcodeCount != NULL);\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
+  *OpcodeCount = 0;\r
 \r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
@@ -286,88 +489,113 @@ F2UCreateOneOfOpCode (
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
\r
-  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
+  UOpcode.Question.VarStoreId  = ThunkContext->FormSet->DefaultVarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
+  \r
   //\r
   // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
   //\r
-  HasQuestionId = FALSE;\r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
     ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
     \r
     FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
-    if (((FwOneOfOp->Key & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) & !HasQuestionId) {\r
-      HasQuestionId = TRUE;\r
-      UOpcode.Question.QuestionId = FwOneOfOp->Key;\r
+    if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
+      \r
+      if (UOpcode.Question.QuestionId == 0) {\r
+        Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+        if (EFI_ERROR (Status)) {\r
+          UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
+        }\r
+      }\r
+\r
+    }\r
+\r
+    if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
     }\r
 \r
     FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
   }\r
 \r
+\r
+  if (UOpcode.Question.QuestionId == 0) {\r
+    //\r
+    // Assign QuestionId if still not assigned.\r
+    //\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  }\r
+  \r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof (UOpcode), UefiUpdateData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *OpcodeCount += 1;\r
+\r
   //\r
   // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
   //\r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
-    Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData);\r
+\r
+    FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
+      \r
+    Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiUpdateData);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiUpdateData);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *OpcodeCount += 1;\r
   }\r
 \r
-  Status = UCreateEndOfOpcode (UefiData);\r
+  Status = UCreateEndOfOpcode (UefiUpdateData);\r
   if (!EFI_ERROR (Status)) {\r
     *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *OpcodeCount += 1;\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-/*\r
-typedef struct _EFI_IFR_QUESTION_HEADER {\r
-  EFI_IFR_STATEMENT_HEADER Header;\r
-  EFI_QUESTION_ID          QuestionId;\r
-  EFI_VARSTORE_ID          VarStoreId;\r
-  union {\r
-    EFI_STRING_ID          VarName;\r
-    UINT16                 VarOffset;\r
-  }                        VarStoreInfo;\r
-  UINT8                    Flags;\r
-} EFI_IFR_QUESTION_HEADER;\r
-\r
-typedef struct _EFI_IFR_ORDERED_LIST {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_IFR_QUESTION_HEADER  Question;\r
-  UINT8                    MaxContainers;\r
-  UINT8                    Flags;\r
-} EFI_IFR_ORDERED_LIST;\r
-\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            QuestionId; // The offset in NV for storage of the data\r
-  UINT8             MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)\r
-  STRING_REF        Prompt;     // The string token for the prompt\r
-  STRING_REF        Help;       // The string token for the context-help\r
-} FRAMEWORK_EFI_IFR_ORDERED_LIST;\r
-\r
-*/\r
+/**\r
+  Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.\r
+\r
+  @param ThunkContext The HII Thunk Context.\r
+  @param FwOpcode     The input Framework Opcode.\r
+  @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
+  @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
+                      the "Ordered List".\r
+  @param OpcodeCount  The number of Opcode for the complete Framework "Ordered List" Opcode.\r
+                      \r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateOrderedListOpCode (\r
+  IN       HII_THUNK_CONTEXT              *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData,\r
-  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode\r
+  IN OUT    EFI_HII_UPDATE_DATA           *UefiUpdateData,\r
+  OUT      FRAMEWORK_EFI_IFR_OP_HEADER    **NextFwOpcode,\r
+  OUT      UINTN                          *OpcodeCount\r
   )\r
 {\r
   EFI_IFR_ORDERED_LIST              UOpcode;\r
   EFI_STATUS                        Status;\r
   FRAMEWORK_EFI_IFR_OP_HEADER       *FwOpHeader;\r
+  FRAMEWORK_EFI_IFR_ONE_OF_OPTION     *FwOneOfOp;\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
+  *OpcodeCount = 0;\r
 \r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
@@ -375,70 +603,92 @@ F2UCreateOrderedListOpCode (
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
+  UOpcode.Question.VarStoreId  = ThunkContext->FormSet->DefaultVarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
   UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
+\r
+  //\r
+  // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
+  //\r
+  FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
+  while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
+    ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
+    \r
+    FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
+    if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
+      \r
+      if (UOpcode.Question.QuestionId == 0) {\r
+        Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+        if (EFI_ERROR (Status)) {\r
+          UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
+        }\r
+\r
+      }\r
+    }\r
+\r
+    if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
+    }\r
+\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+  }\r
+\r
+  if (UOpcode.Question.QuestionId == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  }\r
  \r
-  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  *OpcodeCount += 1;\r
 \r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
-    Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->MaxEntries, UefiData);\r
+    //\r
+    // Each entry of Order List in Framework HII is always 1 byte in size\r
+    //\r
+    Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1, UefiUpdateData);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *OpcodeCount += 1;\r
   }\r
 \r
-  Status = UCreateEndOfOpcode (UefiData);\r
+  Status = UCreateEndOfOpcode (UefiUpdateData);\r
   if (!EFI_ERROR (Status)) {\r
     *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *OpcodeCount += 1;\r
   }\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return Status;\r
 }\r
 \r
-/*\r
-typedef struct _EFI_IFR_QUESTION_HEADER {\r
-  EFI_IFR_STATEMENT_HEADER Header;\r
-  EFI_QUESTION_ID          QuestionId;\r
-  EFI_VARSTORE_ID          VarStoreId;\r
-  union {\r
-    EFI_STRING_ID          VarName;\r
-    UINT16                 VarOffset;\r
-  }                        VarStoreInfo;\r
-  UINT8                    Flags;\r
-} EFI_IFR_QUESTION_HEADER;\r
-*/\r
-\r
-/*\r
-typedef struct _EFI_IFR_CHECKBOX {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_IFR_QUESTION_HEADER  Question;\r
-  UINT8                    Flags;\r
-} EFI_IFR_CHECKBOX;\r
-*/\r
-\r
-/*\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
-  UINT8             Width;      // The Size of the Data being saved\r
-  STRING_REF        Prompt;     // The String Token for the Prompt\r
-  STRING_REF        Help;       // The string Token for the context-help\r
-  UINT8             Flags;      // For now, if non-zero, means that it is the default option, - further definition likely\r
-  UINT16            Key;        // Value to be passed to caller to identify this particular op-code\r
-} FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;\r
-*/\r
+/**\r
+  Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.\r
 \r
+  @param ThunkContext    The HII Thunk Context.\r
+  @param FwOpcode        The input Framework Opcode.\r
+  @param UefiUpdateData  The newly created UEFI HII opcode is appended to UefiUpdateData.\r
 \r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateCheckBoxOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_IFR_CHECKBOX  *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT   EFI_HII_UPDATE_DATA         *UefiUpdateData\r
   )\r
 {\r
+  EFI_STATUS       Status;\r
   EFI_IFR_CHECKBOX UOpcode;\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
@@ -449,94 +699,58 @@ F2UCreateCheckBoxOpCode (
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
-  UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
-  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
+  if (FwOpcode->Key == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
+      //\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
 \r
   //\r
-  // We only  map 2 flags:\r
+  // We map 2 flags:\r
   //      FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE, \r
   //      FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
   // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
   //\r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+\r
+\r
+  UOpcode.Question.VarStoreId    = ThunkContext->FormSet->DefaultVarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
   //\r
-  // We also map 2 flags:\r
-  //      FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE\r
-  //      FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
+  // We also map these 2 flags:\r
+  //      FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+  //      FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,\r
   // to UEFI IFR CheckBox Opcode default flags.\r
   //\r
-  UOpcode.Flags           = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
+  UOpcode.Flags           = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
 \r
-/*\r
-typedef struct _EFI_IFR_QUESTION_HEADER {\r
-  EFI_IFR_STATEMENT_HEADER Header;\r
-  EFI_QUESTION_ID          QuestionId;\r
-  EFI_VARSTORE_ID          VarStoreId;\r
-  union {\r
-    EFI_STRING_ID          VarName;\r
-    UINT16                 VarOffset;\r
-  }                        VarStoreInfo;\r
-  UINT8                    Flags;\r
-} EFI_IFR_QUESTION_HEADER;\r
-\r
-typedef union {\r
-  struct {\r
-    UINT8 MinValue;\r
-    UINT8 MaxValue;\r
-    UINT8 Step;\r
-  } u8;\r
-  struct {\r
-    UINT16 MinValue;\r
-    UINT16 MaxValue;\r
-    UINT16 Step;\r
-  } u16;\r
-  struct {\r
-    UINT32 MinValue;\r
-    UINT32 MaxValue;\r
-    UINT32 Step;\r
-  } u32;\r
-  struct {\r
-    UINT64 MinValue;\r
-    UINT64 MaxValue;\r
-    UINT64 Step;\r
-  } u64;\r
-} MINMAXSTEP_DATA;\r
-\r
-typedef struct _EFI_IFR_NUMERIC {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_IFR_QUESTION_HEADER  Question;\r
-  UINT8                    Flags;\r
-  MINMAXSTEP_DATA          data;\r
-} EFI_IFR_NUMERIC;\r
-\r
-\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
-  UINT8             Width;      // The Size of the Data being saved\r
-  STRING_REF        Prompt;     // The String Token for the Prompt\r
-  STRING_REF        Help;       // The string Token for the context-help\r
-  UINT8             Flags;      // This is included solely for purposes of interactive/dynamic support.\r
-  UINT16            Key;        // Value to be passed to caller to identify this particular op-code\r
-  UINT16            Minimum;\r
-  UINT16            Maximum;\r
-  UINT16            Step;       // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for\r
-  UINT16            Default;\r
-} FRAMEWORK_EFI_IFR_NUMERIC;\r
-\r
-*/\r
+/**\r
+  Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.\r
 \r
+  @param ThunkContext The HII Thunk Context.\r
+  @param FwOpcode     The input Framework Opcode.\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
 \r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateNumericOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_IFR_NUMERIC   *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT    EFI_HII_UPDATE_DATA        *UefiUpdateData\r
   )\r
 {\r
   EFI_STATUS      Status;\r
@@ -545,24 +759,33 @@ F2UCreateNumericOpCode (
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
 \r
+  if (FwOpcode->Key == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
+      //\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
+\r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
   //\r
   // We need to create a nested default value for the UEFI Numeric Opcode.\r
   // So turn on the scope.\r
   //\r
-  if (FwOpcode->Default != 0) {\r
-    UOpcode.Header.Scope = 1;\r
-  }\r
+  UOpcode.Header.Scope = 1;\r
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
-  UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
+  UOpcode.Question.VarStoreId    = ThunkContext->FormSet->DefaultVarStoreId;\r
   UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
   //\r
   // Framework Numeric values are all in UINT16 and displayed as decimal.\r
@@ -574,12 +797,12 @@ F2UCreateNumericOpCode (
   switch (FwOpcode->Width) {\r
     case 1: \r
     {\r
-      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
+      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
       break;\r
     } \r
     case 2: \r
     {\r
-      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
+      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
       break;\r
     }\r
     default: \r
@@ -589,7 +812,7 @@ F2UCreateNumericOpCode (
     }\r
   }\r
   \r
-  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -597,86 +820,65 @@ F2UCreateNumericOpCode (
   //\r
   // We need to create a default value.\r
   //\r
-  if (FwOpcode->Default != 0) {\r
-    ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
-    UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
-    UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
+  ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
+  UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
+  UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
 \r
-    UOpcodeDefault.DefaultId = 0;\r
+  UOpcodeDefault.DefaultId = 0;\r
 \r
-    switch (FwOpcode->Width) {\r
-      case 1: \r
-      {\r
-        UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
-        break;\r
-      } \r
-      case 2: \r
-      {\r
-        UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
-        break;\r
-      }\r
+  switch (FwOpcode->Width) {\r
+    case 1: \r
+    {\r
+      UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+      break;\r
+    } \r
+    case 2: \r
+    {\r
+      UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+      break;\r
     }\r
+  }\r
 \r
-    CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
+  CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
 \r
-    Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiData);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    Status = UCreateEndOfOpcode (UefiData);\r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiUpdateData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
+  Status = UCreateEndOfOpcode (UefiUpdateData);\r
 \r
   return Status;\r
 }\r
 \r
 \r
-/*\r
-\r
-typedef struct _EFI_IFR_QUESTION_HEADER {\r
-  EFI_IFR_STATEMENT_HEADER Header;\r
-  EFI_QUESTION_ID          QuestionId;\r
-  EFI_VARSTORE_ID          VarStoreId;\r
-  union {\r
-    EFI_STRING_ID          VarName;\r
-    UINT16                 VarOffset;\r
-  }                        VarStoreInfo;\r
-  UINT8                    Flags;\r
-} EFI_IFR_QUESTION_HEADER;\r
-\r
-typedef struct _EFI_IFR_STRING {\r
-  EFI_IFR_OP_HEADER        Header;\r
-  EFI_IFR_QUESTION_HEADER  Question;\r
-  UINT8                    MinSize;\r
-  UINT8                    MaxSize;\r
-  UINT8                    Flags;\r
-} EFI_IFR_STRING;\r
+/**\r
+  Create UEFI HII String Opcode from a Framework HII String Opcode.\r
 \r
+  @param ThunkContext The HII Thunk Context.\r
+  @param FwOpcode     The input Framework Opcode.\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
 \r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  UINT16            QuestionId;   // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
-  UINT8             Width;        // The Size of the Data being saved -- BUGBUG -- remove someday\r
-  STRING_REF        Prompt;       // The String Token for the Prompt\r
-  STRING_REF        Help;         // The string Token for the context-help\r
-  UINT8             Flags;        // This is included solely for purposes of interactive/dynamic support.\r
-  UINT16            Key;          // Value to be passed to caller to identify this particular op-code\r
-  UINT8             MinSize;      // Minimum allowable sized password\r
-  UINT8             MaxSize;      // Maximum allowable sized password\r
-} FRAMEWORK_EFI_IFR_STRING;\r
-\r
-\r
-*/\r
-\r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateStringOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_IFR_STRING    *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT    EFI_HII_UPDATE_DATA        *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_STRING UOpcode;\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
 \r
+  if (FwOpcode->Key == 0) {\r
+    FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
+\r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
 \r
@@ -684,41 +886,32 @@ F2UCreateStringOpCode (
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
   UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
-  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.VarStoreId    = ThunkContext->FormSet->DefaultVarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
   UOpcode.MinSize = FwOpcode->MinSize;\r
   UOpcode.MaxSize = FwOpcode->MaxSize;\r
   UOpcode.Flags   = EFI_IFR_STRING_MULTI_LINE;\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
-/*\r
-typedef struct _EFI_IFR_GUID_BANNER {\r
-  EFI_IFR_OP_HEADER   Header;\r
-  EFI_GUID            Guid;\r
-  UINT8               ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER\r
-  EFI_STRING_ID       Title;        // The string token for the banner title\r
-  UINT16              LineNumber;   // 1-based line number\r
-  UINT8               Alignment;    // left, center, or right-aligned\r
-} EFI_IFR_GUID_BANNER;\r
-\r
-typedef struct {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
-  STRING_REF        Title;        // The string token for the banner title\r
-  UINT16            LineNumber;   // 1-based line number\r
-  UINT8             Alignment;    // left, center, or right-aligned\r
-} FRAMEWORK_EFI_IFR_BANNER;\r
-\r
-*/\r
+/**\r
+  Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.\r
+\r
+  @param FwOpcode     The input Framework Opcode.\r
+  @param UefiUpdateData     The newly created UEFI HII opcode is appended to UefiUpdateData.\r
 \r
+  @retval EFI_SUCCESS           The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCE   There is not enough resource.\r
+  \r
+**/\r
 EFI_STATUS\r
 F2UCreateBannerOpCode (\r
   IN CONST FRAMEWORK_EFI_IFR_BANNER    *FwOpcode,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  IN OUT    EFI_HII_UPDATE_DATA        *UefiUpdateData\r
   )\r
 {\r
   EFI_IFR_GUID_BANNER UOpcode;\r
@@ -734,111 +927,128 @@ F2UCreateBannerOpCode (
   UOpcode.LineNumber     = FwOpcode->LineNumber;\r
   UOpcode.Alignment      = FwOpcode->Alignment;\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
 }\r
 \r
+/**\r
+  Create a EFI_HII_UPDATE_DATA structure used to call IfrLibUpdateForm.\r
 \r
+  @param ThunkContext   The HII Thunk Context.\r
+  @param FwUpdateData   The Framework Update Data.\r
+  @param UefiUpdateData The UEFI Update Data.\r
 \r
+  @retval EFI_SUCCESS       The UEFI Update Data is created successfully.\r
+  @retval EFI_UNSUPPORTED   There is unsupported opcode in FwUpdateData.\r
+  @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
+**/\r
 EFI_STATUS\r
-ThunkFrameworkUpdateDataToUefiUpdateData (\r
-  IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA    *Data,\r
-  IN       BOOLEAN                          AddData,\r
-  OUT      EFI_HII_UPDATE_DATA              **UefiData\r
+FwUpdateDataToUefiUpdateData (\r
+  IN       HII_THUNK_CONTEXT                *ThunkContext,\r
+  IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA    *FwUpdateData,\r
+  OUT      EFI_HII_UPDATE_DATA              **UefiUpdateData\r
   )\r
 {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER          *FrameworkOpcodeBuffer;\r
-  FRAMEWORK_EFI_IFR_OP_HEADER          *NextFrameworkOpcodeBuffer;\r
-  EFI_HII_UPDATE_DATA                  *UefiUpdateDataBuffer;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER          *FwOpCode;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER          *NextFwOpCode;\r
+  EFI_HII_UPDATE_DATA                  *UefiOpCode;\r
   UINTN                                Index;\r
   EFI_STATUS                           Status;\r
-  static UINTN                         mOneOfOptionWidth;\r
+  UINTN                                DataCount;\r
 \r
-  mOneOfOptionWidth = 0;\r
-  \r
-\r
-  UefiUpdateDataBuffer = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
-  if (UefiUpdateDataBuffer == NULL) {\r
+  UefiOpCode = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
+  if (UefiOpCode == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   \r
-  UefiUpdateDataBuffer->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
-  if (UefiUpdateDataBuffer->Data == NULL) {\r
+  UefiOpCode->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
+  if (UefiOpCode->Data == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  UefiUpdateDataBuffer->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
-  UefiUpdateDataBuffer->Offset = 0;\r
+  UefiOpCode->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
+  UefiOpCode->Offset = 0;\r
 \r
-  FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;\r
+  FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &FwUpdateData->Data;\r
 \r
-  for (Index = 0; Index < Data->DataCount; Index++) {\r
-    switch (FrameworkOpcodeBuffer->OpCode) {\r
+  for (Index = 0; Index < FwUpdateData->DataCount; Index += DataCount) {\r
+    switch (FwOpCode->OpCode) {\r
       case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
-        Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);\r
+        Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE  *) FwOpCode, UefiOpCode);\r
+        DataCount = 1;\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_TEXT_OP:\r
-        Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_REF_OP:\r
-        Status = F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateReferenceOpCode ((FRAMEWORK_EFI_IFR_REF *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
-        Status = F2UCreateOneOfOpCode ((FRAMEWORK_EFI_IFR_ONE_OF *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer, &NextFrameworkOpcodeBuffer);\r
+        Status = F2UCreateOneOfOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
         if (!EFI_ERROR (Status)) {\r
-          FrameworkOpcodeBuffer = NextFrameworkOpcodeBuffer;\r
+          FwOpCode = NextFwOpCode;\r
           //\r
-          // F2UCreateOneOfOpCode has updated FrameworkOpcodeBuffer to point to the next opcode.\r
+          // FwOpCode is already updated to point to the next opcode.\r
           //\r
           continue;\r
         }\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
-        Status = F2UCreateOrderedListOpCode ((FRAMEWORK_EFI_IFR_ORDERED_LIST *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer, &NextFrameworkOpcodeBuffer);\r
+        Status = F2UCreateOrderedListOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
         if (!EFI_ERROR (Status)) {\r
-          FrameworkOpcodeBuffer = NextFrameworkOpcodeBuffer;\r
+          FwOpCode = NextFwOpCode;\r
           //\r
-          // F2UCreateOrderedListOpCode has updated FrameworkOpcodeBuffer to point to the next opcode.\r
+          // FwOpCode is already updated to point to the next opcode.\r
           //\r
           continue;\r
         }\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
-        Status = F2UCreateCheckBoxOpCode ((FRAMEWORK_EFI_IFR_CHECKBOX *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateCheckBoxOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_STRING_OP:\r
-        Status = F2UCreateStringOpCode ((FRAMEWORK_EFI_IFR_STRING *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateStringOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_BANNER_OP:\r
-        Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:\r
-        Status = UCreateEndOfOpcode (UefiUpdateDataBuffer);\r
-        mOneOfOptionWidth = 0;\r
+        Status = UCreateEndOfOpcode (UefiOpCode);\r
+        DataCount = 1;\r
         break;\r
-        \r
+\r
+      case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
+        Status = F2UCreateNumericOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode, UefiOpCode);\r
+        DataCount = 1;\r
+        break;\r
+\r
       default:\r
         ASSERT (FALSE);\r
         return EFI_UNSUPPORTED;\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
-      FreePool (UefiUpdateDataBuffer->Data);\r
-      FreePool (UefiUpdateDataBuffer);\r
+      FreePool (UefiOpCode->Data);\r
+      FreePool (UefiOpCode);\r
       return Status;\r
     }\r
 \r
-    FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FrameworkOpcodeBuffer + FrameworkOpcodeBuffer->Length);\r
+    FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
   }\r
 \r
-  *UefiData = UefiUpdateDataBuffer;\r
+  *UefiUpdateData = UefiOpCode;\r
   \r
   return EFI_SUCCESS;\r
 }\r