]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootOption.c
IntelFrameworkModulePkg BdsDxe: Remove redundant functions
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootOption.c
index 7929f5cbfd4d56632e2362b71e7b6dbaf481e32a..c4a0e17f3bf1b21f3dc175570b26618b3a1b2288 100644 (file)
@@ -5,8 +5,8 @@
 \r
   Boot option manipulation\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -370,13 +370,9 @@ BOpt_FindFileSystem (
       if (FileContext->Info == NULL) {\r
         VolumeLabel = L"NO FILE SYSTEM INFO";\r
       } else {\r
-        if (FileContext->Info->VolumeLabel == NULL) {\r
-          VolumeLabel = L"NULL VOLUME LABEL";\r
-        } else {\r
-          VolumeLabel = FileContext->Info->VolumeLabel;\r
-          if (*VolumeLabel == 0x0000) {\r
-            VolumeLabel = L"NO VOLUME LABEL";\r
-          }\r
+        VolumeLabel = FileContext->Info->VolumeLabel;\r
+        if (*VolumeLabel == 0x0000) {\r
+          VolumeLabel = L"NO VOLUME LABEL";\r
         }\r
       }\r
 \r
@@ -423,7 +419,8 @@ BOpt_FindFileSystem (
       FileContext->Handle           = LoadFileHandle[Index];\r
       FileContext->IsRoot           = TRUE;\r
 \r
-      FileContext->DevicePath = DevicePathFromHandle (FileContext->Handle);\r
+      FileContext->DevicePath       = DevicePathFromHandle (FileContext->Handle);\r
+      FileContext->FileName         = DevicePathToStr (FileContext->DevicePath);\r
 \r
       MenuEntry->HelpString     = DevicePathToStr (FileContext->DevicePath);\r
 \r
@@ -528,6 +525,7 @@ BOpt_FreeMenu (
     RemoveEntryList (&MenuEntry->Link);\r
     BOpt_DestroyMenuEntry (MenuEntry);\r
   }\r
+  FreeMenu->MenuNumber = 0;\r
 }\r
 \r
 /**\r
@@ -706,7 +704,7 @@ BOpt_GetLegacyOptions (
   HDD_INFO                  *HddInfo;\r
   UINT16                    BbsCount;\r
   BBS_TABLE                 *BbsTable;\r
-  UINT                    Index;\r
+  UINT16                    Index;\r
   CHAR16                    DescString[100];\r
   UINTN                     FDNum;\r
   UINTN                     HDNum;\r
@@ -765,8 +763,8 @@ BOpt_GetLegacyOptions (
     }\r
 \r
     NewLegacyDevContext           = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
-    NewLegacyDevContext->BbsTable = &BbsTable[Index];\r
-    NewLegacyDevContext->Index    = Index;\r
+    NewLegacyDevContext->BbsEntry = &BbsTable[Index];\r
+    NewLegacyDevContext->BbsIndex = Index;\r
     NewLegacyDevContext->BbsCount = BbsCount;\r
     BdsBuildLegacyDevNameString (\r
       &BbsTable[Index],\r
@@ -774,12 +772,11 @@ BOpt_GetLegacyOptions (
       sizeof (DescString),\r
       DescString\r
       );\r
-    NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));\r
+    NewLegacyDevContext->Description = AllocateCopyPool (StrSize (DescString), DescString);\r
     if (NULL == NewLegacyDevContext->Description) {\r
       break;\r
     }\r
 \r
-    CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));\r
     NewMenuEntry->DisplayString = NewLegacyDevContext->Description;\r
     NewMenuEntry->HelpString    = NULL;\r
 \r
@@ -896,7 +893,7 @@ BOpt_GetBootOptions (
   if (BootOrderList == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   //\r
   // Get the BootNext from the Var\r
   //\r
@@ -1011,14 +1008,11 @@ BOpt_GetBootOptions (
     NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;\r
     LoadOptionPtr += sizeof (UINT16);\r
 \r
-    StringSize                  = StrSize ((UINT16 *) LoadOptionPtr);\r
-    NewLoadContext->Description = AllocateZeroPool (StringSize);\r
+    StringSize = StrSize((UINT16*)LoadOptionPtr);\r
+\r
+    NewLoadContext->Description = AllocateCopyPool (StrSize((UINT16*)LoadOptionPtr), LoadOptionPtr);\r
     ASSERT (NewLoadContext->Description != NULL);\r
-    CopyMem (\r
-      NewLoadContext->Description,\r
-      (UINT16 *) LoadOptionPtr,\r
-      StringSize\r
-      );\r
+\r
     NewMenuEntry->DisplayString = NewLoadContext->Description;\r
 \r
     LoadOptionPtr += StringSize;\r
@@ -1093,6 +1087,7 @@ BOpt_AppendFileName (
 {\r
   UINTN   Size1;\r
   UINTN   Size2;\r
+  UINTN   MaxLen;\r
   CHAR16  *Str;\r
   CHAR16  *TmpStr;\r
   CHAR16  *Ptr;\r
@@ -1100,18 +1095,19 @@ BOpt_AppendFileName (
 \r
   Size1 = StrSize (Str1);\r
   Size2 = StrSize (Str2);\r
-  Str   = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
+  MaxLen = (Size1 + Size2 + sizeof (CHAR16)) / sizeof (CHAR16);\r
+  Str   = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
   ASSERT (Str != NULL);\r
 \r
-  TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); \r
+  TmpStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
   ASSERT (TmpStr != NULL);\r
 \r
-  StrCat (Str, Str1);\r
+  StrCatS (Str, MaxLen, Str1);\r
   if (!((*Str == '\\') && (*(Str + 1) == 0))) {\r
-    StrCat (Str, L"\\");\r
+    StrCatS (Str, MaxLen, L"\\");\r
   }\r
 \r
-  StrCat (Str, Str2);\r
+  StrCatS (Str, MaxLen, Str2);\r
 \r
   Ptr       = Str;\r
   LastSlash = Str;\r
@@ -1124,11 +1120,11 @@ BOpt_AppendFileName (
       //\r
 \r
       //\r
-      // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings \r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
       // that overlap.\r
       //\r
-      StrCpy (TmpStr, Ptr + 3);\r
-      StrCpy (LastSlash, TmpStr);\r
+      StrCpyS (TmpStr, MaxLen, Ptr + 3);\r
+      StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
       //\r
@@ -1136,11 +1132,11 @@ BOpt_AppendFileName (
       //\r
 \r
       //\r
-      // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings \r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
       // that overlap.\r
       //\r
-      StrCpy (TmpStr, Ptr + 2);\r
-      StrCpy (Ptr, TmpStr);\r
+      StrCpyS (TmpStr, MaxLen, Ptr + 2);\r
+      StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\') {\r
       LastSlash = Ptr;\r
@@ -1150,7 +1146,7 @@ BOpt_AppendFileName (
   }\r
 \r
   FreePool (TmpStr);\r
-  \r
+\r
   return Str;\r
 }\r
 \r
@@ -1196,69 +1192,7 @@ BOpt_IsEfiImageName (
   return FALSE;\r
 }\r
 \r
-/**\r
-\r
-  Check whether current FileName point to a valid Efi Application\r
-\r
-  @param Dir       Pointer to current Directory\r
-  @param FileName  Pointer to current File name.\r
-\r
-  @retval TRUE      Is a valid Efi Application\r
-  @retval FALSE     not a valid Efi Application\r
-\r
-**/\r
-BOOLEAN\r
-BOpt_IsEfiApp (\r
-  IN EFI_FILE_HANDLE Dir,\r
-  IN UINT16          *FileName\r
-  )\r
-{\r
-  UINTN                       BufferSize;\r
-  EFI_IMAGE_DOS_HEADER        DosHdr;\r
-  UINT16                      Subsystem;\r
-  EFI_FILE_HANDLE             File;\r
-  EFI_STATUS                  Status;\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;\r
 \r
-  Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-\r
-  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);\r
-  File->Read (File, &BufferSize, &DosHdr);\r
-  if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
-    File->Close (File);\r
-    return FALSE;\r
-  }\r
-\r
-  File->SetPosition (File, DosHdr.e_lfanew);\r
-  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
-  File->Read (File, &BufferSize, &PeHdr);\r
-  if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-    File->Close (File);\r
-    return FALSE;\r
-  }\r
-  //\r
-  // Determine PE type and read subsytem\r
-  //\r
-  if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-    Subsystem = PeHdr.Pe32.OptionalHeader.Subsystem;\r
-  } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
-    Subsystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem;\r
-  } else {\r
-    return FALSE;\r
-  }\r
-\r
-  if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
-    File->Close (File);\r
-    return TRUE;\r
-  } else {\r
-    File->Close (File);\r
-    return FALSE;\r
-  }\r
-}\r
 \r
 /**\r
 \r
@@ -1359,136 +1293,98 @@ BOpt_FindDrivers (
 \r
   Get the Option Number that has not been allocated for use.\r
 \r
+  @param Type  The type of Option.\r
+\r
   @return The available Option Number.\r
 \r
 **/\r
 UINT16\r
