]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c
Unix version of EFI emulator
[mirror_edk2.git] / EdkUnixPkg / Dxe / PlatformBds / Generic / BootMaint / UpdatePage.c
diff --git a/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c b/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c
new file mode 100644 (file)
index 0000000..9c72f23
--- /dev/null
@@ -0,0 +1,1275 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  UpdatePage.c\r
+    \r
+AgBStract:\r
+\r
+  Dynamically Update the pages\r
+\r
+--*/\r
+\r
+#include "Generic/Bds.h"\r
+#include "BootMaint.h"\r
+#include "BdsPlatform.h"\r
+\r
+EFI_GUID gTerminalDriverGuid = {\r
+  0x10634d8e, 0x1c05, 0x46cb, 0xbb, 0xc, 0x5a, 0xfd, 0xc8, 0x29, 0xa8, 0xc8\r
+};\r
+\r
+VOID\r
+RefreshUpdateData (\r
+  IN BOOLEAN                      FormSetUpdate,\r
+  IN EFI_PHYSICAL_ADDRESS         FormCallbackHandle,\r
+  IN BOOLEAN                      FormUpdate,\r
+  IN STRING_REF                   FormTitle,\r
+  IN UINT16                       DataCount\r
+  )\r
+/*++\r
+Routine Description:\r
+  Refresh the global UpdateData structure.\r
+\r
+Arguments:\r
+  FormSetUpdate      - If TRUE, next variable is significant\r
+  FormCallbackHandle - If not 0, will update FormSet with this info\r
+  FormUpdate         - If TRUE, next variable is significant\r
+  FormTitle          - If not 0, will update Form with this info\r
+  DataCount          - The number of Data entries in this structure\r
+\r
+Returns:\r
+  None.\r
+--*/\r
+{\r
+  UpdateData->FormSetUpdate = FormSetUpdate;\r
+  if (FormSetUpdate) {\r
+    ASSERT (0 != FormCallbackHandle);\r
+    UpdateData->FormCallbackHandle = FormCallbackHandle;\r
+  }\r
+\r
+  UpdateData->FormUpdate  = FALSE;\r
+  UpdateData->FormTitle   = FormTitle;\r
+  UpdateData->DataCount   = DataCount;\r
+}\r
+\r
+VOID\r
+UpdatePageStart (\r
+  IN BMM_CALLBACK_DATA                *CallbackData,\r
+  IN OUT UINT8                        **CurrentLocation\r
+  )\r
+{\r
+  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->BmmCallbackHandle, FALSE, 0, 0);\r
+\r
+  if (!(CallbackData->BmmAskSaveOrNot)) {\r
+    //\r
+    // Add a "Go back to main page" tag in front of the form when there are no\r
+    // "Apply changes" and "Discard changes" tags in the end of the form.\r
+    //\r
+    CreateGotoOpCode (\r
+      FORM_MAIN_ID,\r
+      STRING_TOKEN (STR_FORM_GOTO_MAIN),\r
+      STRING_TOKEN (STR_FORM_GOTO_MAIN),\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      FORM_MAIN_ID,\r
+      *CurrentLocation\r
+      );\r
+\r
+    UpdateData->DataCount++;\r
+\r
+    *CurrentLocation = *CurrentLocation + ((EFI_IFR_OP_HEADER *) (*CurrentLocation))->Length;\r
+  }\r
+\r
+}\r
+\r
+VOID\r
+UpdatePageEnd (\r
+  IN BMM_CALLBACK_DATA                *CallbackData,\r
+  IN UINT8                            *CurrentLocation\r
+  )\r
+{\r
+  //\r
+  // Create the "Apply changes" and "Discard changes" tags.\r
+  //\r
+  if (CallbackData->BmmAskSaveOrNot) {\r
+    CreateGotoOpCode (\r
+      FORM_MAIN_ID,\r
+      STRING_TOKEN (STR_SAVE_AND_EXIT),\r
+      STRING_TOKEN (STR_NULL_STRING),\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      KEY_VALUE_SAVE_AND_EXIT,\r
+      CurrentLocation\r
+      );\r
+\r
+    UpdateData->DataCount++;\r
+\r
+    CurrentLocation = CurrentLocation + ((EFI_IFR_OP_HEADER *) CurrentLocation)->Length;\r
+\r
+    CreateGotoOpCode (\r
+      FORM_MAIN_ID,\r
+      STRING_TOKEN (STR_NO_SAVE_AND_EXIT),\r
+      STRING_TOKEN (STR_NULL_STRING),\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      KEY_VALUE_NO_SAVE_AND_EXIT,\r
+      CurrentLocation\r
+      );\r
+\r
+    UpdateData->DataCount++;\r
+  }\r
+  //\r
+  // Ensure user can return to the main page.\r
+  //\r
+  if (0 == UpdateData->DataCount) {\r
+    CreateGotoOpCode (\r
+      FORM_MAIN_ID,\r
+      STRING_TOKEN (STR_NO_SAVE_AND_EXIT),\r
+      STRING_TOKEN (STR_NULL_STRING),\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      KEY_VALUE_NO_SAVE_AND_EXIT,\r
+      CurrentLocation\r
+      );\r
+\r
+    UpdateData->DataCount++;\r
+  }\r
+\r
+  CallbackData->Hii->UpdateForm (\r
+                      CallbackData->Hii,\r
+                      CallbackData->BmmHiiHandle,\r
+                      CallbackData->BmmCurrentPageId,\r
+                      TRUE,\r
+                      UpdateData\r
+                      );\r
+}\r
+\r
+VOID\r
+CleanUpPage (\r
+  IN EFI_FORM_LABEL                   LabelId,\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);\r
+\r
+  //\r
+  // Remove all op-codes from dynamic page\r
+  //\r
+  CallbackData->Hii->UpdateForm (\r
+                      CallbackData->Hii,\r
+                      CallbackData->BmmHiiHandle,\r
+                      LabelId,\r
+                      FALSE,\r
+                      UpdateData\r
+                      );\r
+}\r
+\r
+EFI_STATUS\r
+BootThisFile (\r
+  IN BM_FILE_CONTEXT                   *FileContext\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  UINTN             ExitDataSize;\r
+  CHAR16            *ExitData;\r
+  BDS_COMMON_OPTION *Option;\r
+\r
+  Status                  = gBS->AllocatePool (EfiBootServicesData, sizeof (BDS_COMMON_OPTION), &Option);\r
+  Option->Description     = FileContext->FileName;\r
+  Option->DevicePath      = FileContext->DevicePath;\r
+  Option->LoadOptionsSize = 0;\r
+  Option->LoadOptions     = NULL;\r
+\r
+  //\r
+  // Since current no boot from removable media directly is allowed */\r
+  //\r
+  gST->ConOut->ClearScreen (gST->ConOut);\r
+\r
+  ExitDataSize  = 0;\r
+\r
+  Status        = BdsLibBootViaBootOption (Option, Option->DevicePath, &ExitDataSize, &ExitData);\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+VOID\r
+UpdateConCOMPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY *NewMenuEntry;\r
+  UINT16        Index;\r
+  UINT8         *Location;\r
+  EFI_STATUS    Status;\r
+  VOID         *Interface;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = FALSE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  Status = EfiLibLocateProtocol (&gTerminalDriverGuid, &Interface);\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
+      NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
\r
+      CreateGotoOpCode (\r
+        FORM_CON_COM_SETUP_ID,\r
+        NewMenuEntry->DisplayStringToken,\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+        (UINT16) (TERMINAL_OPTION_OFFSET + Index),\r
+        Location\r
+        );\r
+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+      UpdateData->DataCount++;\r
+    }\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateBootDelPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_LOAD_CONTEXT *NewLoadContext;\r
+  UINT16          Index;\r
+  UINT8           *Location;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);\r
+\r
+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
+    NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+    NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+    if (NewLoadContext->IsLegacy) {\r
+      continue;\r
+    }\r
+\r
+    NewLoadContext->Deleted = FALSE;\r
+    CallbackData->BmmFakeNvData->BootOptionDel[Index] = 0x00;\r
+\r
+    CreateCheckBoxOpCode (\r
+      (UINT16) (BOOT_OPTION_DEL_QUESTION_ID + Index),\r
+      (UINT8) 1,\r
+      NewMenuEntry->DisplayStringToken,\r
+      NewMenuEntry->HelpStringToken,\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      (UINT16) BOOT_OPTION_DEL_QUESTION_ID,\r
+      Location\r
+      );\r
+\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    UpdateData->DataCount++;\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateDrvAddHandlePage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY *NewMenuEntry;\r
+  UINT16        Index;\r
+  UINT8         *Location;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = FALSE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {\r
+    NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
+\r
+    CreateGotoOpCode (\r
+      FORM_DRV_ADD_HANDLE_DESC_ID,\r
+      NewMenuEntry->DisplayStringToken,\r
+      STRING_TOKEN (STR_NULL_STRING),\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      (UINT16) (HANDLE_OPTION_OFFSET + Index),\r
+      Location\r
+      );\r
+\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    UpdateData->DataCount++;\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateDrvDelPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_LOAD_CONTEXT *NewLoadContext;\r
+  UINT16          Index;\r
+  UINT8           *Location;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &DriverOptionMenu);\r
+\r
+  for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
+    NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
+\r
+    NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+    NewLoadContext->Deleted = FALSE;\r
+    CallbackData->BmmFakeNvData->DriverOptionDel[Index] = 0x00;\r
+\r
+    CreateCheckBoxOpCode (\r
+      (UINT16) (DRIVER_OPTION_DEL_QUESTION_ID + Index),\r
+      (UINT8) 1,\r
+      NewMenuEntry->DisplayStringToken,\r
+      NewMenuEntry->HelpStringToken,\r
+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+      (UINT16) DRIVER_OPTION_DEL_QUESTION_ID,\r
+      Location\r
+      );\r
+\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    UpdateData->DataCount++;\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateDriverAddHandleDescPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY *NewMenuEntry;\r
+  UINT8         *Location;\r
+\r
+  Location  = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmFakeNvData->DriverAddActive          = 0x01;\r
+  CallbackData->BmmFakeNvData->DriverAddForceReconnect  = 0x00;\r
+  CallbackData->BmmAskSaveOrNot                         = TRUE;\r
+  NewMenuEntry = CallbackData->MenuEntry;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  UpdateData->DataCount += (UINT16) 4;\r
+\r
+  CreateSubTitleOpCode (\r
+    NewMenuEntry->DisplayStringToken,\r
+    Location\r
+    );\r
+\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+\r
+  CreateStringOpCode (\r
+    DRV_ADD_HANDLE_DESC_QUESTION_ID,\r
+    (UINT8) 150,\r
+    STRING_TOKEN (STR_LOAD_OPTION_DESC),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    6,\r
+    75,\r
+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+    KEY_VALUE_DRIVER_ADD_DESC_DATA,\r
+    Location\r
+    );\r
+\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+\r
+  CreateCheckBoxOpCode (\r
+    DRV_ADD_RECON_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),\r
+    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),\r
+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+    DRV_ADD_RECON_QUESTION_ID,\r
+    Location\r
+    );\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+\r
+  CreateStringOpCode (\r
+    DRIVER_ADD_OPTION_QUESTION_ID,\r
+    (UINT8) 150,\r
+    STRING_TOKEN (STR_OPTIONAL_DATA),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    6,\r
+    75,\r
+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+    KEY_VALUE_DRIVER_ADD_OPT_DATA,\r
+    Location\r
+    );\r
+\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateConsolePage (\r
+  IN UINT16                           UpdatePageId,\r
+  IN BM_MENU_OPTION                   *ConsoleMenu,\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY       *NewMenuEntry;\r
+  BM_CONSOLE_CONTEXT  *NewConsoleContext;\r
+  BM_TERMINAL_CONTEXT *NewTerminalContext;\r
+  UINT16              Index;\r
+  UINT16              Index2;\r
+  UINT8               *Location;\r
+  UINT8               CheckFlags;\r
+  EFI_STATUS          Status;\r
+  VOID               *Interface;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {\r
+    NewMenuEntry      = BOpt_GetMenuEntry (ConsoleMenu, Index);\r
+    NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+    CheckFlags        = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (NewConsoleContext->IsActive) {\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+      CallbackData->BmmFakeNvData->ConsoleCheck[Index] = TRUE;\r
+    } else {\r
+      CallbackData->BmmFakeNvData->ConsoleCheck[Index] = FALSE;\r
+    }\r
+\r
+    CreateCheckBoxOpCode (\r
+      (UINT16) (CON_DEVICE_QUESTION_ID + Index),\r
+      (UINT8) 1,\r
+      NewMenuEntry->DisplayStringToken,\r
+      NewMenuEntry->HelpStringToken,\r
+      CheckFlags,\r
+      (UINT16) (CONSOLE_OPTION_OFFSET + Index),\r
+      Location\r
+      );\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    UpdateData->DataCount++;\r
+  }\r
+\r
+  Status = EfiLibLocateProtocol (&gTerminalDriverGuid, &Interface);\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index2 = 0; Index2 < TerminalMenu.MenuNumber; Index2++) {\r
+      CheckFlags          = EFI_IFR_FLAG_INTERACTIVE;\r
+      NewMenuEntry        = BOpt_GetMenuEntry (&TerminalMenu, Index2);\r
+      NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+      if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||\r
+          (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||\r
+          (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))\r
+          ) {\r
+        CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+        CallbackData->BmmFakeNvData->ConsoleCheck[Index] = TRUE;\r
+      } else {\r
+        CallbackData->BmmFakeNvData->ConsoleCheck[Index] = FALSE;\r
+      }\r
+\r
+      CreateCheckBoxOpCode (\r
+        (UINT16) (CON_DEVICE_QUESTION_ID + Index),\r
+        (UINT8) 1,\r
+        NewMenuEntry->DisplayStringToken,\r
+        NewMenuEntry->HelpStringToken,\r
+        CheckFlags,\r
+        (UINT16) (CONSOLE_OPTION_OFFSET + Index),\r
+        Location\r
+        );\r
+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+      UpdateData->DataCount++;\r
+      Index++;\r
+    }\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateOrderPage (\r
+  IN UINT16                           UpdatePageId,\r
+  IN BM_MENU_OPTION                   *OptionMenu,\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY *NewMenuEntry;\r
+  UINT16        Index;\r
+  UINT8         *Location;\r
+  IFR_OPTION    *IfrOptionList;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);\r
+\r
+  ZeroMem (CallbackData->BmmFakeNvData->OptionOrder, 100);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * OptionMenu->MenuNumber);\r
+  if (NULL == IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+    NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);\r
+    IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;\r
+    IfrOptionList[Index].Value = (UINT16) (NewMenuEntry->OptionNumber + 1);\r
+    IfrOptionList[Index].OptionString = NULL;\r
+    CallbackData->BmmFakeNvData->OptionOrder[Index] = (UINT8) (IfrOptionList[Index].Value);\r
+  }\r
+\r
+  if (OptionMenu->MenuNumber > 0) {\r
+    CreateOrderedListOpCode (\r
+      (UINT16) OPTION_ORDER_QUESTION_ID,\r
+      (UINT8) 100,\r
+      STRING_TOKEN (STR_CHANGE_ORDER),\r
+      STRING_TOKEN (STR_CHANGE_ORDER),\r
+      IfrOptionList,\r
+      OptionMenu->MenuNumber,\r
+      Location\r
+      );\r
+\r
+    for (Index = 0; Index < OptionMenu->MenuNumber + 2; Index++) {\r
+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    }\r
+\r
+    UpdateData->DataCount = (UINT16) (UpdateData->DataCount + OptionMenu->MenuNumber + 2);\r
+  }\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+\r
+  CopyMem (\r
+    CallbackData->BmmOldFakeNVData.OptionOrder,\r
+    CallbackData->BmmFakeNvData->OptionOrder,\r
+    100\r
+    );\r
+}\r
+\r
+VOID\r
+UpdateBootNextPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  UINT8           *Location;\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_LOAD_CONTEXT *NewLoadContext;\r
+  IFR_OPTION      *IfrOptionList;\r
+  UINTN           NumberOfOptions;\r
+  UINT16          Index;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  IfrOptionList                 = NULL;\r
+  NumberOfOptions               = BootOptionMenu.MenuNumber;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);\r
+\r
+  if (NumberOfOptions > 0) {\r
+    UpdateData->DataCount = (UINT8) (UpdateData->DataCount + NumberOfOptions);\r
+    IfrOptionList = AllocateZeroPool ((NumberOfOptions + 1) * sizeof (IFR_OPTION));\r
+\r
+    ASSERT (IfrOptionList);\r
+\r
+    CallbackData->BmmFakeNvData->BootNext = (UINT16) (BootOptionMenu.MenuNumber);\r
+\r
+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
+      NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+      NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+      if (NewLoadContext->IsBootNext) {\r
+        IfrOptionList[Index].Flags            = EFI_IFR_FLAG_DEFAULT | EFI_IFR_FLAG_INTERACTIVE;\r
+        CallbackData->BmmFakeNvData->BootNext = Index;\r
+      } else {\r
+        IfrOptionList[Index].Flags = EFI_IFR_FLAG_INTERACTIVE;\r
+      }\r
+\r
+      IfrOptionList[Index].Key          = (UINT16) KEY_VALUE_MAIN_BOOT_NEXT;\r
+      IfrOptionList[Index].Value        = Index;\r
+      IfrOptionList[Index].StringToken  = NewMenuEntry->DisplayStringToken;\r
+      IfrOptionList[Index].OptionString = NULL;\r
+    }\r
+\r
+    IfrOptionList[Index].Key          = (UINT16) KEY_VALUE_MAIN_BOOT_NEXT;\r
+    IfrOptionList[Index].Value        = Index;\r
+    IfrOptionList[Index].StringToken  = STRING_TOKEN (STR_NONE);\r
+    IfrOptionList[Index].Flags        = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (CallbackData->BmmFakeNvData->BootNext == Index) {\r
+      IfrOptionList[Index].Flags |= EFI_IFR_FLAG_DEFAULT;\r
+    }\r
+\r
+    IfrOptionList[Index].OptionString = NULL;\r
+\r
+    CreateOneOfOpCode (\r
+      (UINT16) BOOT_NEXT_QUESTION_ID,\r
+      (UINT8) 2,\r
+      STRING_TOKEN (STR_BOOT_NEXT),\r
+      STRING_TOKEN (STR_BOOT_NEXT_HELP),\r
+      IfrOptionList,\r
+      (UINTN) (NumberOfOptions + 1),\r
+      Location\r
+      );\r
+    Location  = Location + (NumberOfOptions + 2) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+    Location  = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+\r
+    UpdateData->DataCount += 3;\r
+    SafeFreePool (IfrOptionList);\r
+    IfrOptionList = NULL;\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateTimeOutPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  UINT8   *Location;\r
+  UINT16  BootTimeOut;\r
+\r
+  Location                      = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  BootTimeOut = BdsLibGetTimeout ();\r
+\r
+  CreateNumericOpCode (\r
+    (UINT16) BOOT_TIME_OUT_QUESTION_ID,\r
+    (UINT8) 2,\r
+    STRING_TOKEN (STR_NUM_AUTO_BOOT),\r
+    STRING_TOKEN (STR_HLP_AUTO_BOOT),\r
+    0,\r
+    65535,\r
+    0,\r
+    10,\r
+    0,\r
+    0,\r
+    Location\r
+    );\r
+\r
+  CallbackData->BmmFakeNvData->BootTimeOut = (UINT16) BootTimeOut;\r
+  UpdateData->DataCount++;\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdateTerminalPage (\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  UINT16              Index;\r
+  UINT8               *Location;\r
+  UINT8               CheckFlags;\r
+  IFR_OPTION          *IfrOptionList;\r
+  BM_MENU_ENTRY       *NewMenuEntry;\r
+  BM_TERMINAL_CONTEXT *NewTerminalContext;\r
+\r
+  ZeroMem (UpdateData, UPDATE_DATA_SIZE);\r
+  Location = (UINT8 *) &UpdateData->Data;\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  NewMenuEntry = BOpt_GetMenuEntry (\r
+                  &TerminalMenu,\r
+                  CallbackData->CurrentTerminal\r
+                  );\r
+\r
+  if (!NewMenuEntry) {\r
+    return ;\r
+  }\r
+\r
+  NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+  IfrOptionList       = AllocateZeroPool (sizeof (IFR_OPTION) * 19);\r
+  if (!IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < 19; Index++) {\r
+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[Index].Value)) {\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+      NewTerminalContext->BaudRateIndex         = (UINT8) Index;\r
+      CallbackData->BmmFakeNvData->COMBaudRate  = NewTerminalContext->BaudRateIndex;\r
+    }\r
+\r
+    IfrOptionList[Index].Flags        = CheckFlags;\r
+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_BAUD_RATE;\r
+    IfrOptionList[Index].StringToken  = BaudRateList[Index].StringToken;\r
+    IfrOptionList[Index].Value        = Index;\r
+  }\r
+\r
+  CreateOneOfOpCode (\r
+    (UINT16) COM_BAUD_RATE_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_COM_BAUD_RATE),\r
+    STRING_TOKEN (STR_COM_BAUD_RATE),\r
+    IfrOptionList,\r
+    19,\r
+    Location\r
+    );\r
+\r
+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);\r
+  UpdateData->DataCount += 2;\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 4);\r
+  if (!IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < 4; Index++) {\r
+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;\r
+\r
+    if (NewTerminalContext->DataBits == DataBitsList[Index].Value) {\r
+      NewTerminalContext->DataBitsIndex         = (UINT8) Index;\r
+      CallbackData->BmmFakeNvData->COMDataRate  = NewTerminalContext->DataBitsIndex;\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+    }\r
+\r
+    IfrOptionList[Index].Flags        = CheckFlags;\r
+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_DATA_BITS;\r
+    IfrOptionList[Index].StringToken  = DataBitsList[Index].StringToken;\r
+    IfrOptionList[Index].Value        = Index;\r
+  }\r
+\r
+  CreateOneOfOpCode (\r
+    (UINT16) COM_DATA_RATE_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_COM_DATA_BITS),\r
+    STRING_TOKEN (STR_COM_DATA_BITS),\r
+    IfrOptionList,\r
+    4,\r
+    Location\r
+    );\r
+\r
+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);\r
+  UpdateData->DataCount += 2;\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 5);\r
+  if (!IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < 5; Index++) {\r
+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (NewTerminalContext->Parity == ParityList[Index].Value) {\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+      NewTerminalContext->ParityIndex         = (UINT8) Index;\r
+      CallbackData->BmmFakeNvData->COMParity  = NewTerminalContext->ParityIndex;\r
+    }\r
+\r
+    IfrOptionList[Index].Flags        = CheckFlags;\r
+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_PARITY;\r
+    IfrOptionList[Index].StringToken  = ParityList[Index].StringToken;\r
+    IfrOptionList[Index].Value        = Index;\r
+  }\r
+\r
+  CreateOneOfOpCode (\r
+    (UINT16) COM_PARITY_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_COM_PARITY),\r
+    STRING_TOKEN (STR_COM_PARITY),\r
+    IfrOptionList,\r
+    5,\r
+    Location\r
+    );\r
+\r
+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);\r
+  UpdateData->DataCount += 2;\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 3);\r
+  if (!IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (NewTerminalContext->StopBits == StopBitsList[Index].Value) {\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+      NewTerminalContext->StopBitsIndex         = (UINT8) Index;\r
+      CallbackData->BmmFakeNvData->COMStopBits  = NewTerminalContext->StopBitsIndex;\r
+    }\r
+\r
+    IfrOptionList[Index].Flags        = CheckFlags;\r
+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_STOP_BITS;\r
+    IfrOptionList[Index].StringToken  = StopBitsList[Index].StringToken;\r
+    IfrOptionList[Index].Value        = Index;\r
+  }\r
+\r
+  CreateOneOfOpCode (\r
+    (UINT16) COM_STOP_BITS_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_COM_STOP_BITS),\r
+    STRING_TOKEN (STR_COM_STOP_BITS),\r
+    IfrOptionList,\r
+    3,\r
+    Location\r
+    );\r
+\r
+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);\r
+  UpdateData->DataCount += 2;\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 4);\r
+  if (!IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < 4; Index++) {\r
+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (NewTerminalContext->TerminalType == Index) {\r
+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;\r
+      CallbackData->BmmFakeNvData->COMTerminalType = NewTerminalContext->TerminalType;\r
+    }\r
+\r
+    IfrOptionList[Index].Flags        = CheckFlags;\r
+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_TERMI_TYPE;\r
+    IfrOptionList[Index].StringToken  = (STRING_REF) TerminalType[Index];\r
+    IfrOptionList[Index].Value        = Index;\r
+  }\r
+\r
+  CreateOneOfOpCode (\r
+    (UINT16) COM_TERMINAL_QUESTION_ID,\r
+    (UINT8) 1,\r
+    STRING_TOKEN (STR_COM_TERMI_TYPE),\r
+    STRING_TOKEN (STR_COM_TERMI_TYPE),\r
+    IfrOptionList,\r
+    4,\r
+    Location\r
+    );\r
+\r
+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);\r
+  UpdateData->DataCount += 2;\r
+\r
+  SafeFreePool (IfrOptionList);\r
+\r
+  CreateGotoOpCode (\r
+    FORM_MAIN_ID,\r
+    STRING_TOKEN (STR_SAVE_AND_EXIT),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+    KEY_VALUE_SAVE_AND_EXIT,\r
+    Location\r
+    );\r
+\r
+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+  UpdateData->DataCount++;\r
+\r
+  CreateGotoOpCode (\r
+    FORM_MAIN_ID,\r
+    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+    KEY_VALUE_NO_SAVE_AND_EXIT,\r
+    Location\r
+    );\r
+\r
+  UpdateData->DataCount++;\r
+\r
+  CallbackData->Hii->UpdateForm (\r
+                      CallbackData->Hii,\r
+                      CallbackData->BmmHiiHandle,\r
+                      (EFI_FORM_LABEL) FORM_CON_COM_SETUP_ID,\r
+                      TRUE,\r
+                      UpdateData\r
+                      );\r
+\r
+}\r
+\r
+VOID\r
+UpdatePageBody (\r
+  IN UINT16                           UpdatePageId,\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  CleanUpPage (UpdatePageId, CallbackData);\r
+  switch (UpdatePageId) {\r
+  case FORM_CON_IN_ID:\r
+    UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);\r
+    break;\r
+\r
+  case FORM_CON_OUT_ID:\r
+    UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);\r
+    break;\r
+\r
+  case FORM_CON_ERR_ID:\r
+    UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);\r
+    break;\r
+\r
+  case FORM_BOOT_CHG_ID:\r
+    UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);\r
+    break;\r
+\r
+  case FORM_DRV_CHG_ID:\r
+    UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+VOID *\r
+GetLegacyBootOptionVar (\r
+  IN  UINTN                            DeviceType,\r
+  OUT UINTN                            *OptionIndex,\r
+  OUT UINTN                            *OptionSize\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  VOID                      *OptionBuffer;\r
+  UINTN                     OrderSize;\r
+  UINTN                     Index;\r
+  UINT32                    Attribute;\r
+  UINT16                    *OrderBuffer;\r
+  CHAR16                    StrTemp[100];\r
+  UINT16                    FilePathSize;\r
+  CHAR16                    *Description;\r
+  UINT8                     *Ptr;\r
+  UINT8                     *OptionalData;\r
+\r
+  //\r
+  // Get Boot Option number from the size of BootOrder\r
+  //\r
+  OrderBuffer = BdsLibGetVariableAndSize (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  &OrderSize\r
+                  );\r
+\r
+  for (Index = 0; Index < OrderSize / sizeof (UINT16); Index++) {\r
+    UnicodeSPrint (StrTemp, 100, L"Boot%04x", OrderBuffer[Index]);\r
+    OptionBuffer = BdsLibGetVariableAndSize (\r
+                    StrTemp,\r
+                    &gEfiGlobalVariableGuid,\r
+                    OptionSize\r
+                    );\r
+    if (NULL == OptionBuffer) {\r
+      continue;\r
+    }\r
+\r
+    Ptr       = (UINT8 *) OptionBuffer;\r
+    Attribute = *(UINT32 *) Ptr;\r
+    Ptr += sizeof (UINT32);\r
+\r
+    FilePathSize = *(UINT16 *) Ptr;\r
+    Ptr += sizeof (UINT16);\r
+\r
+    Description = (CHAR16 *) Ptr;\r
+    Ptr += StrSize ((CHAR16 *) Ptr);\r
+\r
+    //\r
+    // Now Ptr point to Device Path\r
+    //\r
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
+    Ptr += FilePathSize;\r
+\r
+    //\r
+    // Now Ptr point to Optional Data\r
+    //\r
+    OptionalData = Ptr;\r
+\r
+    if ((DeviceType == ((BBS_TABLE *) OptionalData)->DeviceType) &&\r
+        (BBS_DEVICE_PATH == DevicePath->Type) &&\r
+        (BBS_BBS_DP == DevicePath->SubType)\r
+        ) {\r
+      *OptionIndex = OrderBuffer[Index];\r
+      SafeFreePool (OrderBuffer);\r
+      return OptionBuffer;\r
+    } else {\r
+      SafeFreePool (OptionBuffer);\r
+    }\r
+  }\r
+\r
+  SafeFreePool (OrderBuffer);\r
+  return NULL;\r
+}\r
+\r
+VOID\r
+UpdateSetLegacyDeviceOrderPage (\r
+  IN UINT16                           UpdatePageId,\r
+  IN BMM_CALLBACK_DATA                *CallbackData\r
+  )\r
+{\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
+  BM_MENU_OPTION              *OptionMenu;\r
+  BM_MENU_ENTRY               *NewMenuEntry;\r
+  IFR_OPTION                  *IfrOptionList;\r
+  STRING_REF                  StrRef;\r
+  STRING_REF                  StrRefHelp;\r
+  BBS_TYPE                    BbsType;\r
+  UINTN                       VarSize;\r
+  UINTN                       Pos;\r
+  UINTN                       Bit;\r
+  UINT16                      Index;\r
+  UINT16                      Index2;\r
+  UINT16                      Key;\r
+  CHAR16                      String[100];\r
+  CHAR16                      *TypeStr;\r
+  CHAR16                      *TypeStrHelp;\r
+  UINT16                      VarDevOrder;\r
+  UINT8                       *Location;\r
+  UINT8                       *VarData;\r
+  UINT8                       *OriginalPtr;\r
+  UINT8                       *LegacyOrder;\r
+  UINT8                       *OldData;\r
+  UINT8                       *DisMap;\r
+\r
+  OptionMenu                    = NULL;\r
+  Key = 0;\r
+  StrRef = 0;\r
+  StrRefHelp = 0;\r
+  TypeStr = NULL;\r
+  TypeStrHelp = NULL;\r
+  BbsType = BBS_FLOPPY;\r
+  LegacyOrder = NULL;\r
+  OldData = NULL;\r
+  DisMap = NULL;\r
+\r
+  Location = (UINT8 *) &UpdateData->Data;\r
+  CallbackData->BmmAskSaveOrNot = TRUE;\r
+\r
+  UpdatePageStart (CallbackData, &Location);\r
+\r
+  DisMap = CallbackData->BmmOldFakeNVData.DisableMap;\r
+\r
+  SetMem (DisMap, 32, 0);\r
+  //\r
+  // Create oneof option list\r
+  //\r
+  switch (UpdatePageId) {\r
+  case FORM_SET_FD_ORDER_ID:\r
+    OptionMenu  = (BM_MENU_OPTION *) &LegacyFDMenu;\r
+    Key         = LEGACY_FD_QUESTION_ID;\r
+    TypeStr     = StrFloppy;\r
+    TypeStrHelp = StrFloppyHelp;\r
+    BbsType     = BBS_FLOPPY;\r
+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyFD;\r
+    OldData     = CallbackData->BmmOldFakeNVData.LegacyFD;\r
+    break;\r
+\r
+  case FORM_SET_HD_ORDER_ID:\r
+    OptionMenu  = (BM_MENU_OPTION *) &LegacyHDMenu;\r
+    Key         = LEGACY_HD_QUESTION_ID;\r
+    TypeStr     = StrHardDisk;\r
+    TypeStrHelp = StrHardDiskHelp;\r
+    BbsType     = BBS_HARDDISK;\r
+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyHD;\r
+    OldData     = CallbackData->BmmOldFakeNVData.LegacyHD;\r
+    break;\r
+\r
+  case FORM_SET_CD_ORDER_ID:\r
+    OptionMenu  = (BM_MENU_OPTION *) &LegacyCDMenu;\r
+    Key         = LEGACY_CD_QUESTION_ID;\r
+    TypeStr     = StrCDROM;\r
+    TypeStrHelp = StrCDROMHelp;\r
+    BbsType     = BBS_CDROM;\r
+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyCD;\r
+    OldData     = CallbackData->BmmOldFakeNVData.LegacyCD;\r
+    break;\r
+\r
+  case FORM_SET_NET_ORDER_ID:\r
+    OptionMenu  = (BM_MENU_OPTION *) &LegacyNETMenu;\r
+    Key         = LEGACY_NET_QUESTION_ID;\r
+    TypeStr     = StrNET;\r
+    TypeStrHelp = StrNETHelp;\r
+    BbsType     = BBS_EMBED_NETWORK;\r
+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyNET;\r
+    OldData     = CallbackData->BmmOldFakeNVData.LegacyNET;\r
+    break;\r
+\r
+  case FORM_SET_BEV_ORDER_ID:\r
+    OptionMenu  = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
+    Key         = LEGACY_BEV_QUESTION_ID;\r
+    TypeStr     = StrBEV;\r
+    TypeStrHelp = StrBEVHelp;\r
+    BbsType     = BBS_BEV_DEVICE;\r
+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyBEV;\r
+    OldData     = CallbackData->BmmOldFakeNVData.LegacyBEV;\r
+    break;\r
+\r
+  }\r
+\r
+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);\r
+\r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * (OptionMenu->MenuNumber + 1));\r
+  if (NULL == IfrOptionList) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+    NewMenuEntry                = BOpt_GetMenuEntry (OptionMenu, Index);\r
+    IfrOptionList[Index].Flags  = EFI_IFR_FLAG_INTERACTIVE;\r
+    if (0 == Index) {\r
+      IfrOptionList[Index].Flags |= EFI_IFR_FLAG_DEFAULT;\r
+    }\r
+\r
+    IfrOptionList[Index].Key          = Key;\r
+    IfrOptionList[Index].StringToken  = NewMenuEntry->DisplayStringToken;\r
+    IfrOptionList[Index].Value        = (UINT16) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->Index;\r
+    IfrOptionList[Index].OptionString = NULL;\r
+  }\r
+  //\r
+  // for item "Disabled"\r
+  //\r
+  IfrOptionList[Index].Flags        = EFI_IFR_FLAG_INTERACTIVE;\r
+  IfrOptionList[Index].Key          = Key;\r
+  IfrOptionList[Index].StringToken  = STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE);\r
+  IfrOptionList[Index].Value        = 0xFF;\r
+  IfrOptionList[Index].OptionString = NULL;\r
+\r
+  //\r
+  // Get Device Order from variable\r
+  //\r
+  VarData = BdsLibGetVariableAndSize (\r
+              VarLegacyDevOrder,\r
+              &EfiLegacyDevOrderGuid,\r
+              &VarSize\r
+              );\r
+\r
+  if (NULL != VarData) {\r
+    OriginalPtr = VarData;\r
+    DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
+    while (VarData < VarData + VarSize) {\r
+      if (DevOrder->BbsType == BbsType) {\r
+        break;\r
+      }\r
+\r
+      VarData += sizeof (BBS_TYPE);\r
+      VarData += *(UINT16 *) VarData;\r
+      DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
+    }\r
+    //\r
+    // Create oneof tag here for FD/HD/CD #1 #2\r
+    //\r
+    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+      for (Index2 = 0; Index2 <= OptionMenu->MenuNumber; Index2++) {\r
+        IfrOptionList[Index2].Key = (UINT16) (Key + Index);\r
+      }\r
+      //\r
+      // Create the string for oneof tag\r
+      //\r
+      UnicodeSPrint (String, sizeof (String), TypeStr, Index);\r
+      StrRef = 0;\r
+      CallbackData->Hii->NewString (\r
+                          CallbackData->Hii,\r
+                          NULL,\r
+                          CallbackData->BmmHiiHandle,\r
+                          &StrRef,\r
+                          String\r
+                          );\r
+\r
+      UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);\r
+      StrRefHelp = 0;\r
+      CallbackData->Hii->NewString (\r
+                          CallbackData->Hii,\r
+                          NULL,\r
+                          CallbackData->BmmHiiHandle,\r
+                          &StrRefHelp,\r
+                          String\r
+                          );\r
+\r
+      CreateOneOfOpCode (\r
+        (UINT16) (Key + Index),\r
+        (UINT8) 1,\r
+        StrRef,\r
+        StrRefHelp,\r
+        IfrOptionList,\r
+        OptionMenu->MenuNumber + 1,\r
+        Location\r
+        );\r
+\r
+      VarDevOrder = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));\r
+\r
+      if (0xFF00 == (VarDevOrder & 0xFF00)) {\r
+        LegacyOrder[Index]  = 0xFF;\r
+        Pos                 = (VarDevOrder & 0xFF) / 8;\r
+        Bit                 = 7 - ((VarDevOrder & 0xFF) % 8);\r
+        DisMap[Pos] |= (UINT8) (1 << Bit);\r
+      } else {\r
+        LegacyOrder[Index] = (UINT8) (VarDevOrder & 0xFF);\r
+      }\r
+\r
+      Location              = Location + (OptionMenu->MenuNumber + 2) * ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+      Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+      UpdateData->DataCount = (UINT16) (UpdateData->DataCount + (OptionMenu->MenuNumber + 3));\r
+    }\r
+  }\r
+\r
+  CopyMem (\r
+    OldData,\r
+    LegacyOrder,\r
+    100\r
+    );\r
+\r
+  if (IfrOptionList != NULL) {\r
+    SafeFreePool (IfrOptionList);\r
+    IfrOptionList = NULL;\r
+  }\r
+\r
+  UpdatePageEnd (CallbackData, Location);\r
+}\r
+\r
+VOID\r
+UpdatePageId (\r
+  BMM_CALLBACK_DATA              *Private,\r
+  UINT16                         NewPageId\r
+  )\r
+{\r
+  UINT16  FileOptionMask;\r
+\r
+  FileOptionMask = (UINT16) (FILE_OPTION_MASK & NewPageId);\r
+\r
+  if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {\r
+    //\r
+    // If we select a handle to add driver option, advance to the add handle description page.\r
+    //\r
+    NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;\r
+  } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {\r
+    //\r
+    // Return to main page after "Save Changes" or "Discard Changes".\r
+    //\r
+    NewPageId = FORM_MAIN_ID;\r
+  }\r
+\r
+  if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {\r
+    Private->BmmPreviousPageId  = Private->BmmCurrentPageId;\r
+    Private->BmmCurrentPageId   = NewPageId;\r
+  }\r
+}\r