]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BBSsupport.c
index 94261a0bef5824ed75e7e32a48fdb9a691bfb033..f9ba0a7bc78320037caa010e3490249085f77ed2 100644 (file)
@@ -3,8 +3,8 @@
   and manage the legacy boot option, all legacy boot option is getting from\r
   the legacy BBS table.\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
@@ -16,1648 +16,239 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "BBSsupport.h"\r
 \r
-/**\r
-\r
-  Translate the first n characters of an Ascii string to\r
-  Unicode characters. The count n is indicated by parameter\r
-  Size. If Size is greater than the length of string, then\r
-  the entire string is translated.\r
-\r
-\r
-  @param AStr               Pointer to input Ascii string.\r
-  @param Size               The number of characters to translate.\r
-  @param UStr               Pointer to output Unicode string buffer.\r
-\r
-**/\r
-VOID\r
-AsciiToUnicodeSize (\r
-  IN UINT8              *AStr,\r
-  IN UINTN              Size,\r
-  OUT UINT16            *UStr\r
-  )\r
-{\r
-  UINTN Idx;\r
-\r
-  Idx = 0;\r
-  while (AStr[Idx] != 0) {\r
-    UStr[Idx] = (CHAR16) AStr[Idx];\r
-    if (Idx == Size) {\r
-      break;\r
-    }\r
-\r
-    Idx++;\r
-  }\r
-  UStr[Idx] = 0;\r
-}\r
+#pragma pack(1)\r
+typedef struct {\r
+  BBS_TABLE BbsEntry;\r
+  UINT16    BbsIndex;\r
+} LEGACY_BOOT_OPTION_BBS_DATA;\r
+#pragma pack()\r
 \r
 /**\r
-  Build Legacy Device Name String according.\r
-\r
-  @param CurBBSEntry     BBS Table.\r
-  @param Index           Index.\r
-  @param BufSize         The buffer size.\r
-  @param BootString      The output string.\r
-\r
+  Re-order the Boot Option according to the DevOrder.\r
+\r
+  The routine re-orders the Boot Option in BootOption array according to\r
+  the order specified by DevOrder.\r
+\r
+  @param DevOrder           Pointer to buffer containing the BBS Index,\r
+                            high 8-bit value 0xFF indicating a disabled boot option\r
+  @param DevOrderCount      Count of the BBS Index\r
+  @param EnBootOption       Callee allocated buffer containing the enabled Boot Option Numbers\r
+  @param EnBootOptionCount  Count of the enabled Boot Option Numbers\r
+  @param DisBootOption      Callee allocated buffer containing the disabled Boot Option Numbers\r
+  @param DisBootOptionCount Count of the disabled Boot Option Numbers\r
 **/\r
 VOID\r
