]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
IntelFrameworkModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BBSsupport.c
index 94261a0bef5824ed75e7e32a48fdb9a691bfb033..7ba4fa2ab84f0f1e84813bf7230be6abccd46b6f 100644 (file)
   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
-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
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \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
+  EFI_STATUS               Status;\r
+  UINT16                   *NewBootOption;\r
+  UINT16                   *BootOrder;\r
+  UINTN                    BootOrderSize;\r
+  UINTN                    Index;\r
+  UINTN                    StartPosition;\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
+  BDS_COMMON_OPTION        *BootOption;\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
+  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
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = BdsCreateLegacyBootOption (\r
-            BbsItem,\r
-            DevPath,\r
-            Index,\r
-            BootOrderList,\r
-            BootOrderListSize\r
-            );\r
-  BbsItem->BootPriority = 0x00;\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
-\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
+  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
-    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