-BOpt_GetBootOptionNumber (\r
-  VOID\r
+BOpt_GetOptionNumber (\r
+  CHAR16        *Type\r
   )\r
 {\r
-  BM_MENU_ENTRY *NewMenuEntry;\r
-  UINT16        *BootOrderList;\r
-  UINTN         BootOrderListSize;\r
-  UINT16        Number;\r
+  UINT16        *OrderList;\r
+  UINTN         OrderListSize;\r
   UINTN         Index;\r
-  UINTN         Index2;\r
-  BOOLEAN       Found;\r
-  CHAR16        StrTemp[100];\r
+  CHAR16        StrTemp[20];\r
   UINT16        *OptionBuffer;\r
+  UINT16        OptionNumber;\r
   UINTN         OptionSize;\r
 \r
-  BootOrderListSize = 0;\r
-  BootOrderList     = NULL;\r
+  OrderListSize = 0;\r
+  OrderList     = NULL;\r
+  OptionNumber  = 0;\r
+  Index         = 0;\r
 \r
-  BootOrderList = BdsLibGetVariableAndSize (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    &BootOrderListSize\r
-                    );\r
-  if (BootOrderList != NULL) {\r
-    //\r
-    // already have Boot####\r
-    //\r
-    // AlreadyBootNumbers = BootOrderListSize / sizeof(UINT16);\r
-    //\r
-    for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
-      Found = TRUE;\r
-      for (Index2 = 0; Index2 < BootOptionMenu.MenuNumber; Index2++) {\r
-        NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index2);\r
-        if (Index == NewMenuEntry->OptionNumber) {\r
-          Found = FALSE;\r
-          break;\r
-        }\r
-      }\r
+  UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%sOrder", Type);\r
 \r
-      if (Found) {\r
-        UnicodeSPrint (StrTemp, 100, L"Boot%04x", Index);\r
-        DEBUG((DEBUG_ERROR,"INdex= %s\n", StrTemp));\r
-        OptionBuffer = BdsLibGetVariableAndSize (\r
+  OrderList = BdsLibGetVariableAndSize (\r
                           StrTemp,\r
                           &gEfiGlobalVariableGuid,\r
-                          &OptionSize\r
+                          &OrderListSize\r
                           );\r
-        if (NULL == OptionBuffer) {\r
+\r
+  for (OptionNumber = 0; ; OptionNumber++) {\r
+    if (OrderList != NULL) {\r
+      for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {\r
+        if (OptionNumber == OrderList[Index]) {\r
           break;\r
         }\r
       }\r
     }\r
-    //\r
-    // end for Index\r
-    //\r
-    Number = (UINT16) Index;\r
-  } else {\r
-    //\r
-    // No Boot####\r
-    //\r
-    Number = 0;\r
+\r
+    if (Index < OrderListSize / sizeof (UINT16)) {\r
+      //\r
+      // The OptionNumber occurs in the OrderList, continue to use next one\r
+      //\r
+      continue;\r
+    }\r
+    UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%s%04x", Type, (UINTN) OptionNumber);\r
+    DEBUG((EFI_D_ERROR,"Option = %s\n", StrTemp));\r
+    OptionBuffer = BdsLibGetVariableAndSize (\r
+                       StrTemp,\r
+                       &gEfiGlobalVariableGuid,\r
+                       &OptionSize\r
+                       );\r
+    if (NULL == OptionBuffer) {\r
+      //\r
+      // The Boot[OptionNumber] / Driver[OptionNumber] NOT occurs, we found it\r
+      //\r
+      break;\r
+    }\r
   }\r
 \r
-  return Number;\r
+  return OptionNumber;\r
 }\r
 \r
 /**\r
 \r
-  Get the Option Number that is not in use.\r
+  Get the Option Number for Boot#### that does not used.\r
 \r
-  @return The unused Option Number.\r
+  @return The available Option Number.\r
 \r
 **/\r
 UINT16\r
-BOpt_GetDriverOptionNumber (\r
+BOpt_GetBootOptionNumber (\r
   VOID\r
   )\r
 {\r
-  BM_MENU_ENTRY *NewMenuEntry;\r
-  UINT16        *DriverOrderList;\r
-  UINTN         DriverOrderListSize;\r
-  UINT16        Number;\r
-  UINTN         Index;\r
-  UINTN         Index2;\r
-  BOOLEAN       Found;\r
+  return BOpt_GetOptionNumber (L"Boot");\r
+}\r
 \r
-  DriverOrderListSize = 0;\r
-  DriverOrderList     = NULL;\r
+/**\r
 \r
-  DriverOrderList = BdsLibGetVariableAndSize (\r
-                      L"DriverOrder",\r
-                      &gEfiGlobalVariableGuid,\r
-                      &DriverOrderListSize\r
-                      );\r
-  if (DriverOrderList != NULL) {\r
-    //\r
-    // already have Driver####\r
-    //\r
-    // AlreadyDriverNumbers = DriverOrderListSize / sizeof(UINT16);\r
-    //\r
-    for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {\r
-      Found = TRUE;\r
-      for (Index2 = 0; Index2 < DriverOptionMenu.MenuNumber; Index2++) {\r
-        NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index2);\r
-        if (Index == NewMenuEntry->OptionNumber) {\r
-          Found = FALSE;\r
-          break;\r
-        }\r
-      }\r
+  Get the Option Number for Driver#### that does not used.\r
 \r
-      if (Found) {\r
-        break;\r
-      }\r
-    }\r
-    //\r
-    // end for Index\r
-    //\r
-    Number = (UINT16) Index;\r
-  } else {\r
-    //\r
-    // No Driver####\r
-    //\r
-    Number = 0;\r
-  }\r
+  @return The unused Option Number.\r
 \r
-  return Number;\r
+**/\r
+UINT16\r
+BOpt_GetDriverOptionNumber (\r
+  VOID\r
+  )\r
+{\r
+  return BOpt_GetOptionNumber (L"Driver");\r
 }\r
 \r
 /**\r
@@ -1539,7 +1435,7 @@ BOpt_GetDriverOptions (
   if (DriverOrderList == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {\r
     UnicodeSPrint (\r
       DriverString,\r
@@ -1659,3 +1555,207 @@ BOpt_GetDriverOptions (
 \r
 }\r
 \r
+/**\r
+  Get option number according to Boot#### and BootOrder variable.\r
+  The value is saved as #### + 1.\r
+\r
+  @param CallbackData    The BMM context data.\r
+**/\r
+VOID\r
+GetBootOrder (\r
+  IN  BMM_CALLBACK_DATA    *CallbackData\r
+  )\r
+{\r
+  BMM_FAKE_NV_DATA          *BmmConfig;\r
+  UINT16                    Index;\r
+  UINT16                    OptionOrderIndex;\r
+  UINTN                     DeviceType;\r
+  BM_MENU_ENTRY             *NewMenuEntry;\r
+  BM_LOAD_CONTEXT           *NewLoadContext;\r
+\r
+  ASSERT (CallbackData != NULL);\r
+\r
+  DeviceType = (UINTN) -1;\r
+  BmmConfig  = &CallbackData->BmmFakeNvData;\r
+  ZeroMem (BmmConfig->BootOptionOrder, sizeof (BmmConfig->BootOptionOrder));\r
+\r
+  for (Index = 0, OptionOrderIndex = 0; ((Index < BootOptionMenu.MenuNumber) &&\r
+       (OptionOrderIndex < (sizeof (BmmConfig->BootOptionOrder) / sizeof (BmmConfig->BootOptionOrder[0]))));\r
+       Index++) {\r
+    NewMenuEntry   = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewLoadContext->IsLegacy) {\r
+      if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
+        DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
+      } else {\r
+        //\r
+        // Only show one legacy boot option for the same device type\r
+        // assuming the boot options are grouped by the device type\r
+        //\r
+        continue;\r
+      }\r
+    }\r
+    BmmConfig->BootOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
+  }\r
+}\r
+\r
+/**\r
+  According to LegacyDevOrder variable to get legacy FD\HD\CD\NET\BEV\r
+  devices list .\r
+\r
+  @param CallbackData    The BMM context data.\r
+**/\r
+VOID\r
+GetLegacyDeviceOrder (\r
+  IN  BMM_CALLBACK_DATA    *CallbackData\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  UINTN                     OptionIndex;\r
+  UINT16                    PageIdList[5];\r
+  UINTN                     PageNum;\r
+  UINTN                     VarSize;\r
+  UINT8                     *VarData;\r
+  UINT8                     *WorkingVarData;\r
+  LEGACY_DEV_ORDER_ENTRY    *DevOrder;\r
+  UINT16                    VarDevOrder;\r
+  UINT8                     *DisMap;\r
+  BM_MENU_OPTION            *OptionMenu;\r
+  BBS_TYPE                  BbsType;\r
+  UINT8                     *LegacyOrder;\r
+  UINT8                     *OldData;\r
+  UINTN                     Pos;\r
+  UINTN                     Bit;\r
+\r
+  ASSERT (CallbackData != NULL);\r
+\r
+  PageIdList[0] = FORM_SET_FD_ORDER_ID;\r
+  PageIdList[1] = FORM_SET_HD_ORDER_ID;\r
+  PageIdList[2] = FORM_SET_CD_ORDER_ID;\r
+  PageIdList[3] = FORM_SET_NET_ORDER_ID;\r
+  PageIdList[4] = FORM_SET_BEV_ORDER_ID;\r
+  OptionMenu  = NULL;\r
+  BbsType     = 0;\r
+  LegacyOrder = NULL;\r
+  OldData     = NULL;\r
+  DisMap      = ZeroMem (CallbackData->BmmFakeNvData.DisableMap, sizeof (CallbackData->BmmFakeNvData.DisableMap));\r
+  PageNum     = ARRAY_SIZE (PageIdList);\r
+  VarData     = BdsLibGetVariableAndSize (\r
+                  VAR_LEGACY_DEV_ORDER,\r
+                  &gEfiLegacyDevOrderVariableGuid,\r
+                  &VarSize\r
+                  );\r
+\r
+  for (Index = 0; Index < PageNum; Index++) {\r
+    switch (PageIdList[Index]) {\r
+\r
+    case FORM_SET_FD_ORDER_ID:\r
+      OptionMenu  = (BM_MENU_OPTION *) &LegacyFDMenu;\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
+      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
+      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
+      BbsType     = BBS_EMBED_NETWORK;\r
+      LegacyOrder = CallbackData->BmmFakeNvData.LegacyNET;\r
+      OldData     = CallbackData->BmmOldFakeNVData.LegacyNET;\r
+      break;\r
+\r
+    default:\r
+      ASSERT (PageIdList[Index] == FORM_SET_BEV_ORDER_ID);\r
+      OptionMenu  = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
+      BbsType     = BBS_BEV_DEVICE;\r
+      LegacyOrder = CallbackData->BmmFakeNvData.LegacyBEV;\r
+      OldData     = CallbackData->BmmOldFakeNVData.LegacyBEV;\r
+      break;\r
+    }\r
+\r
+    if (NULL != VarData) {\r
+      WorkingVarData = VarData;\r
+      DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
+      while (WorkingVarData < VarData + VarSize) {\r
+        if (DevOrder->BbsType == BbsType) {\r
+          break;\r
+        }\r
+\r
+        WorkingVarData  = (UINT8 *)((UINTN)WorkingVarData + sizeof (BBS_TYPE));\r
+        WorkingVarData += *(UINT16 *) WorkingVarData;\r
+        DevOrder = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
+      }\r
+      for (OptionIndex = 0; OptionIndex < OptionMenu->MenuNumber; OptionIndex++) {\r
+        VarDevOrder = *(UINT16 *) ((UINTN) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + OptionIndex * sizeof (UINT16));\r
+         if (0xFF00 == (VarDevOrder & 0xFF00)) {\r
+          LegacyOrder[OptionIndex]  = 0xFF;\r
+          Pos                       = (VarDevOrder & 0xFF) / 8;\r
+          Bit                       = 7 - ((VarDevOrder & 0xFF) % 8);\r
+          DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
+        } else {\r
+          LegacyOrder[OptionIndex] = (UINT8) (VarDevOrder & 0xFF);\r
+        }\r
+      }\r
+      CopyMem (OldData, LegacyOrder, 100);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Get driver option order from globalc DriverOptionMenu.\r
+\r
+  @param CallbackData    The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetDriverOrder (\r
+  IN  BMM_CALLBACK_DATA    *CallbackData\r
+  )\r
+{\r
+  BMM_FAKE_NV_DATA          *BmmConfig;\r
+  UINT16                    Index;\r
+  UINT16                    OptionOrderIndex;\r
+  UINTN                     DeviceType;\r
+  BM_MENU_ENTRY             *NewMenuEntry;\r
+  BM_LOAD_CONTEXT           *NewLoadContext;\r
+\r
+  ASSERT (CallbackData != NULL);\r
+\r
+  DeviceType = (UINTN) -1;\r
+  BmmConfig  = &CallbackData->BmmFakeNvData;\r
+  ZeroMem (BmmConfig->DriverOptionOrder, sizeof (BmmConfig->DriverOptionOrder));\r
+\r
+  for (Index = 0, OptionOrderIndex = 0; ((Index < DriverOptionMenu.MenuNumber) &&\r
+       (OptionOrderIndex < (sizeof (BmmConfig->DriverOptionOrder) / sizeof (BmmConfig->DriverOptionOrder[0]))));\r
+       Index++) {\r
+    NewMenuEntry   = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
+    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewLoadContext->IsLegacy) {\r
+      if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
+        DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
+      } else {\r
+        //\r
+        // Only show one legacy boot option for the same device type\r
+        // assuming the boot options are grouped by the device type\r
+        //\r
+        continue;\r
+      }\r
+    }\r
+    BmmConfig->DriverOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
+  }\r
+}\r