-BdsBuildLegacyDevNameString (\r
-  IN  BBS_TABLE                 *CurBBSEntry,\r
-  IN  UINTN                     Index,\r
-  IN  UINTN                     BufSize,\r
-  OUT CHAR16                    *BootString\r
-  )\r
-{\r
-  CHAR16  *Fmt;\r
-  CHAR16  *Type;\r
-  UINT8   *StringDesc;\r
-  CHAR16  Temp[80];\r
-\r
-  switch (Index) {\r
-  //\r
-  // Primary Master\r
-  //\r
-  case 1:\r
-    Fmt = L"Primary Master %s";\r
-    break;\r
-\r
- //\r
- // Primary Slave\r
- //\r
-  case 2:\r
-    Fmt = L"Primary Slave %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Master\r
-  //\r
-  case 3:\r
-    Fmt = L"Secondary Master %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Slave\r
-  //\r
-  case 4:\r
-    Fmt = L"Secondary Slave %s";\r
-    break;\r
-\r
-  default:\r
-    Fmt = L"%s";\r
-    break;\r
-  }\r
-\r
-  switch (CurBBSEntry->DeviceType) {\r
-  case BBS_FLOPPY:\r
-    Type = L"Floppy";\r
-    break;\r
-\r
-  case BBS_HARDDISK:\r
-    Type = L"Harddisk";\r
-    break;\r
-\r
-  case BBS_CDROM:\r
-    Type = L"CDROM";\r
-    break;\r
-\r
-  case BBS_PCMCIA:\r
-    Type = L"PCMCIAe";\r
-    break;\r
-\r
-  case BBS_USB:\r
-    Type = L"USB";\r
-    break;\r
-\r
-  case BBS_EMBED_NETWORK:\r
-    Type = L"Network";\r
-    break;\r
-\r
-  case BBS_BEV_DEVICE:\r
-    Type = L"BEVe";\r
-    break;\r
-\r
-  case BBS_UNKNOWN:\r
-  default:\r
-    Type = L"Unknown";\r
-    break;\r
-  }\r
-  //\r
-  // If current BBS entry has its description then use it.\r
-  //\r
-  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);\r
-  if (NULL != StringDesc) {\r
-    //\r
-    // Only get fisrt 32 characters, this is suggested by BBS spec\r
-    //\r
-    AsciiToUnicodeSize (StringDesc, 32, Temp);\r
-    Fmt   = L"%s";\r
-    Type  = Temp;\r
-  }\r
-\r
-  //\r
-  // BbsTable 16 entries are for onboard IDE.\r
-  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11\r
-  //\r
-  if (Index >= 5 && Index <= 16 && CurBBSEntry->DeviceType == BBS_HARDDISK) {\r
-    Fmt = L"%s %d";\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);\r
-  } else {\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Create a legacy boot option for the specified entry of\r
-  BBS table, save it as variable, and append it to the boot\r
-  order list.\r
-\r
-\r
-  @param CurrentBbsEntry    Pointer to current BBS table.\r
-  @param CurrentBbsDevPath  Pointer to the Device Path Protocol instance of BBS\r
-  @param Index              Index of the specified entry in BBS table.\r
-  @param BootOrderList      On input, the original boot order list.\r
-                            On output, the new boot order list attached with the\r
-                            created node.\r
-  @param BootOrderListSize  On input, the original size of boot order list.\r
-                            On output, the size of new boot order list.\r
-\r
-  @retval  EFI_SUCCESS             Boot Option successfully created.\r
-  @retval  EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
-  @retval  Other                   Error occurs while setting variable.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsCreateLegacyBootOption (\r
-  IN BBS_TABLE                        *CurrentBbsEntry,\r
-  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,\r
-  IN UINTN                            Index,\r
-  IN OUT UINT16                       **BootOrderList,\r
-  IN OUT UINTN                        *BootOrderListSize\r
-  )\r
-{\r
-  EFI_STATUS           Status;\r
-  UINT16               CurrentBootOptionNo;\r
-  UINT16               BootString[10];\r
-  UINT16               BootDesc[100];\r
-  CHAR8                HelpString[100];\r
-  UINT16               *NewBootOrderList;\r
-  UINTN                BufferSize;\r
-  UINTN                StringLen;\r
-  VOID                 *Buffer;\r
-  UINT8                *Ptr;\r
-  UINT16               CurrentBbsDevPathSize;\r
-  UINTN                BootOrderIndex;\r
-  UINTN                BootOrderLastIndex;\r
-  UINTN                ArrayIndex;\r
-  BOOLEAN              IndexNotFound;\r
-  BBS_BBS_DEVICE_PATH  *NewBbsDevPathNode;\r
-\r
-  if ((*BootOrderList) == NULL) {\r
-    CurrentBootOptionNo = 0;\r
-  } else {\r
-    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {\r
-      IndexNotFound = TRUE;\r
-      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {\r
-        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {\r
-          IndexNotFound = FALSE;\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (!IndexNotFound) {\r
-        continue;\r
-      } else {\r
-        break;\r
-      }\r
-    }\r
-\r
-    CurrentBootOptionNo = (UINT16) ArrayIndex;\r
-  }\r
-\r
-  UnicodeSPrint (\r
-    BootString,\r
-    sizeof (BootString),\r
-    L"Boot%04x",\r
-    CurrentBootOptionNo\r
-    );\r
-\r
-  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);\r
-\r
-  //\r
-  // Create new BBS device path node with description string\r
-  //\r
-  UnicodeStrToAsciiStr ((CONST CHAR16*)&BootDesc, (CHAR8*)&HelpString);\r
-\r
-  StringLen = AsciiStrLen (HelpString);\r
-  NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
-  if (NewBbsDevPathNode == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));\r
-  CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);\r
-  SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
-\r
-  //\r
-  // Create entire new CurrentBbsDevPath with end node\r
-  //\r
-  CurrentBbsDevPath = AppendDevicePathNode (\r
-                        EndDevicePath,\r
-                        (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode\r
-                        );\r
-   if (CurrentBbsDevPath == NULL) {\r
-    FreePool (NewBbsDevPathNode);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));\r
-\r
-  BufferSize = sizeof (UINT32) +\r
-    sizeof (UINT16) +\r
-    StrSize (BootDesc) +\r
-    CurrentBbsDevPathSize +\r
-    sizeof (BBS_TABLE) +\r
-    sizeof (UINT16);\r
-\r
-  Buffer = AllocateZeroPool (BufferSize);\r
-  if (Buffer == NULL) {\r
-    FreePool (NewBbsDevPathNode);\r
-    FreePool (CurrentBbsDevPath);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Ptr               = (UINT8 *) Buffer;\r
-\r
-  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;\r
-  Ptr += sizeof (UINT32);\r
-\r
-  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;\r
-  Ptr += sizeof (UINT16);\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    BootDesc,\r
-    StrSize (BootDesc)\r
-    );\r
-  Ptr += StrSize (BootDesc);\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    CurrentBbsDevPath,\r
-    CurrentBbsDevPathSize\r
-    );\r
-  Ptr += CurrentBbsDevPathSize;\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    CurrentBbsEntry,\r
-    sizeof (BBS_TABLE)\r
-    );\r
-\r
-  Ptr += sizeof (BBS_TABLE);\r
-  *((UINT16 *) Ptr) = (UINT16) Index;\r
-\r
-  Status = gRT->SetVariable (\r
-                  BootString,\r
-                  &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
-                  BufferSize,\r
-                  Buffer\r
-                  );\r
-\r
-  FreePool (Buffer);\r
-  \r
-  Buffer = NULL;\r
-\r
-  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));\r
-  if (NULL == NewBootOrderList) {\r
-    FreePool (NewBbsDevPathNode);\r
-    FreePool (CurrentBbsDevPath);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (*BootOrderList != NULL) {\r
-    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);\r
-    FreePool (*BootOrderList);\r
-  }\r
-\r
-  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof (UINT16));\r
-  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;\r
-  *BootOrderListSize += sizeof (UINT16);\r
-  *BootOrderList = NewBootOrderList;\r
-\r
-  FreePool (NewBbsDevPathNode);\r
-  FreePool (CurrentBbsDevPath);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Check if the boot option is a legacy one.\r
-\r
-  @param BootOptionVar   The boot option data payload.\r
-  @param BbsEntry        The BBS Table.\r
-  @param BbsIndex        The table index.\r
-\r
-  @retval TRUE           It is a legacy boot option.\r
-  @retval FALSE          It is not a legacy boot option.\r
-\r
-**/\r
-BOOLEAN\r
-BdsIsLegacyBootOption (\r
-  IN UINT8                 *BootOptionVar,\r
-  OUT BBS_TABLE            **BbsEntry,\r
-  OUT UINT16               *BbsIndex\r
-  )\r
-{\r
-  UINT8                     *Ptr;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  BOOLEAN                   Ret;\r
-  UINT16                    DevPathLen;\r
-\r
-  Ptr = BootOptionVar;\r
-  Ptr += sizeof (UINT32);\r
-  DevPathLen = *(UINT16 *) Ptr;\r
-  Ptr += sizeof (UINT16);\r
-  Ptr += StrSize ((UINT16 *) Ptr);\r
-  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
-  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {\r
-    Ptr += DevPathLen;\r
-    *BbsEntry = (BBS_TABLE *) Ptr;\r
-    Ptr += sizeof (BBS_TABLE);\r
-    *BbsIndex = *(UINT16 *) Ptr;\r
-    Ret       = TRUE;\r
-  } else {\r
-    *BbsEntry = NULL;\r
-    Ret       = FALSE;\r
-  }\r
-\r
-  return Ret;\r
-}\r
-\r
-/**\r
-  Delete all the invalid legacy boot options.\r
-\r
-  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.\r
-  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
-  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.\r
-**/\r
-EFI_STATUS\r
-BdsDeleteAllInvalidLegacyBootOptions (\r
-  VOID\r
+OrderLegacyBootOption4SameType (\r
+  UINT16                   *DevOrder,\r
+  UINTN                    DevOrderCount,\r
+  UINT16                   **EnBootOption,\r
+  UINTN                    *EnBootOptionCount,\r
+  UINT16                   **DisBootOption,\r
+  UINTN                    *DisBootOptionCount\r
   )\r
 {\r
-  UINT16                    *BootOrder;\r
-  UINT8                     *BootOptionVar;\r
-  UINTN                     BootOrderSize;\r
-  UINTN                     BootOptionSize;\r
-  EFI_STATUS                Status;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  BBS_TABLE                 *BbsEntry;\r
-  UINT16                    BbsIndex;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINTN                     Index;\r
-  UINT16                    BootOption[10];\r
-  UINT16                    BootDesc[100];\r
-  BOOLEAN                   DescStringMatch;\r
-\r
-  Status        = EFI_SUCCESS;\r
-  BootOrder     = NULL;\r
-  BootOrderSize = 0;\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  BbsEntry      = NULL;\r
+  EFI_STATUS               Status;\r
+  UINT16                   *NewBootOption;\r
+  UINT16                   *BootOrder;\r
+  UINTN                    BootOrderSize;\r
+  UINTN                    Index;\r
+  UINTN                    StartPosition;\r
 \r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  BDS_COMMON_OPTION        *BootOption;\r
 \r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
+  CHAR16                   OptionName[sizeof ("Boot####")];\r
+  UINT16                   *BbsIndexArray;\r
+  UINT16                   *DeviceTypeArray;\r
+  LIST_ENTRY               List;\r
 \r
   BootOrder = BdsLibGetVariableAndSize (\r
                 L"BootOrder",\r
                 &gEfiGlobalVariableGuid,\r
                 &BootOrderSize\r
                 );\r
-  if (NULL == BootOrder) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
+  ASSERT (BootOrder != NULL);\r
+\r
+  BbsIndexArray       = AllocatePool (BootOrderSize);\r
+  DeviceTypeArray     = AllocatePool (BootOrderSize);\r
+  *EnBootOption       = AllocatePool (BootOrderSize);\r
+  *DisBootOption      = AllocatePool (BootOrderSize);\r
+  *DisBootOptionCount = 0;\r
+  *EnBootOptionCount  = 0;\r
+  Index               = 0;\r
+\r
+  ASSERT (BbsIndexArray != NULL);\r
+  ASSERT (DeviceTypeArray != NULL);\r
+  ASSERT (*EnBootOption != NULL);\r
+  ASSERT (*DisBootOption != NULL);\r
+\r
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+\r
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
+    InitializeListHead (&List);\r
+    BootOption = BdsLibVariableToOption (&List, OptionName);\r
+    ASSERT (BootOption != NULL);\r
+\r
+    if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
+      //\r
+      // Legacy Boot Option\r
+      //\r
+      ASSERT (BootOption->LoadOptionsSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
 \r
-  Index = 0;\r
-  while (Index < BootOrderSize / sizeof (UINT16)) {\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      if (BootOrder != NULL) {\r
-        FreePool (BootOrder);\r
-      }\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  \r
-    //\r
-    // Skip Non-Legacy boot options\r
-    // \r
-    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {\r
-      if (BootOptionVar!= NULL) {\r
-        FreePool (BootOptionVar);\r
+      DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType;\r
+      BbsIndexArray  [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption->LoadOptions)->BbsIndex;\r
+    } else {\r
+      DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r
+      BbsIndexArray  [Index] = 0xFFFF;\r
+    }\r
+    FreePool (BootOption->DevicePath);\r
+    FreePool (BootOption->Description);\r
+    FreePool (BootOption->LoadOptions);\r
+    FreePool (BootOption);\r
+  }\r
+\r
+  //\r
+  // Record the corresponding Boot Option Numbers according to the DevOrder\r
+  // Record the EnBootOption and DisBootOption according to the DevOrder\r
+  //\r
+  StartPosition = BootOrderSize / sizeof (UINT16);\r
+  NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r
+  ASSERT (NewBootOption != NULL);\r
+  while (DevOrderCount-- != 0) {\r
+    for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+      if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r
+        StartPosition = MIN (StartPosition, Index);\r
+        NewBootOption[DevOrderCount] = BootOrder[Index];\r
+\r
+        if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
+          (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r
+          (*DisBootOptionCount)++;\r
+        } else {\r
+          (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r
+          (*EnBootOptionCount)++;\r
+        }\r
+        break;\r
       }\r
-      Index++;\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Check if BBS Description String is changed\r
-    //\r
-    DescStringMatch = FALSE;\r
-\r
-    BdsBuildLegacyDevNameString (\r
-      &LocalBbsTable[BbsIndex],\r
-      BbsIndex,\r
-      sizeof(BootDesc),\r
-      BootDesc\r
-      );\r
-\r
-    if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {\r
-      DescStringMatch = TRUE;\r
-    }\r
-\r
-    if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||\r
-          (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&\r
-        (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&\r
-        DescStringMatch) {\r
-      Index++;\r
-      continue;\r
     }\r
-\r
-    if (BootOptionVar != NULL) {\r
-      FreePool (BootOptionVar);\r
-    }\r
-    //\r
-    // should delete\r
-    //\r
-    BdsDeleteBootOption (\r
-      BootOrder[Index],\r
-      BootOrder,\r
-      &BootOrderSize\r
-      );\r
   }\r
 \r
   //\r
-  // Adjust the number of boot options.\r
+  // Overwrite the old BootOption\r
   //\r
-  if (BootOrderSize != 0) {\r
-    Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    BootOrderSize,\r
-                    BootOrder\r
-                    );\r
-  } else {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Find all legacy boot option by device type.\r
-\r
-  @param BootOrder       The boot order array.\r
-  @param BootOptionNum   The number of boot option.\r
-  @param DevType         Device type.\r
-  @param Attribute       The boot option attribute.\r
-  @param BbsIndex        The BBS table index.\r
-  @param OptionNumber    The boot option index.\r
-\r
-  @retval TRUE           The Legacy boot option is found.\r
-  @retval FALSE          The legacy boot option is not found.\r
-\r
-**/\r
-BOOLEAN\r
-BdsFindLegacyBootOptionByDevType (\r
-  IN UINT16                 *BootOrder,\r
-  IN UINTN                  BootOptionNum,\r
-  IN UINT16                 DevType,\r
-  OUT UINT32                *Attribute,\r
-  OUT UINT16                *BbsIndex,\r
-  OUT UINTN                 *OptionNumber\r
-  )\r
-{\r
-  UINTN     Index;\r
-  UINTN     BootOrderIndex;\r
-  UINT16    BootOption[100];\r
-  UINTN     BootOptionSize;\r
-  UINT8     *BootOptionVar;\r
-  BBS_TABLE *BbsEntry;\r
-  BOOLEAN   Found;\r
-\r
-  BbsEntry  = NULL;\r
-  Found     = FALSE;\r
-\r
-  if (NULL == BootOrder) {\r
-    return Found;\r
-  }\r
-\r
-  //\r
-  // Loop all boot option from variable\r
-  //\r
-  for (BootOrderIndex = 0; BootOrderIndex < BootOptionNum; BootOrderIndex++) {\r
-    Index = (UINTN) BootOrder[BootOrderIndex];\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", Index);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Skip Non-legacy boot option\r
-    //\r
-    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    if (BbsEntry->DeviceType != DevType) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    *Attribute    = *(UINT32 *) BootOptionVar;\r
-    *OptionNumber = Index;\r
-    Found         = TRUE;\r
-    FreePool (BootOptionVar);\r
-    break;\r
-  }\r
-\r
-  return Found;\r
-}\r
-\r
-/**\r
-  Create a legacy boot option.\r
-\r
-  @param BbsItem         The BBS Table entry.\r
-  @param Index           Index of the specified entry in BBS table.\r
-  @param BootOrderList   The boot order list.\r
-  @param BootOrderListSize The size of boot order list.\r
-\r
-  @retval EFI_OUT_OF_RESOURCE  No enough memory.\r
-  @retval EFI_SUCCESS          The function complete successfully.\r
-  @return Other value if the legacy boot option is not created.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsCreateOneLegacyBootOption (\r
-  IN BBS_TABLE              *BbsItem,\r
-  IN UINTN                  Index,\r
-  IN OUT UINT16             **BootOrderList,\r
-  IN OUT UINTN              *BootOrderListSize\r
-  )\r
-{\r
-  BBS_BBS_DEVICE_PATH       BbsDevPathNode;\r
-  EFI_STATUS                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
-\r
-  DevPath                       = NULL;\r
-\r
+  CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
+  Status = gRT->SetVariable (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BootOrderSize,\r
+                  BootOrder\r
+                  );\r
   //\r
-  // Create device path node.\r
+  // Changing content without increasing its size with current variable implementation shouldn't fail.\r
   //\r
-  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;\r
-  BbsDevPathNode.Header.SubType = BBS_BBS_DP;\r
-  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));\r
-  BbsDevPathNode.DeviceType = BbsItem->DeviceType;\r
-  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));\r
-\r
-  DevPath = AppendDevicePathNode (\r
-              EndDevicePath,\r
-              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode\r
-              );\r
-  if (NULL == DevPath) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = BdsCreateLegacyBootOption (\r
-            BbsItem,\r
-            DevPath,\r
-            Index,\r
-            BootOrderList,\r
-            BootOrderListSize\r
-            );\r
-  BbsItem->BootPriority = 0x00;\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  FreePool (DevPath);\r
-\r
-  return Status;\r
+  FreePool (NewBootOption);\r
+  FreePool (DeviceTypeArray);\r
+  FreePool (BbsIndexArray);\r
+  FreePool (BootOrder);\r
 }\r
 \r
 /**\r
+  Group the legacy boot options in the BootOption.\r
 \r
-  Add the legacy boot options from BBS table if they do not exist.\r
+  The routine assumes the boot options in the beginning that covers all the device\r
+  types are ordered properly and re-position the following boot options just after\r
+  the corresponding boot options with the same device type.\r
+  For example:\r
+  1. Input  = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r
+     Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r
+     Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r
 \r
-  @retval EFI_SUCCESS       The boot options are added successfully \r
-                            or they are already in boot options.\r
+  2. Input  = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r
+     Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r
+     Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r
 \r
 **/\r
-EFI_STATUS\r
-BdsAddNonExistingLegacyBootOptions (\r
+VOID\r
+GroupMultipleLegacyBootOption4SameType (\r
   VOID\r
   )\r
 {\r
-  UINT16                    *BootOrder;\r
-  UINTN                     BootOrderSize;\r
-  EFI_STATUS                Status;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  UINT16                    BbsIndex;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINTN                     Index;\r
-  UINT32                    Attribute;\r
-  UINTN                     OptionNumber;\r
-  BOOLEAN                   Ret;\r
-\r
-  BootOrder     = NULL;\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
+  EFI_STATUS                   Status;\r
+  UINTN                        Index;\r
+  UINTN                        DeviceIndex;\r
+  UINTN                        DeviceTypeIndex[7];\r
+  UINTN                        *NextIndex;\r
+  UINT16                       OptionNumber;\r
+  UINT16                       *BootOrder;\r
+  UINTN                        BootOrderSize;\r
+  CHAR16                       OptionName[sizeof ("Boot####")];\r
+  BDS_COMMON_OPTION            *BootOption;\r
+  LIST_ENTRY                   List;\r
+\r
+  SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r
 \r
   BootOrder = BdsLibGetVariableAndSize (\r
                 L"BootOrder",\r
                 &gEfiGlobalVariableGuid,\r
                 &BootOrderSize\r
                 );\r
-  if (NULL == BootOrder) {\r
-    BootOrderSize = 0;\r
-  }\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    Ret = BdsFindLegacyBootOptionByDevType (\r
-            BootOrder,\r
-            BootOrderSize / sizeof (UINT16),\r
-            LocalBbsTable[Index].DeviceType,\r
-            &Attribute,\r
-            &BbsIndex,\r
-            &OptionNumber\r
-            );\r
-    if (Ret) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Not found such type of legacy device in boot options or we found but it's disabled\r
-    // so we have to create one and put it to the tail of boot order list\r
-    //\r
-    Status = BdsCreateOneLegacyBootOption (\r
-              &LocalBbsTable[Index],\r
-              Index,\r
-              &BootOrder,\r
-              &BootOrderSize\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (BootOrderSize > 0) {\r
-    Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    BootOrderSize,\r
-                    BootOrder\r
-                    );\r
-  } else {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Fill the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsType         The BBS Type.\r
-  @param BbsCount        The BBS Count.\r
-  @param Buf             device order buffer.\r
-\r
-  @return The device order buffer.\r
-\r
-**/\r
-UINT16 *\r
-BdsFillDevOrderBuf (\r
-  IN BBS_TABLE                    *BbsTable,\r
-  IN BBS_TYPE                     BbsType,\r
-  IN UINTN                        BbsCount,\r
-  OUT UINT16                       *Buf\r
-  )\r
-{\r
-  UINTN Index;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
-      continue;\r
-    }\r
-\r
-    if (BbsTable[Index].DeviceType != BbsType) {\r
-      continue;\r
-    }\r
-\r
-    *Buf = (UINT16) (Index & 0xFF);\r
-    Buf++;\r
-  }\r
-\r
-  return Buf;\r
-}\r
-\r
-/**\r
-  Create the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsCount        The BBS Count.\r
-\r
-  @retval EFI_SUCCES     The buffer is created and the EFI variable named \r
-                         VAR_LEGACY_DEV_ORDER and EfiLegacyDevOrderGuid is\r
-                         set correctly.\r
-  @return Other value if the set of EFI variable fails. Check gRT->SetVariable\r
-          for detailed information.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsCreateDevOrder (\r
-  IN BBS_TABLE                  *BbsTable,\r
-  IN UINT16                     BbsCount\r
-  )\r
-{\r
-  UINTN       Index;\r
-  UINTN       FDCount;\r
-  UINTN       HDCount;\r
-  UINTN       CDCount;\r
-  UINTN       NETCount;\r
-  UINTN       BEVCount;\r
-  UINTN       TotalSize;\r
-  UINTN       HeaderSize;\r
-  UINT8       *DevOrder;\r
-  UINT8       *Ptr;\r
-  EFI_STATUS  Status;\r
 \r
-  FDCount     = 0;\r
-  HDCount     = 0;\r
-  CDCount     = 0;\r
-  NETCount    = 0;\r
-  BEVCount    = 0;\r
-  TotalSize   = 0;\r
-  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  DevOrder    = NULL;\r
-  Ptr         = NULL;\r
-  Status      = EFI_SUCCESS;\r
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
+    InitializeListHead (&List);\r
+    BootOption = BdsLibVariableToOption (&List, OptionName);\r
+    ASSERT (BootOption != NULL);\r
 \r
-  //\r
-  // Count all boot devices\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
-      continue;\r
-    }\r
-\r
-    switch (BbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);\r
-\r
-  //\r
-  // Create buffer to hold all boot device order\r
-  //\r
-  DevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Ptr                 = DevOrder;\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_FLOPPY;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (FDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_HARDDISK;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (HDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_CDROM;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (CDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_EMBED_NETWORK;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (NETCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_BEV_DEVICE;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (BEVCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  //\r
-  // Save device order for legacy boot device to variable.\r
-  //\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &EfiLegacyDevOrderGuid,\r
-                  VAR_FLAG,\r
-                  TotalSize,\r
-                  DevOrder\r
-                  );\r
-  FreePool (DevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-\r
-  Add the legacy boot devices from BBS table into \r
-  the legacy device boot order.\r
-\r
-  @retval EFI_SUCCESS       The boot devices are added successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsUpdateLegacyDevOrder (\r
-  VOID\r
-  )\r
-{\r
-  UINT8                     *DevOrder;\r
-  UINT8                     *NewDevOrder;\r
-  UINTN                     DevOrderSize;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  EFI_STATUS                Status;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  UINTN                     Index;\r
-  UINTN                     Index2;\r
-  UINTN                     *Idx;\r
-  UINTN                     FDCount;\r
-  UINTN                     HDCount;\r
-  UINTN                     CDCount;\r
-  UINTN                     NETCount;\r
-  UINTN                     BEVCount;\r
-  UINTN                     TotalSize;\r
-  UINTN                     HeaderSize;\r
-  UINT8                     *Ptr;\r
-  UINT8                     *NewPtr;\r
-  UINT16                    *NewFDPtr;\r
-  UINT16                    *NewHDPtr;\r
-  UINT16                    *NewCDPtr;\r
-  UINT16                    *NewNETPtr;\r
-  UINT16                    *NewBEVPtr;\r
-  UINT16                    *NewDevPtr;\r
-  UINT16                    Length;\r
-  UINT16                    Tmp;\r
-  UINTN                     FDIndex;\r
-  UINTN                     HDIndex;\r
-  UINTN                     CDIndex;\r
-  UINTN                     NETIndex;\r
-  UINTN                     BEVIndex;\r
-\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  Idx           = NULL;\r
-  FDCount       = 0;\r
-  HDCount       = 0;\r
-  CDCount       = 0;\r
-  NETCount      = 0;\r
-  BEVCount      = 0;\r
-  TotalSize     = 0;\r
-  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  FDIndex       = 0;\r
-  HDIndex       = 0;\r
-  CDIndex       = 0;\r
-  NETIndex      = 0;\r
-  BEVIndex      = 0;\r
-  NewDevPtr     = NULL;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
-\r
-  DevOrder = (UINT8 *) BdsLibGetVariableAndSize (\r
-                        VAR_LEGACY_DEV_ORDER,\r
-                        &EfiLegacyDevOrderGuid,\r
-                        &DevOrderSize\r
-                        );\r
-  if (NULL == DevOrder) {\r
-    return BdsCreateDevOrder (LocalBbsTable, BbsCount);\r
-  }\r
-  //\r
-  // First we figure out how many boot devices with same device type respectively\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));\r
-\r
-  NewDevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == NewDevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  NewFDPtr  = (UINT16 *) (NewDevOrder + HeaderSize);\r
-  NewHDPtr  = (UINT16 *) ((UINT8 *) NewFDPtr + FDCount * sizeof (UINT16) + HeaderSize);\r
-  NewCDPtr  = (UINT16 *) ((UINT8 *) NewHDPtr + HDCount * sizeof (UINT16) + HeaderSize);\r
-  NewNETPtr = (UINT16 *) ((UINT8 *) NewCDPtr + CDCount * sizeof (UINT16) + HeaderSize);\r
-  NewBEVPtr = (UINT16 *) ((UINT8 *) NewNETPtr + NETCount * sizeof (UINT16) + HeaderSize);\r
-\r
-  //\r
-  // copy FD\r
-  //\r
-  Ptr                     = DevOrder;\r
-  NewPtr                  = NewDevOrder;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY\r
-        ) {\r
-      Ptr += sizeof (UINT16);\r
-      continue;\r
-    }\r
-\r
-    NewFDPtr[FDIndex] = *(UINT16 *) Ptr;\r
-    FDIndex++;\r
-    Ptr += sizeof (UINT16);\r
-  }\r
-  //\r
-  // copy HD\r
-  //\r
-  NewPtr                  = (UINT8 *) NewHDPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK\r
-        ) {\r
-      Ptr += sizeof (UINT16);\r
-      continue;\r
-    }\r
-\r
-    NewHDPtr[HDIndex] = *(UINT16 *) Ptr;\r
-    HDIndex++;\r
-    Ptr += sizeof (UINT16);\r
-  }\r
-  //\r
-  // copy CD\r
-  //\r
-  NewPtr                  = (UINT8 *) NewCDPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_CDROM\r
-        ) {\r
-      Ptr += sizeof (UINT16);\r
-      continue;\r
-    }\r
-\r
-    NewCDPtr[CDIndex] = *(UINT16 *) Ptr;\r
-    CDIndex++;\r
-    Ptr += sizeof (UINT16);\r
-  }\r
-  //\r
-  // copy NET\r
-  //\r
-  NewPtr                  = (UINT8 *) NewNETPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK\r
-        ) {\r
-      Ptr += sizeof (UINT16);\r
-      continue;\r
-    }\r
-\r
-    NewNETPtr[NETIndex] = *(UINT16 *) Ptr;\r
-    NETIndex++;\r
-    Ptr += sizeof (UINT16);\r
-  }\r
-  //\r
-  // copy BEV\r
-  //\r
-  NewPtr                  = (UINT8 *) NewBEVPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE\r
-        ) {\r
-      Ptr += sizeof (UINT16);\r
-      continue;\r
-    }\r
-\r
-    NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;\r
-    BEVIndex++;\r
-    Ptr += sizeof (UINT16);\r
-  }\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      Idx       = &FDIndex;\r
-      NewDevPtr = NewFDPtr;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      Idx       = &HDIndex;\r
-      NewDevPtr = NewHDPtr;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      Idx       = &CDIndex;\r
-      NewDevPtr = NewCDPtr;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      Idx       = &NETIndex;\r
-      NewDevPtr = NewNETPtr;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      Idx       = &BEVIndex;\r
-      NewDevPtr = NewBEVPtr;\r
-      break;\r
-\r
-    default:\r
-      Idx = NULL;\r
-      break;\r
-    }\r
-    //\r
-    // at this point we have copied those valid indexes to new buffer\r
-    // and we should check if there is any new appeared boot device\r
-    //\r
-    if (Idx != 0) {\r
-      for (Index2 = 0; Index2 < *Idx; Index2++) {\r
-        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
-          break;\r
-        }\r
-      }\r
+    if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
+      //\r
+      // Legacy Boot Option\r
+      //\r
+      ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < ARRAY_SIZE (DeviceTypeIndex));\r
+      NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r
 \r
-      if (Index2 == *Idx) {\r
+      if (*NextIndex == (UINTN) -1) {\r
         //\r
-        // Index2 == *Idx means we didn't find Index\r
-        // so Index is a new appeared device's index in BBS table\r
-        // save it.\r
+        // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r
         //\r
-        NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);\r
-        (*Idx)++;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (FDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < FDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {\r
-        if (0 == (NewFDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewFDPtr[Index];\r
-          NewFDPtr[Index]   = NewFDPtr[Index2];\r
-          NewFDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (HDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < HDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {\r
-        if (0 == (NewHDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewHDPtr[Index];\r
-          NewHDPtr[Index]   = NewHDPtr[Index2];\r
-          NewHDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (CDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < CDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {\r
-        if (0 == (NewCDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewCDPtr[Index];\r
-          NewCDPtr[Index]   = NewCDPtr[Index2];\r
-          NewCDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (NETCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < NETIndex - 1; Index++) {\r
-      if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {\r
-        if (0 == (NewNETPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewNETPtr[Index];\r
-          NewNETPtr[Index]  = NewNETPtr[Index2];\r
-          NewNETPtr[Index2] = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (BEVCount!= 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < BEVIndex - 1; Index++) {\r
-      if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
+        *NextIndex = Index + 1;\r
+      } else {\r
+        //\r
+        // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r
+        //\r
+        OptionNumber = BootOrder[Index];\r
+        CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r
+        BootOrder[*NextIndex] = OptionNumber;\r
 \r
-      for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {\r
-        if (0 == (NewBEVPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewBEVPtr[Index];\r
-          NewBEVPtr[Index]  = NewBEVPtr[Index2];\r
-          NewBEVPtr[Index2] = Tmp;\r
-          break;\r
+        //\r
+        // Update the DeviceTypeIndex array to reflect the right shift operation\r
+        //\r
+        for (DeviceIndex = 0; DeviceIndex < ARRAY_SIZE (DeviceTypeIndex); DeviceIndex++) {\r
+          if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r
+            DeviceTypeIndex[DeviceIndex]++;\r
+          }\r
         }\r
       }\r
     }\r
+    FreePool (BootOption->DevicePath);\r
+    FreePool (BootOption->Description);\r
+    FreePool (BootOption->LoadOptions);\r
+    FreePool (BootOption);\r
   }\r
 \r
-  FreePool (DevOrder);\r
-\r
   Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &EfiLegacyDevOrderGuid,\r
-                  VAR_FLAG,\r
-                  TotalSize,\r
-                  NewDevOrder\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BootOrderSize,\r
+                  BootOrder\r
                   );\r
-  FreePool (NewDevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set Boot Priority for specified device type.\r
-\r
-  @param DeviceType      The device type.\r
-  @param LocalBbsTable   The BBS table.\r
-  @param Priority        The prority table.\r
-\r
-  @retval EFI_SUCCESS    The function completes successfully.\r
-  @retval EFI_NOT_FOUND  Failed to find device.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsSetBootPriority4SameTypeDev (\r
-  IN UINT16                                              DeviceType,\r
-  IN OUT BBS_TABLE                                       *LocalBbsTable,\r
-  IN OUT UINT16                                          *Priority\r
-  )\r
-{\r
-  UINT8   *DevOrder;\r
-\r
-  UINT8   *OrigBuffer;\r
-  UINT16  *DevIndex;\r
-  UINTN   DevOrderSize;\r
-  UINTN   DevCount;\r
-  UINTN   Index;\r
-\r
-  DevOrder = BdsLibGetVariableAndSize (\r
-              VAR_LEGACY_DEV_ORDER,\r
-              &EfiLegacyDevOrderGuid,\r
-              &DevOrderSize\r
-              );\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  OrigBuffer = DevOrder;\r
-  while (DevOrder < OrigBuffer + DevOrderSize) {\r
-    if (DeviceType == * (BBS_TYPE *) DevOrder) {\r
-      break;\r
-    }\r
-\r
-    DevOrder += sizeof (BBS_TYPE);\r
-    DevOrder += *(UINT16 *) DevOrder;\r
-  }\r
-\r
-  if (DevOrder >= OrigBuffer + DevOrderSize) {\r
-    FreePool (OrigBuffer);\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  DevOrder += sizeof (BBS_TYPE);\r
-  DevCount  = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);\r
-  DevIndex  = (UINT16 *) (DevOrder + sizeof (UINT16));\r
   //\r
-  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.\r
+  // Changing content without increasing its size with current variable implementation shouldn't fail.\r
   //\r
-  for (Index = 0; Index < DevCount; Index++) {\r
-    if ((DevIndex[Index] & 0xFF00) == 0xFF00) {\r
-      //\r
-      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;\r
-      //\r
-    } else {\r
-      LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;\r
-      (*Priority)++;\r
-    }\r
-  }\r
-\r
-  FreePool (OrigBuffer);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Print the BBS Table.\r
-\r
-  @param LocalBbsTable   The BBS table.\r
-\r
-**/\r
-VOID\r
-PrintBbsTable (\r
-  IN BBS_TABLE                      *LocalBbsTable\r
-  )\r
-{\r
-  UINT16  Idx;\r
-\r
-  DEBUG ((DEBUG_ERROR, "\n"));\r
-  DEBUG ((DEBUG_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));\r
-  DEBUG ((DEBUG_ERROR, "=============================================\n"));\r
-  for (Idx = 0; Idx < MAX_BBS_ENTRIES; Idx++) {\r
-    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
-        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    DEBUG (\r
-      (DEBUG_ERROR,\r
-      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",\r
-      (UINTN) Idx,\r
-      (UINTN) LocalBbsTable[Idx].BootPriority,\r
-      (UINTN) LocalBbsTable[Idx].Bus,\r
-      (UINTN) LocalBbsTable[Idx].Device,\r
-      (UINTN) LocalBbsTable[Idx].Function,\r
-      (UINTN) LocalBbsTable[Idx].Class,\r
-      (UINTN) LocalBbsTable[Idx].SubClass,\r
-      (UINTN) LocalBbsTable[Idx].DeviceType,\r
-      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,\r
-      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,\r
-      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,\r
-      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),\r
-      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))\r
-      );\r
-  }\r
-\r
-  DEBUG ((DEBUG_ERROR, "\n"));\r
+  ASSERT_EFI_ERROR (Status);\r
+  FreePool (BootOrder);\r
 }\r
 \r
-/**\r
-\r
-  Set the boot priority for BBS entries based on boot option entry and boot order.\r
-\r
-  @param  Entry             The boot option is to be checked for refresh BBS table.\r
-  \r
-  @retval EFI_SUCCESS       The boot priority for BBS entries is refreshed successfully.\r
-  @return status of BdsSetBootPriority4SameTypeDev()\r
-**/\r
-EFI_STATUS\r
-BdsRefreshBbsTableForBoot (\r
-  IN BDS_COMMON_OPTION        *Entry\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  UINT16                    DevType;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINTN                     Index;\r
-  UINT16                    Priority;\r
-  UINT16                    *BootOrder;\r
-  UINTN                     BootOrderSize;\r
-  UINT8                     *BootOptionVar;\r
-  UINTN                     BootOptionSize;\r
-  UINT16                    BootOption[100];\r
-  UINT8                     *Ptr;\r
-  UINT16                    DevPathLen;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
-\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  DevType       = BBS_UNKNOWN;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
-  //\r
-  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY\r
-  // We will set them according to the settings setup by user\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||\r
-        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||\r
-         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {\r
-      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
-    }\r
-  }\r
-  //\r
-  // boot priority always starts at 0\r
-  //\r
-  Priority = 0;\r
-  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {\r
-    //\r
-    // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.\r
-    //\r
-    DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;\r
-    Status = BdsSetBootPriority4SameTypeDev (\r
-              DevType,\r
-              LocalBbsTable,\r
-              &Priority\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // we have to set the boot priority for other BBS entries with different device types\r
-  //\r
-  BootOrder = (UINT16 *) BdsLibGetVariableAndSize (\r
-                          L"BootOrder",\r
-                          &gEfiGlobalVariableGuid,\r
-                          &BootOrderSize\r
-                          );\r
-  for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      continue;\r
-    }\r
-\r
-    Ptr = BootOptionVar;\r
-\r
-    Ptr += sizeof (UINT32);\r
-    DevPathLen = *(UINT16 *) Ptr;\r
-    Ptr += sizeof (UINT16);\r
-    Ptr += StrSize ((UINT16 *) Ptr);\r
-    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
-    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    Ptr += DevPathLen;\r
-    if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {\r
-      //\r
-      // We don't want to process twice for a device type\r
-      //\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    Status = BdsSetBootPriority4SameTypeDev (\r
-              ((BBS_TABLE *) Ptr)->DeviceType,\r
-              LocalBbsTable,\r
-              &Priority\r
-              );\r
-    FreePool (BootOptionVar);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  DEBUG_CODE_BEGIN();\r
-    PrintBbsTable (LocalBbsTable);\r
-  DEBUG_CODE_END();\r
-  \r
-  return Status;\r
-}\r