4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function deal with the legacy boot option, it create, delete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and manage the legacy boot option, all legacy boot option is getting from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the legacy BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "BBSsupport.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOT_OPTION_BBS_MAPPING *mBootOptionBbsMapping = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINTN mBootOptionBbsMappingCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Translate the first n characters of an Ascii string to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Unicode characters. The count n is indicated by parameter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Size. If Size is greater than the length of string, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the entire string is translated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param AStr Pointer to input Ascii string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The number of characters to translate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param UStr Pointer to output Unicode string buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAsciiToUnicodeSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *AStr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *UStr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Idx;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (AStr[Idx] != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UStr[Idx] = (CHAR16) AStr[Idx];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Idx == Size) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UStr[Idx] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build Legacy Device Name String according.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurBBSEntry BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BufSize The buffer size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootString The output string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsBuildLegacyDevNameString (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *CurBBSEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN BufSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT CHAR16 *BootString
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 *Fmt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 *Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *StringDesc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 Temp[80];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Index) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Primary Master
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"Primary Master %s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Primary Slave
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"Primary Slave %s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Secondary Master
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 3:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"Secondary Master %s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Secondary Slave
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 4:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"Secondary Slave %s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"%s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (CurBBSEntry->DeviceType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_FLOPPY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"Floppy";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_HARDDISK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"Harddisk";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_CDROM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"CDROM";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_PCMCIA:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"PCMCIAe";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_USB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"USB";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_EMBED_NETWORK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"Network";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_BEV_DEVICE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"BEVe";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_UNKNOWN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = L"Unknown";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If current BBS entry has its description then use it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL != StringDesc) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only get fisrt 32 characters, this is suggested by BBS spec
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiToUnicodeSize (StringDesc, 32, Temp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"%s";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = Temp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BbsTable 16 entries are for onboard IDE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fmt = L"%s %d";
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootString, BufSize, Fmt, Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a legacy boot option for the specified entry of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS table, save it as variable, and append it to the boot
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurrentBbsEntry Pointer to current BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index of the specified entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderList On input, the original boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On output, the new boot order list attached with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync created node.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderListSize On input, the original size of boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On output, the size of new boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Boot Option successfully created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Error occurs while setting variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsCreateLegacyBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *CurrentBbsEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *CurrentBbsDevPath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT16 **BootOrderList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINTN *BootOrderListSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CurrentBootOptionNo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BootString[10];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 BootDesc[100];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 HelpString[100];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewBootOrderList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN StringLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *Buffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CurrentBbsDevPathSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOrderIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOrderLastIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN ArrayIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IndexNotFound;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_BBS_DEVICE_PATH *NewBbsDevPathNode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*BootOrderList) == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBootOptionNo = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IndexNotFound = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IndexNotFound = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IndexNotFound) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBootOptionNo = (UINT16) ArrayIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootString,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (BootString),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"Boot%04x",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBootOptionNo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create new BBS device path node with description string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeStrToAsciiStr (BootDesc, HelpString);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StringLen = AsciiStrLen (HelpString);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NewBbsDevPathNode == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create entire new CurrentBbsDevPath with end node
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPath = AppendDevicePathNode (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndDevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CurrentBbsDevPath == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (NewBbsDevPathNode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferSize = sizeof (UINT32) +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (UINT16) +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StrSize (BootDesc) +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPathSize +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (BBS_TABLE) +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer = AllocateZeroPool (BufferSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Buffer == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (NewBbsDevPathNode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (CurrentBbsDevPath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (UINT8 *) Buffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT32);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT16 *) Ptr) = CurrentBbsDevPathSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootDesc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StrSize (BootDesc)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += StrSize (BootDesc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPathSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += CurrentBbsDevPathSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (BBS_TABLE)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (BBS_TABLE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT16 *) Ptr) = (UINT16) Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->SetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootString,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_FLAG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == NewBootOrderList) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (NewBbsDevPathNode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (CurrentBbsDevPath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*BootOrderList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (*BootOrderList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BootOrderListSize += sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BootOrderList = NewBootOrderList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (NewBbsDevPathNode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (CurrentBbsDevPath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the boot option is a legacy one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionVar The boot option data payload.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsEntry The BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The table index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE It is a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE It is not a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsIsLegacyBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *BootOptionVar,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BBS_TABLE **BbsEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *BbsIndex
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_PATH_PROTOCOL *DevicePath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 DevPathLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT32);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPathLen = *(UINT16 *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += StrSize ((UINT16 *) Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += DevPathLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BbsEntry = (BBS_TABLE *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (BBS_TABLE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BbsIndex = *(UINT16 *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ret = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BbsEntry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ret = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ret;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Re-order the Boot Option according to the DevOrder.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The routine re-orders the Boot Option in BootOption array according to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the order specified by DevOrder.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOption Pointer to buffer containing the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionCount Count of the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevOrder Pointer to buffer containing the BBS Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync high 8-bit value 0xFF indicating a disabled boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevOrderCount Count of the BBS Index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EnBootOption Pointer to buffer receiving the enabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EnBootOptionCount Count of the enabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DisBootOption Pointer to buffer receiving the disabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DisBootOptionCount Count of the disabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOrderLegacyBootOption4SameType (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOptionCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *DevOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DevOrderCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *EnBootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN *EnBootOptionCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *DisBootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN *DisBootOptionCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN MappingIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewBootOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *DisBootOptionCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *EnBootOptionCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsType = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record the corresponding Boot Option Numbers according to the DevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record the EnBootOption and DisBootOption according to the DevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (NewBootOption != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (DevOrderCount-- != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < mBootOptionBbsMappingCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[Index].BbsIndex == (DevOrder[DevOrderCount] & 0xFF)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsType = mBootOptionBbsMapping[Index].BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOption[DevOrderCount] = mBootOptionBbsMapping[Index].BootOptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DisBootOption[*DisBootOptionCount] = NewBootOption[DevOrderCount];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*DisBootOptionCount)++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EnBootOption[*EnBootOptionCount] = NewBootOption[DevOrderCount];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*EnBootOptionCount)++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BootOptionCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the start position for the BbsType in BootOption
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[MappingIndex].BbsType == BbsType && mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Overwrite the old BootOption
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MappingIndex < mBootOptionBbsMappingCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BootOption[Index], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Group the legacy boot options in the BootOption.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The routine assumes the boot options in the beginning that covers all the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync types are ordered properly and re-position the following boot options just after
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the corresponding boot options with the same device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync For example:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOption Pointer to buffer containing Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionCount Count of the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGroupMultipleLegacyBootOption4SameType (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOptionCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DeviceTypeIndex[7];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN MappingIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN *NextIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 OptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DeviceIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BootOptionCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the DeviceType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MappingIndex == mBootOptionBbsMappingCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Is not a legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((mBootOptionBbsMapping[MappingIndex].BbsType & 0xF) <
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextIndex = &DeviceTypeIndex[mBootOptionBbsMapping[MappingIndex].BbsType & 0xF];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*NextIndex == (UINTN) -1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *NextIndex is the index in BootOption to put the next Option Number for the same type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *NextIndex = Index + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionNumber = BootOption[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BootOption[*NextIndex + 1], &BootOption[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOption[*NextIndex] = OptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the DeviceTypeIndex array to reflect the right shift operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceTypeIndex[DeviceIndex]++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delete all the invalid legacy boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS All invalide legacy boot options are deleted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsDeleteAllInvalidLegacyBootOptions (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *BootOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOrderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOptionSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 HddCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDD_INFO *LocalHddInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *LocalBbsTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *BbsEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BootOption[10];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BootDesc[100];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN DescStringMatch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HddCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalHddInfo = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsEntry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios->GetBbsInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &HddCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalHddInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BbsCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrder == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Index < BootOrderSize / sizeof (UINT16)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOptionVar = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOptionSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == BootOptionVar) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOptionSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->GetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOptionSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOptionVar
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_NOT_FOUND) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update BootOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsDeleteBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder[Index],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip Non-Legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOptionVar!= NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsIndex < BbsCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check if BBS Description String is changed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DescStringMatch = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsBuildLegacyDevNameString (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable[BbsIndex],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (BootDesc),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootDesc
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DescStringMatch = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DescStringMatch) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOptionVar != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // should delete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsDeleteBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder[Index],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Adjust the number of boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrderSize != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->SetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_FLAG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrder != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find all legacy boot option by device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrder The boot order array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionNum The number of boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevType Device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevName Device name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Attribute The boot option attribute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The BBS table index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param OptionNumber The boot option index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The Legacy boot option is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The legacy boot option is not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsFindLegacyBootOptionByDevTypeAndName (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 *BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN BootOptionNum,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 DevType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN CHAR16 *DevName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *Attribute,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *BbsIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *OptionNumber
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 BootOption[9];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOptionSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *BbsEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Found;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsEntry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Found = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == BootOrder) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Found;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop all boot option from variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BootOptionNum; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOptionVar = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOptionSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == BootOptionVar) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip Non-legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BbsEntry->DeviceType != DevType) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Attribute = *(UINT32 *) BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OptionNumber = BootOrder[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Found = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Found;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsItem The BBS Table entry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index of the specified entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderList The boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderListSize The size of boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCE No enough memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Other value if the legacy boot option is not created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsCreateOneLegacyBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *BbsItem,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT16 **BootOrderList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINTN *BootOrderListSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_BBS_DEVICE_PATH BbsDevPathNode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_PATH_PROTOCOL *DevPath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPath = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create device path node.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsDevPathNode.Header.Type = BBS_DEVICE_PATH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsDevPathNode.Header.SubType = BBS_BBS_DP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsDevPathNode.DeviceType = BbsItem->DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPath = AppendDevicePathNode (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndDevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == DevPath) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = BdsCreateLegacyBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsItem,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderListSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsItem->BootPriority = 0x00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (DevPath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add the legacy boot options from BBS table if they do not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot options are added successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or they are already in boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND No legacy boot options is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCE No enough memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Other value LegacyBoot options are not added.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsAddNonExistingLegacyBootOptions (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *BootOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOrderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 Desc[100];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 HddCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDD_INFO *LocalHddInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *LocalBbsTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Attribute;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 OptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Exist;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HddCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalHddInfo = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (mBootOptionBbsMapping);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMappingCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios->GetBbsInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &HddCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalHddInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BbsCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrder == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Exist = BdsFindLegacyBootOptionByDevTypeAndName (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize / sizeof (UINT16),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Index].DeviceType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Desc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Attribute,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BbsIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &OptionNumber
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Exist) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Not found such type of legacy device in boot options or we found but it's disabled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so we have to create one and put it to the tail of boot order list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = BdsCreateOneLegacyBootOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable[Index],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsIndex = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (BbsIndex == Index);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the BbsIndex
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping = ReallocatePool (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMappingCount * sizeof (BOOT_OPTION_BBS_MAPPING),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (mBootOptionBbsMappingCount + 1) * sizeof (BOOT_OPTION_BBS_MAPPING),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (mBootOptionBbsMapping != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BootOptionNumber = OptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsIndex = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsType = LocalBbsTable[Index].DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMappingCount ++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Group the Boot Option Number in BootOrder for the same type devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GroupMultipleLegacyBootOption4SameType (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize / sizeof (UINT16)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrderSize > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->SetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_FLAG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrder != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fill the device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsType The BBS Type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The BBS Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Buf device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16 *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsFillDevOrderBuf (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *BbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TYPE BbsType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN BbsCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *Buf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsTable[Index].DeviceType != BbsType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Buf = (UINT16) (Index & 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buf++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Buf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create the device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The BBS Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The buffer is created and the EFI variable named
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync set correctly.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync because of hardware error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsCreateDevOrder (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *BbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 BbsCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN FDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN HDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN CDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN NETCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BEVCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN HeaderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *DevOrderPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrder = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Count all boot devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (BbsTable[Index].DeviceType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_FLOPPY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_HARDDISK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_CDROM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_EMBED_NETWORK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_BEV_DEVICE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create buffer to hold all boot device order
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrder = AllocateZeroPool (TotalSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == DevOrder) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->BbsType = BBS_FLOPPY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->BbsType = BBS_HARDDISK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->BbsType = BBS_CDROM;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->BbsType = BBS_EMBED_NETWORK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->BbsType = BBS_BEV_DEVICE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save device order for legacy boot device to variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->SetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiLegacyDevOrderVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_FLAG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (DevOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add the legacy boot devices from BBS table into
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the legacy device boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot devices are added successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The legacy boot devices are not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync because of hardware error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsUpdateLegacyDevOrder (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *NewDevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *NewPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DevOrderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 HddCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDD_INFO *LocalHddInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *LocalBbsTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN *Idx;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN FDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN HDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN CDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN NETCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BEVCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN HeaderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewFDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewHDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewCDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewNETPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewBEVPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *NewDevPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN FDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN HDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN CDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN NETIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BEVIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = LegacyBios->GetBbsInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &HddCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalHddInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BbsCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrder = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiLegacyDevOrderVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &DevOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == DevOrder) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return BdsCreateDevOrder (LocalBbsTable, BbsCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First we figure out how many boot devices with same device type respectively
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (LocalBbsTable[Index].DeviceType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_FLOPPY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_HARDDISK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_CDROM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_EMBED_NETWORK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_BEV_DEVICE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevOrder = AllocateZeroPool (TotalSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == NewDevOrder) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy FD
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = NewDevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->BbsType = Ptr->BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Data[FDIndex] = Ptr->Data[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDIndex++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewFDPtr = NewPtr->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy HD
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->BbsType = Ptr->BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Data[HDIndex] = Ptr->Data[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDIndex++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewHDPtr = NewPtr->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy CD
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->BbsType = Ptr->BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Data[CDIndex] = Ptr->Data[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDIndex++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewCDPtr = NewPtr->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy NET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->BbsType = Ptr->BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Data[NETIndex] = Ptr->Data[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NETIndex++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewNETPtr = NewPtr->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy BEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->BbsType = Ptr->BbsType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Data[BEVIndex] = Ptr->Data[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BEVIndex++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBEVPtr = NewPtr->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (LocalBbsTable[Index].DeviceType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_FLOPPY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = &FDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NewFDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_HARDDISK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = &HDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NewHDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_CDROM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = &CDIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NewCDPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_EMBED_NETWORK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = &NETIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NewNETPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case BBS_BEV_DEVICE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = &BEVIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr = NewBEVPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Idx = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // at this point we have copied those valid indexes to new buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and we should check if there is any new appeared boot device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Idx != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index2 = 0; Index2 < *Idx; Index2++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index2 == *Idx) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Index2 == *Idx means we didn't find Index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so Index is a new appeared device's index in BBS table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // insert it before disabled indexes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index2 = 0; Index2 < *Idx; Index2++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevPtr[Index2] = (UINT16) (Index & 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Idx)++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (DevOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gRT->SetVariable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiLegacyDevOrderVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_FLAG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewDevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (NewDevOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set Boot Priority for specified device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DeviceType The device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The BBS index to set the highest priority. Ignore when -1.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param LocalBbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Priority The prority table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completes successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Failed to find device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsSetBootPriority4SameTypeDev (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 DeviceType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN BbsIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT BBS_TABLE *LocalBbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT16 *Priority
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LEGACY_DEV_ORDER_ENTRY *DevOrderPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DevOrderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrder = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiLegacyDevOrderVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &DevOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == DevOrder) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = DevOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DevOrderPtr->BbsType == DeviceType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINT8 *) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (DevOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsIndex != (UINTN) -1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[BbsIndex].BootPriority = *Priority;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Priority)++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (DevOrderPtr->Data[Index] != BbsIndex) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Priority)++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (DevOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Print the BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param LocalBbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The count of entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPrintBbsTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BBS_TABLE *LocalBbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 BbsCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Idx;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, "\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, "=============================================\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Idx = 0; Idx < BbsCount; Idx++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) Idx,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].BootPriority,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].Bus,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].Device,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].Function,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].Class,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].SubClass,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].DeviceType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, "\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set the boot priority for BBS entries based on boot option entry and boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Entry The boot option is to be checked for refresh BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND BBS entries can't be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBdsRefreshBbsTableForBoot (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BDS_COMMON_OPTION *Entry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 HddCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BbsCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HDD_INFO *LocalHddInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS_TABLE *LocalBbsTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 DevType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Priority;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *BootOrder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOrderSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootOptionSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR16 BootOption[9];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 DevPathLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_PATH_PROTOCOL *DevPath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DeviceTypeCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN DeviceTypeIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HddCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalHddInfo = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType = BBS_UNKNOWN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios->GetBbsInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LegacyBios,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &HddCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalHddInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BbsCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &LocalBbsTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We will set them according to the settings setup by user
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BbsCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // boot priority always starts at 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Priority = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = BdsSetBootPriority4SameTypeDev (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Priority
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // we have to set the boot priority for other BBS entries with different device types
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrder = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOrderSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (DeviceType != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceType[0] = DevType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceTypeCount = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOptionVar = BdsLibGetVariableAndSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiGlobalVariableGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &BootOptionSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == BootOptionVar) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = BootOptionVar;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT32);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPathLen = *(UINT16 *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += sizeof (UINT16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += StrSize ((UINT16 *) Ptr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr += DevPathLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType = ((BBS_TABLE *) Ptr)->DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeviceType[DeviceTypeIndex] == DevType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeviceTypeIndex < DeviceTypeCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We don't want to process twice for a device type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceType[DeviceTypeCount] = DevType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceTypeCount++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = BdsSetBootPriority4SameTypeDev (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) -1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Priority
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOptionVar);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BootOrder != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (BootOrder);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_BEGIN();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrintBbsTable (LocalBbsTable, BbsCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_END();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}