summaryrefslogtreecommitdiff
path: root/Core/EM/EfiOsBootOptionNames
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/EfiOsBootOptionNames
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/EfiOsBootOptionNames')
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c603
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chmbin0 -> 88779 bytes
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif14
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak123
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd118
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl286
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.unibin0 -> 6122 bytes
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c1682
8 files changed, 2826 insertions, 0 deletions
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c
new file mode 100644
index 0000000..8aea545
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c
@@ -0,0 +1,603 @@
+//#**********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.c 5 8/13/14 11:14p Walonli $
+//
+// $Revision: 5 $
+//
+// $Date: 8/13/14 11:14p $
+//***********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.c $
+//
+// 5 8/13/14 11:14p Walonli
+// [TAG] EIP180632
+// [Category] New Feature
+// [Description] Support FixedBootOrder to display Uefi OS full name
+// "Windows Boot Manager(Px: DeviceName)".
+// [Files] EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 4 5/23/14 5:08a Dukeyeh
+// [TAG] EIP167957
+// [Category] Bug Fix
+// [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+// support the "FixedBootOrder" module Boot option strings.
+// EIP159984 - Linux UEFI OS boot issue.
+// EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+// [Solution] EIP147262 =>A new token
+// "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+// EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+// EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+// of the allocated memory, NewStringLength.
+//
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+//***********************************************************************
+//***********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOptionNames.c
+//
+// Description: Change the Name of boot Option in Setup into format of
+// "OS Name(Px:HDD name)" or "OS Name(HDD name)" if there
+// is no port or "OS Name" if can't find controller name.
+//
+//<AMI_FHDR_END>
+//***********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Protocol\BlockIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\SimpleFileSystem.h>
+#include <Protocol\PDiskinfo.h>
+#include "boot.h" // Part of TSE Binary
+#include <Token.h>
+
+//
+// External variables (part of AMITSEBin)
+//
+extern UINTN gBootOptionCount;
+extern BOOT_DATA* gBootData;
+
+//
+// External functions
+//
+
+/*
+ This function locates the handle with BlockIo installed that provides block
+ access to the partition containing the Windows boot loader. The load option
+ (BootXXXX variable) created by Windows starts with a HD node instead of a
+ complete device path. The partition signature is used to find the complete
+ device path.
+
+ @param DevicePath
+
+ @retval EFI_DEVICE_PATH_PROTOCOL*
+*/
+EFI_DEVICE_PATH_PROTOCOL* _DiscoverPartition(
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+//
+// DEFINE
+//
+#define CONTROLLER_NAME_BUFFER_LENGTH 100
+
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: GetPhysicalBlockIoHandle
+//
+// Description:
+// Takes a handle with BlockIo providing partition access and returns
+// the handle with the BlockIo providing raw access to the drive that
+// contains the partition.
+//
+// Input:
+// IN EFI_HANDLE BlockIoHandle - Image handle with BlockIo partition access.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_HANDLE - Handle with BlockIo that provides raw access to drive
+// containing partition.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol()
+// DPCut()
+// LocateDevicePath()
+// FreePool()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+EFI_HANDLE GetPhysicalBlockIoHandle (
+ IN EFI_HANDLE BlockIoHandle
+)
+{
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, *Dp;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = BlockIoHandle;
+
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ if (!BlkIo->Media->LogicalPartition) return Handle;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiDevicePathProtocolGuid, &DevicePath
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ Dp=DevicePath;
+ while(BlkIo->Media->LogicalPartition){
+ EFI_DEVICE_PATH_PROTOCOL *PrevDp=Dp;
+ //We need to cut Devicepath node to get Phisycal Partition
+ Dp=DPCut(PrevDp);
+ if (PrevDp!=DevicePath) pBS->FreePool(PrevDp);
+ if (Dp == NULL) break;
+ PrevDp=Dp;
+ Status=pBS->LocateDevicePath(
+ &gEfiBlockIoProtocolGuid,&PrevDp,&Handle
+ );
+ if(EFI_ERROR(Status)) break;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if(EFI_ERROR(Status)) break;
+ }
+ if (Dp!=NULL && Dp!=DevicePath) pBS->FreePool(Dp);
+ //if physical Block I/O handle is not found, return original handle
+ return (BlkIo->Media->LogicalPartition) ? BlockIoHandle : Handle;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: RemoveTrailingSpaces
+//
+// Description:
+// Removes trailing spaces from *Name.
+//
+// Input:
+// IN CHAR16 *Name - String from which trailing spaces should be removed.
+// IN UINTN NumberOfCharacters - Length of string at *Name.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINTN - Length of string after spaces have been removed.
+//
+// Modified:
+// String pointed to by *Name.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINTN RemoveTrailingSpaces (
+ IN CHAR16 *Name,
+ IN UINTN NumberOfCharacters
+)
+{
+ //remove trailing spaces
+ while(NumberOfCharacters>0 && Name[NumberOfCharacters-1]==L' ')
+ NumberOfCharacters--;
+ Name[NumberOfCharacters]=0;
+ return NumberOfCharacters;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: ConstructBootOptionNameByHandle
+//
+// Description:
+// Construct controller name from parent Handle.
+//
+// Input:
+// IN EFI_HANDLE Handle - Handle with partition BlockIo.
+// IN CHAR16 *Name - Caller allocated string to store name in.
+// IN UINTN NameSize - Size of string buffer.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINTN - Length of controller name string.
+//
+// Modified:
+// String pointed to by *Name.
+//
+// Referrals:
+// GetPhysicalBlockIoHandle()
+// Swprintf_s()
+// RemoveTrailingSpaces()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINTN ConstructBootOptionNameByHandle (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *Name,
+ IN UINTN NameSize
+)
+{
+ CHAR16 *ControllerName;
+ UINTN NumberOfCharacters;
+
+ if (Handle == NULL) return 0;
+
+ //Name from Controller Handle
+ Handle = GetPhysicalBlockIoHandle(Handle);
+ if (!GetControllerName(Handle, &ControllerName)) return 0;
+ NumberOfCharacters = Swprintf_s(Name, NameSize, L"%s", ControllerName);
+ return RemoveTrailingSpaces(Name, NumberOfCharacters);
+}
+
+/**
+ OEM Variable, PLEASE reference SbSetup.c and modify this function to get correct port number.
+*/
+UINT16 gSATA[3][2] = {
+ { 0, 1 },
+ { 2, 3 },
+ { 4, 5 }
+};
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: GetHDDPort
+//
+// Description:
+// Use handle and EFI_DISK_INFO_PROTOCOL to get sata hard disk port.
+//
+// Input:
+// IN EFI_HANDLE - Use in locating EFI_DISK_INFO_PROTOCOL.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINT16 - Sata port number.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT16 GetHDDPort( IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath );
+
+ if( !EFI_ERROR( Status ))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *MessagingDevicePath;
+ PCI_DEVICE_PATH *PciDevicePath;
+
+ DevicePathNode = DevicePath;
+ while (!isEndNode (DevicePathNode))
+ {
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH)
+ && (DevicePathNode->SubType == HW_PCI_DP))
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ else
+ if (DevicePathNode->Type == MESSAGING_DEVICE_PATH)
+ MessagingDevicePath = DevicePathNode;
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+
+ Status = pBS->HandleProtocol ( Handle, &gEfiDiskInfoProtocolGuid, &DiskInfo );
+ if ( !EFI_ERROR(Status) )
+ {
+ Status = DiskInfo->WhichIde ( DiskInfo, &IdeChannel, &IdeDevice );
+ if( !EFI_ERROR(Status) )
+ {
+ if( MessagingDevicePath->SubType == MSG_ATAPI_DP ) //IDE mode?
+ {
+ if (PciDevicePath->Function == 5)
+ return gSATA[IdeDevice+2][IdeChannel];
+ else
+ return gSATA[IdeDevice][IdeChannel];
+ }
+ else
+ return IdeChannel; //AHCI Port Number
+ }
+ }
+ }
+ return 0xff;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: CreateNameWithUefiOS
+//
+// Description:
+// Create boot option name into format of "OS NAME(Px:HDD Name) or
+// "OS NAME(HDD Name) if there is no port or "OS_NAME" if can't find
+// controller name.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - Use in getting complete
+// device path of partition.
+// IN CHAR16 BootOptionName - Original boot option name.
+//
+// Output:
+// None.
+//
+// Returns:
+// CHAR16* - New boot option name string.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+CHAR16* CreateNameWithUefiOS( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *BootOptionName )
+{
+ EFI_STATUS Status;
+ CHAR16* NewString = NULL;
+ UINTN NewStringLength = 0;
+ BOOLEAN SupportsSimpleFileSystem = FALSE;
+ EFI_DEVICE_PATH_PROTOCOL* FullDevicePath = NULL;
+
+
+ FullDevicePath = _DiscoverPartition(DevicePath);
+
+ // Make sure that handle associated with full
+ // device path supports Simple File System.
+ if (FullDevicePath != NULL)
+ {
+ EFI_DEVICE_PATH_PROTOCOL* pTempDevicePath = FullDevicePath;
+ EFI_HANDLE TempHandle = NULL;
+
+ Status = pBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ &pTempDevicePath,
+ &TempHandle );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "Does not support Simple File System.\n"));
+ SupportsSimpleFileSystem = FALSE;
+ }
+ else
+ SupportsSimpleFileSystem = TRUE;
+
+ if ( SupportsSimpleFileSystem )
+ {
+ EFI_HANDLE BlkIoPartitionHandle = NULL;
+ EFI_HANDLE ControllerHandle = NULL;
+ CHAR16 ControllerNameBuffer[CONTROLLER_NAME_BUFFER_LENGTH];
+ UINTN ControllerNameLength = 0;
+ UINT16 PortNumber = 0;
+
+ // Locate handle with above device path..
+ Status = pBS->LocateDevicePath (
+ &gEfiBlockIoProtocolGuid,
+ &FullDevicePath,
+ &BlkIoPartitionHandle );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "LocateDevicePath: %r\n", Status));
+ return NULL;
+ }
+
+ ControllerHandle = GetPhysicalBlockIoHandle(BlkIoPartitionHandle);
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "GetPhysicalBlockIoHandle: %r\n", Status));
+ return NULL;
+ }
+
+ ControllerNameLength = ConstructBootOptionNameByHandle (
+ ControllerHandle,
+ ControllerNameBuffer,
+ CONTROLLER_NAME_BUFFER_LENGTH );
+
+ // Allocate proper memory for new string and copy updated string to it.
+ NewStringLength = Wcslen(ControllerNameBuffer) + Wcslen(BootOptionName) + 0xf;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ NewStringLength * sizeof(CHAR16),
+ &NewString );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "AllocatePool: %r\n", Status));
+ return NULL;
+ }
+
+ // Append OS name and update bootdata pointer
+ PortNumber = GetHDDPort( ControllerHandle );
+ if (PortNumber != 0xff)
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (P%d: %s)",
+ BootOptionName,
+ PortNumber,
+ ControllerNameBuffer );
+ }
+ else
+ {
+ if( ControllerNameLength == 0)
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s",
+ BootOptionName );
+ }
+ else
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (%s)",
+ BootOptionName,
+ ControllerNameBuffer );
+ }
+ }
+
+ return NewString;
+ }
+ // Could not find drive with matching partition.
+ else
+ {
+ NewStringLength = Wcslen(L" (Drive not present)") + Wcslen(BootOptionName) + 1;
+
+ Status = pBS->AllocatePool ( EfiBootServicesData,
+ NewStringLength * sizeof(CHAR16),
+ &NewString );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "AllocatePool: %r\n", Status));
+ return NULL;
+ }
+
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (Drive not present)",
+ BootOptionName );
+
+ return NewString;
+ }
+ }// if (FullDevicePath != NULL)
+ return NULL;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: ChangeUefiBootNames
+//
+// Description:
+// Examines boot options and adds drive information string to them.
+// This function is called at the ProcessEnterSetup hook provided by TSE.
+//
+// Input:
+// None.
+//
+// Output:
+// None.
+//
+// Returns:
+// None.
+//
+// Modified:
+// String used by TSE when displaying Windows Boot Manager boot options.
+//
+// Referrals:
+// _DiscoverPartition()
+// GetSataPortNumber()
+// LocateDevicePath()
+// GetPhysicalBlockIoHandle()
+// ConstructBootOptionNameByHandle()
+// Swprintf_s()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID ChangeUefiBootNames(
+ VOID
+)
+{
+ UINTN i = 0;
+
+ // Loop through all present boot options
+ for( i = 0; i < gBootOptionCount; i++ )
+ {
+ BOOT_DATA *bootData = NULL;
+
+ bootData = &(gBootData[i]);
+
+ if( bootData->DevicePath->Type == MEDIA_DEVICE_PATH
+ && bootData->DevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ CHAR16 *NewBootOptionName;
+ NewBootOptionName = CreateNameWithUefiOS( bootData->DevicePath, bootData->Name);
+ if ( NewBootOptionName )
+ {
+ bootData->Name = NewBootOptionName;
+ }
+ }
+ }//for( i = 0; i < gBootOptionCount; i++ )
+ return;
+}
+
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm
new file mode 100644
index 0000000..c972e1e
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm
Binary files differ
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif
new file mode 100644
index 0000000..c3a32e3
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "EFI OS BootOptionNames"
+ category = eModule
+ LocalRoot = "Core\EM\EfiOsBootOptionNames\"
+ RefName = "EfiOsBootOptionNames"
+[files]
+"EfiOsBootOptionNames.sdl"
+"EfiOsBootOptionNames.mak"
+"EfiOsBootOptionNames.chm"
+"EfiOsBootOptionNames.sd"
+"EfiOsBootOptionNames.uni"
+"EfiOsBootOptionNames.c"
+"EfiOsBootOrder.c"
+<endComponent>
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak
new file mode 100644
index 0000000..eab36ba
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak
@@ -0,0 +1,123 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.mak 5 3/11/15 6:48a Dukeyeh $
+#
+# $Revision: 5 $
+#
+# $Date: 3/11/15 6:48a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.mak $
+#
+# 5 3/11/15 6:48a Dukeyeh
+# [TAG] EIP178808
+# [Category] New Feature
+# [Description] Implement the selection of
+# NEW_UEFI_OS_OPTION_ORDER_POLICY item in Setup.
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOrder.c
+# EfiOsBootOptionNames.cif
+#
+# 4 3/11/15 3:47a Dukeyeh
+# [TAG] EIP204138
+# [Category] Improvement
+# [Description] Add a CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+# token to control whether create
+# "UEFI OS" boot option if can't find any other in specified file paths
+# (default) or just create it.
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOrder.c
+#
+# 3 5/23/14 5:08a Dukeyeh
+# [TAG] EIP167957
+# [Category] Bug Fix
+# [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+# support the "FixedBootOrder" module Boot option strings.
+# EIP159984 - Linux UEFI OS boot issue.
+# EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+# [Solution] EIP147262 =>A new token
+# "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+# EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+# EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+# of the allocated memory, NewStringLength.
+#
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOptionNames.chm
+# EfiOsBootOptionNames.c
+# EfiOsBootOrder.c
+# EfiOsBootOptionNames.cif
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: EfiOsBootOptionNames.mak
+#
+# Description:
+# Adds EfiOsBootOptionNames.obj to AMITSEBin dependencies
+# and builds EfiOsBootOptionNames.obj.
+#
+# Adds EfiOsBootOrder.obj to CORE_DXEBin dependencies
+# and builds EfiOsBootOrder.obj.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+#
+# EfiOsBootOrder.c
+#
+CORE_DXEBin : $(BUILD_DIR)\EfiOsBootOrder.obj
+
+$(BUILD_DIR)\EfiOsBootOrder.obj : $(EfiOsBootOptionNames_DIR)\EfiOsBootOrder.c EfiOsFilePathMapElinkList
+ $(CC) $(CFLAGS) /I$(TSEBIN_DIR)\Inc /I$(CORE_DXE_DIR) /Fo$(BUILD_DIR)\ $(EfiOsBootOptionNames_DIR)\EfiOsBootOrder.c $(BUILD_DIR)\EfiOsNamesFilePathMaps.h
+
+EfiOsFilePathMapElinkList:
+ $(SILENT)type << >$(BUILD_DIR)\EfiOsNamesFilePathMaps.h
+#define EfiOsFilePathMaps $(EfiOsBootOptionNamesFilePathItem)
+<<
+
+#
+# EfiOsBootOptionNames.c
+#
+AMITSEBin: $(BUILD_DIR)\EfiOsBootOptionNames.obj
+
+$(BUILD_DIR)\EfiOsBootOptionNames.obj : $(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.c
+ $(CC) $(CFLAGS) /I$(TSEBIN_DIR)\Inc /Fo$(BUILD_DIR)\ $(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.c
+
+#
+# SDB
+#
+SetupSdbs : $(BUILD_DIR)\EfiOsBootOptionNames.sdb
+
+$(BUILD_DIR)\EfiOsBootOptionNames.sdb : $(EfiOsBootOptionNames_DIR)\$(@B).sd $(EfiOsBootOptionNames_DIR)\$(@B).uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\$(@B).sdb $(EfiOsBootOptionNames_DIR)\$(@B).uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\$(@B).sdb -od $(BUILD_DIR)\$(@B).sdb $(EfiOsBootOptionNames_DIR)\$(@B).sd
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd
new file mode 100644
index 0000000..8f99071
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd
@@ -0,0 +1,118 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.sd 1 3/11/15 6:45a Dukeyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 3/11/15 6:45a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.sd $
+//
+// 1 3/11/15 6:45a Dukeyeh
+// [TAG] EIP178808
+// [Category] Improvement
+// [Description] Setup definition for EfiOsBootOptionNames module.
+// [Files] EfiOsBootOptionNames.sd
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOptionNames.sd
+//
+// Description: EfiOsBootOptionNames setup items
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <token.h>
+
+#ifdef SETUP_DATA_DEFINITION
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+///
+/// Put control definitions here.
+///
+
+#define EOBON_ONEOF_NEW_OPTION_POLICY\
+ oneof varid = NEW_OPTION_POLICY.NewOptionPolicy,\
+ prompt = STRING_TOKEN(STR_NEW_OPTION_POLICY),\
+ help = STRING_TOKEN(STR_NEW_OPTION_POLICY_HELP),\
+ default = NEW_UEFI_OS_OPTION_ORDER_POLICY,\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_NOT_OVERRIDE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_FIRST), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_LAST), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#endif
+
+#ifdef CONTROLS_WITH_DEFAULTS
+///
+/// List macros of all the controls attached to the actual data.
+///
+ //EOBON_ONEOF_NEW_OPTION_POLICY
+#endif
+
+#ifdef BOOT_FORM_SET
+
+ #ifdef FORM_SET_TYPEDEF
+ typedef struct {
+ UINT8 NewOptionPolicy;
+ } NEW_OPTION_POLICY;
+ #endif
+
+ #ifdef FORM_SET_VARSTORE
+ varstore NEW_OPTION_POLICY,
+ key = AUTO_ID(EOBON_NEW_OPTION_POLICY_KEY),
+ name = NewOptionPolicy,
+ guid = {0x69ECC1BE, 0xA981, 0x446D, 0x8E, 0xB6, 0xAF, 0x0E, 0x53, 0xD0, 0x6C, 0xE8}; //EFI_OS_BOOT_OPTION_NAMES_GUID
+ #endif
+
+ #ifdef FORM_SET_ITEM
+
+ EOBON_ONEOF_NEW_OPTION_POLICY
+
+ #endif //#ifdef FORM_SET_FORM
+
+#endif //#ifdef BOOT_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl
new file mode 100644
index 0000000..a4c1635
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl
@@ -0,0 +1,286 @@
+TOKEN
+ Name = "EfiOsBootOptionNames_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable EfiOsBootOptionNames support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "RemoveLegacyGptHddDevice"
+ Value = "0"
+ Help = "On. Filter GPT Format Hard disk of Legacy device."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RemoveBootOptionWithoutFile"
+ Value = "0"
+ Help = "On. Delete Boot Option when the file path in EfiOsBootOptionNamesFilePathItem doesn't exist."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BootOption_x64"
+ Value = "1"
+ Help = "Enable build support for 64 bit(x64/IA64)"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+#TOKEN
+# Name = "NORMALIZE_BOOT_OPTION_NAME"
+# Value = "0"
+# Help = "When the token is on, the Description of the existing boot options is regenerated during the boot option processing.\It is possible to override built time Description normalization policy using NormalizeBootOptionName variable."
+# TokenType = Boolean
+# TargetH = Yes
+#End
+
+#TOKEN
+# Name = "NORMALIZE_BOOT_OPTION_DEVICE_PATH"
+# Value = "0"
+# Help = "When the token is on, the FilePathList of the existing boot options is regenerated during the boot option processing.\It is possible to override built time FilePathList normalization policy using NormalizeBootOptionDevicePath variable."
+# TokenType = Boolean
+# TargetH = Yes
+#End
+
+TOKEN
+ Name = "DefaultFwBootOption"
+ Value = "1"
+ Help = "Boot Option Created by this module, 1 - FW Boot Option , 0 - Non FW Boot Option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KeepDuplicateNonFWBootOption"
+ Value = "0"
+ Help = "0 - Delete Duplicate Non FW BootOption, 1 - Leave Non FW BootOption."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "DISPLAY_FULL_OPTION_NAME_WITH_FBO"
+ Value = "1"
+ Help = "Display full boot option name with Fixed Boot Order, such as: Windows Boot Manager(P0 DeviceName)."
+ TokenType = Boolean
+ Token = "FIXED_BOOT_ORDER_SUPPORT" "=" "1"
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY"
+ Value = "0"
+ Help = "The order of new UEFI OS boot option. \0:BoTagUefi order.\1:The Highest order.\2:The Lowest order."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY"
+ Value = "1"
+ Help = "0: Create boot option by EfiOsBootOptionNamesFilePathItem, 1: Create boot option (UEFI OS) if can't find any other"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NAME_OF_UEFI_OS"
+ Value = 'L"UEFI OS"'
+ Help = "Name of UEFI OS, BootX64.efi or BootIa32.efi"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR"
+ Value = "SearchBootablePathAndCreateBootOption"
+ Help = "Name of the function pointer of type DEAL_WITH_EFI_OS_BOOT_OPTION."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR"
+ Value = "CreateTargetEfiOsBootOption"
+ Help = "Name of the function pointer of type CREATE_TARGET_EFI_OS_BOOT_OPTION."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY"
+ Value = "0"
+ Help = "To replace the Elink dependency on BcpBootOrder_SUPPORT token."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY"
+ Value = "1"
+ Help = "To replace the Elink dependency on BcpBootOrder_SUPPORT token."
+ TokenType = Integer
+ TargetH = Yes
+ Token = "BcpBootOrder_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "EfiOsBootOptionNames_DIR"
+ Help = "EfiOsBootOptionNames files source directory"
+End
+
+MODULE
+ Help = "Includes EfiOsBootOptionNames.mak to Project"
+ File = "EfiOsBootOptionNames.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\EfiOsBootOptionNames.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.sd"
+ Parent = "SETUP_DEFINITIONS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ChangeUefiBootNames,"
+ Parent = "ProcessEnterSetupHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustEfiOsBootOrder,"
+ Parent = "ReadBootOptions,"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "CreateEfiOsBootOption,"
+ Parent = "FilterBootDeviceList,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EfiOsName_NormalizeBootOptions,"
+ Parent = "NormalizeBootOptions,"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "RemoveLegacyGptHdd,"
+ Parent = "BootOptionBootDeviceFilteringFunctions"
+ Token = "RemoveLegacyGptHddDevice" "=" "1"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustNewUefiOsOptionPriority,"
+ Parent = "SetBootOptionPriorities,"
+ Token = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustNewUefiOsOptionPriority,"
+ Parent = "SetDefaultBcpBootOptionPriorities,"
+ Token = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveEfiOsBootOrder,"
+ Parent = "SaveBootOptions,"
+ InvokeOrder = AfterParent
+ Token = "DefaultFwBootOption" "=" "0"
+End
+
+ELINK
+ Name = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Microsoft\\Boot\\bootmgfw.efi), TstrW(Windows Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Suse\\elilo.efi), TstrW(Suse Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Ubuntu\\grubx64.efi), TstrW(ubuntu)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\elilo.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\grub.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\shim.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Centos\\shim.efi), TstrW(CentOS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\opensuse\\grubx64.efi), TstrW(opensuse)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\BOOT\\BOOTX64.EFI), TstrW(UEFI OS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ Token = "x64_BUILD" "=" "1"
+ Token = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\BOOT\\BOOTIA32.EFI), TstrW(UEFI OS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ Token = "x64_BUILD" "=" "0"
+ Token = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\debian\\grubx64.efi), TstrW(debian)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni
new file mode 100644
index 0000000..28afbd9
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni
Binary files differ
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c b/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c
new file mode 100644
index 0000000..32087f9
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c
@@ -0,0 +1,1682 @@
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOrder.c 24 6/11/15 2:42a Dukeyeh $
+//
+// $Revision: 24 $
+//
+// $Date: 6/11/15 2:42a $
+//***********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOrder.c $
+//
+// 24 6/11/15 2:42a Dukeyeh
+// Change IsSpecifiedUefiOsBootOptions function's comment header style
+// from AptioV to 4
+//
+// 23 4/28/15 4:55a Dukeyeh
+// [TAG] EIP213903
+// [Category] Bug Fix
+// [Severity] Normal
+// [RootCause] "UEFI OS" boot option's name/device path being
+// renormalized.
+// [Solution] "UEFI OS" boot option needs to escape name/device path
+// normalization when token CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+// is enabled (create "UEFI OS" boot option if can't find any other boot
+// file paths in table).
+// [Files] EfiOsBootOrder.c
+//
+// 22 3/11/15 6:48a Dukeyeh
+// [TAG] EIP178808
+// [Category] New Feature
+// [Description] Implement the selection of
+// NEW_UEFI_OS_OPTION_ORDER_POLICY item in Setup.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 21 3/11/15 3:47a Dukeyeh
+// [TAG] EIP204138
+// [Category] Improvement
+// [Description] Add a CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+// token to control whether create
+// "UEFI OS" boot option if can't find any other in specified file paths
+// (default) or just create it.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOrder.c
+//
+// 20 12/24/14 1:11a Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] When deleting the duplicate boot options, synchronized
+// with FIXED_BOOT_ORDER module.
+// [Files] EfiOsBootOrder.c
+//
+// 19 12/23/14 5:45a Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] Add KeepDuplicateNonFWBootOption token to determine
+// whether deletes the duplicated NON-FW boot options or not.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOrder.c
+//
+// 18 12/04/14 4:51a Dukeyeh
+// [TAG] EIP194753
+// [Category] Bug Fix
+// [RootCause] Compiler makes CHAR8 into signed value of 4 bytes in
+// comparison statement, so it fails to comparison with immediate value.
+// [Solution] Change the variable declarations of CHAR8 into UINT8.
+// [Files] EfiOsBootOrder.c
+//
+// 17 12/03/14 10:59p Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] For CppCheck error in AdjustNewUefiOsOptionPriority
+// function that Priority variable didn't have default/initialized value.
+// [Files] EfiOsBootOrder.c
+//
+// 16 11/19/14 2:22a Klzhan
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add a token to set boot option created by this module
+// is Fw Boot Option or not.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 15 9/03/14 10:41p Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] 1. Add new token for eLink dependency of
+// BcpBootOrder_SUPPORT.
+// 2. CHM file for version 10.
+// 3. Change NewEfiOsOptionDpListCount variable to zero when return.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.chm
+// EfiOsBootOrder.c
+//
+// 14 9/03/14 1:59a Dukeyeh
+// [TAG] EIP180447
+// [Category] Improvement
+// [Description] Create a token to set the priority of the boot option
+// created by Efi Os Boot Option Name.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiBootOrder.c
+//
+// 13 9/02/14 10:27p Dukeyeh
+// [TAG] EIP178318
+// [Category] Improvement
+// [Description] Sync Boot priority after remove FW Boot Option.
+// [Files] EfiOsBootOrder.c
+//
+// 12 8/13/14 11:14p Walonli
+// [TAG] EIP180632
+// [Category] New Feature
+// [Description] Support FixedBootOrder to display Uefi OS full name
+// "Windows Boot Manager(Px: DeviceName)".
+// [Files] EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 11 7/07/14 4:40a Klzhan
+// [TAG] EIPNone
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Duplicated boot option created by module
+// [RootCause] FwBootOption check is incorrect.
+//
+// 10 5/23/14 5:08a Dukeyeh
+// [TAG] EIP167957
+// [Category] Bug Fix
+// [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+// support the "FixedBootOrder" module Boot option strings.
+// EIP159984 - Linux UEFI OS boot issue.
+// EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+// [Solution] EIP147262 =>A new token
+// "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+// EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+// EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+// of the allocated memory, NewStringLength.
+//
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+//***********************************************************************
+//***********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOrder.c
+//
+// Description: Deal with UEFI Boot Devices that contain UEFI OS.
+// Create boot option if device is existed, delete
+// boot option if there is a duplicated one and then
+// adjust the BootOrder.
+//
+//<AMI_FHDR_END>
+//***********************************************************************
+
+#include <BootOptions.h>
+#include "EfiOsNamesFilePathMaps.h"
+#include <Protocol\PDiskinfo.h>
+#include <Token.h>
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+#include "Board\em\FixedBootOrder\FixedBootOrder.h"
+#endif
+
+#ifdef BootOption_x64
+#define EFI_BOOT_FILE_NAME L"\\EFI\\BOOT\\BOOTX64.EFI"
+#else
+#define EFI_BOOT_FILE_NAME L"\\EFI\\BOOT\\BOOTIA32.EFI"
+#endif
+
+#define EFI_OS_BOOT_OPTION_NAMES_GUID \
+ {0x69ECC1BE, 0xA981, 0x446D, 0x8E, 0xB6, 0xAF, 0x0E, 0x53, 0xD0, 0x6C, 0xE8}
+
+#define TstrW(s) L#s //(EIP103672+)
+
+#pragma pack(1)
+typedef struct _PARTITION_ENTRY {
+ UINT8 ActiveFlag; // Bootable or not
+ UINT8 StartingTrack; // Not used
+ UINT8 StartingCylinderLsb; // Not used
+ UINT8 StartingCylinderMsb; // Not used
+ UINT8 PartitionType; // 12 bit FAT, 16 bit FAT etc.
+ UINT8 EndingTrack; // Not used
+ UINT8 EndingCylinderLsb; // Not used
+ UINT8 EndingCylinderMsb; // Not used
+ UINT32 StartSector; // Relative sectors
+ UINT32 PartitionLength; // Sectors in this partition
+} PARTITION_ENTRY;
+
+typedef struct
+{
+ CHAR16 *FilePath;
+ CHAR16 *BootOptionName;
+}NAME_MAP;
+#pragma pack()
+
+typedef EFI_STATUS (DEAL_WITH_EFI_OS_BOOT_OPTION) (EFI_HANDLE Handle);
+extern DEAL_WITH_EFI_OS_BOOT_OPTION DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR;
+DEAL_WITH_EFI_OS_BOOT_OPTION *DealWithEfiOsBootOptionFuncPtr = DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR;
+
+typedef BOOLEAN (CREATE_TARGET_EFI_OS_BOOT_OPTION) (EFI_HANDLE Handle, NAME_MAP* NameMap);
+extern CREATE_TARGET_EFI_OS_BOOT_OPTION CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR;
+CREATE_TARGET_EFI_OS_BOOT_OPTION *CreateTargetEfiOsBootOptionFuncPtr = CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR;
+
+/**
+ Arrary of eLinks that contain many OS image paths and their corresponding OS names.
+*/
+NAME_MAP FILE_NAME_MAPS[] = { EfiOsFilePathMaps {NULL,NULL} }; //(EIP103672+)
+
+extern BOOLEAN NormalizeBootOptionName ;
+extern BOOLEAN NormalizeBootOptionDevicePath ;
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+extern EFI_HANDLE GetPhysicalBlockIoHandle (IN EFI_HANDLE BlockIoHandle) ;
+extern UINTN RemoveTrailingSpaces(CHAR16 *Name, UINTN NumberOfCharacters);
+extern UINT16 gSATA[3][2] ;
+#endif
+
+EFI_DEVICE_PATH_PROTOCOL **NewEfiOsOptionDpList = NULL ;
+UINTN NewEfiOsOptionDpListCount = 0 ;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetHdNode
+//
+// Description:
+// Locates HD node in DevicePath associated with Handle.
+//
+// Input:
+// IN EFI_HANDLE Handle - Handle with DevicePath protocol for which HD
+// node should be located.
+//
+// Output:
+// OUT EFI_DEVICE_PATH_PROTOCOL** DevPath - Pointer to HD node, if found.
+//
+// Returns:
+// EFI_SUCCESS - HD node was found and returned.
+// EFI_NOT_FOUND - No HD node was found.
+// Other errors possible if Handle does not have DevicePath protocol.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol()
+// isEndNode()
+// NEXT_NODE()
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetHdNode (
+ IN EFI_HANDLE Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL** DevPath
+)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePath;
+
+ *DevPath = NULL;
+
+ // Get DevicePath attached to handle.
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "HandleProtocol: %r\n", Status));
+ return Status;
+ }
+
+ // Find hard drive node.
+ while (!isEndNode(DevicePath)) {
+
+ if ((DevicePath->Type == MEDIA_DEVICE_PATH) &&
+ (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
+
+ *DevPath = DevicePath;
+ return EFI_SUCCESS;
+ }
+
+ DevicePath = NEXT_NODE(DevicePath);
+ }
+
+ // HD node was not found. Return error.
+ return EFI_NOT_FOUND;
+}
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetHDDPort
+//
+// Description:
+// Use handle and EFI_DISK_INFO_PROTOCOL to get sata hard disk port.
+//
+// Input:
+// IN EFI_HANDLE - Use in locating EFI_DISK_INFO_PROTOCOL.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINT16 - Sata port number.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetHDDPort( IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *MessagingDevicePath;
+ PCI_DEVICE_PATH *PciDevicePath;
+
+ DevicePathNode = DevicePath;
+ while (!isEndNode (DevicePathNode))
+ {
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH)
+ && (DevicePathNode->SubType == HW_PCI_DP))
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ else if (DevicePathNode->Type == MESSAGING_DEVICE_PATH)
+ MessagingDevicePath = DevicePathNode;
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+
+ Status = pBS->HandleProtocol ( Handle, &gEfiDiskInfoProtocolGuid, &DiskInfo );
+ if ( !EFI_ERROR(Status) )
+ {
+ Status = DiskInfo->WhichIde ( DiskInfo, &IdeChannel, &IdeDevice );
+ if ( !EFI_ERROR(Status) )
+ {
+ if ( MessagingDevicePath->SubType == MSG_ATAPI_DP ) //IDE mode?
+ {
+ if (PciDevicePath->Function == 5)
+ return gSATA[IdeDevice+2][IdeChannel];
+ else
+ return gSATA[IdeDevice][IdeChannel];
+ }
+ else
+ return IdeChannel; //AHCI Port Number
+ }
+ }
+ }
+ return 0xff;
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetGptPartitionHandle
+//
+// Description: Search GPT HDD and return Hard disk handle.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - Search GPT HDD and return Hard disk handle.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_HANDLE - Hard Disk handle or NULL.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// LocateHandleBuffer(),
+// HandleProtocol().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HANDLE GetGptPartitionHandle(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle, TempHandle = NULL;
+ UINTN Count, i;
+
+ HARDDRIVE_DEVICE_PATH* BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)DevicePath;
+
+ //get list of available Block I/O devices
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return NULL;
+
+ for( i=0; i<Count; i++ )
+ {
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath, *TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiBlockIoProtocolGuid,&BlockIo);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition)
+ continue;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&PartitionDevicePath);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)PartitionDevicePath;
+
+ for( TmpDevicePath = PartitionDevicePath;
+ !isEndNode(TmpDevicePath);
+ TmpDevicePath=NEXT_NODE(TmpDevicePath) )
+ {
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ }
+
+ //Check if our partition matches Boot partition
+ if (PartitionNode->Header.Type!=MEDIA_DEVICE_PATH || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP)
+ continue;
+
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber &&
+ PartitionNode->SignatureType==BootParitionDevicePath->SignatureType &&
+ !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16) )
+ {
+ //Match found
+ TempHandle = Handle[i];
+ break;
+ }
+ }
+
+ pBS->FreePool(Handle);
+ return TempHandle;
+}
+ //(EIP126686+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CompareHddDevicePath
+//
+// Description: Compare whether two HDD device paths are the same.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevDp1 - Device path in comparison.
+// IN EFI_DEVICE_PATH_PROTOCOL *DevDp2 - Device path in comparison.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_STATUS
+//
+// Modified:
+// None.
+//
+// Referrals:
+// MemCmp(),
+// NEXT_NODE().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CompareHddDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevDp1, EFI_DEVICE_PATH_PROTOCOL *DevDp2 )
+{
+
+ if ( DevDp1->Type == MEDIA_DEVICE_PATH &&
+ DevDp1->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ if (MemCmp(DevDp1+1, DevDp2+1, sizeof(HARDDRIVE_DEVICE_PATH)-sizeof(EFI_DEVICE_PATH_PROTOCOL)) == 0) //Skip Header EFI_DEVICE_PATH_PROTOCOL.
+ {
+ DevDp1 = NEXT_NODE(DevDp1);
+ if( DevDp1->Type == MEDIA_DEVICE_PATH &&
+ DevDp1->SubType == MEDIA_FILEPATH_DP ) Wcsupr( (CHAR16*)DevDp1+1 );
+
+ DevDp2 = NEXT_NODE(DevDp2);
+ if( DevDp2->Type == MEDIA_DEVICE_PATH &&
+ DevDp2->SubType == MEDIA_FILEPATH_DP ) Wcsupr( (CHAR16*)DevDp2+1 );
+
+ if (MemCmp(DevDp1, DevDp2, DPLength(DevDp2)) == 0)
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+ //<(EIP126686+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckBootOptionMatch
+//
+// Description: Search all BootOptionList and found out the matched HDD device path.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *HdDevPath
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckBootOptionMatch (
+ IN EFI_DEVICE_PATH_PROTOCOL* HdDevPath
+)
+{
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+
+ //(EIP126686+)>
+ if( CompareHddDevicePath(Option->FilePathList, HdDevPath) == EFI_SUCCESS )
+ return EFI_SUCCESS;
+ //<(EIP126686+)
+ }
+ return EFI_NOT_FOUND;
+}
+
+ //(EIP103672+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetEfiOsBootNameItemCount
+//
+// Description: Count the elements in eLink FILE_NAME_MAPS.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *DevicePath
+//
+// Output: EFI_HANDLE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetEfiOsBootNameItemCount(void)
+{
+ UINT16 ItemCount=0;
+
+ do{
+
+ if( FILE_NAME_MAPS[ItemCount].FilePath == NULL )
+ break;
+
+ ItemCount++;
+
+ }while(1);
+
+ return ItemCount;
+}
+ //<(EIP103672+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateTargetEfiOsBootOption
+//
+// Description: Create target efi os boot option
+//
+// Input: EFI_HANDLE FileSystemHandle - Handle to get file system
+// NAME_MAP* DevicePath - Contain boot file name and boot option name
+//
+// Output: TRUE - if find any matched boot option / create boot option successfully
+// FALSE - if one of inputs is invalid / fail to allocate pool / fail to get hdd node
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CreateTargetEfiOsBootOption(EFI_HANDLE FileSystemHandle, NAME_MAP* NameMap)
+{
+ EFI_STATUS Status;
+ UINTN OptionSize;
+ UINT8* BytePtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *HdDevPath = NULL;
+ FILEPATH_DEVICE_PATH *FpDevPath = NULL;
+ BOOT_OPTION *Option;
+
+ if(!FileSystemHandle || !NameMap)
+ return FALSE;
+
+ // Find total size of new boot option.
+ OptionSize = sizeof(HARDDRIVE_DEVICE_PATH) + // Partition node
+ sizeof(FILEPATH_DEVICE_PATH) + // FilePath node
+ ((Wcslen(NameMap->FilePath) ) * sizeof(CHAR16)) + //(EIP120976)
+ sizeof(EFI_DEVICE_PATH_PROTOCOL); //+ // End node //(EIP103870)
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ OptionSize,
+ &DevicePath);
+
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "AllocatePool %r\n", Status));
+ return FALSE;
+ }
+
+ // Get HD node of device path associated with handle.
+ Status = GetHdNode (
+ FileSystemHandle,
+ &HdDevPath );
+
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "GetHdNode: %r\n", Status));
+ pBS->FreePool(DevicePath);
+ return FALSE;
+ }
+
+ BytePtr = (UINT8*)DevicePath;
+ // Copy to FilePath.
+ MemCpy(BytePtr, HdDevPath, NODE_LENGTH(HdDevPath));
+
+ // Point to next node.
+ BytePtr += NODE_LENGTH(HdDevPath);
+ FpDevPath = (FILEPATH_DEVICE_PATH*)BytePtr;
+
+ // Set Filepath node.
+ FpDevPath->Header.Type = MEDIA_DEVICE_PATH;
+ FpDevPath->Header.SubType = MEDIA_FILEPATH_DP;
+ SET_NODE_LENGTH(&(FpDevPath->Header), 4 + (UINT16)((Wcslen(NameMap->FilePath) + 1) * sizeof(CHAR16)));
+
+ // Set Filepath PathName.
+ MemCpy(FpDevPath->PathName, NameMap->FilePath, (Wcslen(NameMap->FilePath) + 1) * sizeof(CHAR16));
+
+ // Point to next node.
+ BytePtr += NODE_LENGTH(&(FpDevPath->Header));
+ ((EFI_DEVICE_PATH_PROTOCOL*)BytePtr)->Type = END_DEVICE_PATH;
+ ((EFI_DEVICE_PATH_PROTOCOL*)BytePtr)->SubType = END_ENTIRE_SUBTYPE;
+ SET_NODE_LENGTH((EFI_DEVICE_PATH_PROTOCOL*)BytePtr, END_DEVICE_PATH_LENGTH);
+
+ // Point to signature.
+ BytePtr += END_DEVICE_PATH_LENGTH;
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+ //
+ // Uefi OS in Setup as style "OS Name(PX: DeviceName)" because of
+ // EfiOsBootOptionNames module creates it by ChangeUefiBootNames
+ // eLink to change bootData->Name, however, FixedBootOrder module
+ // creates its oneof items with BootXXXX variable's description
+ // which saved according to Option->Description, that makes only
+ // "OS Name" appear in setup, hence we need to use FixedBootOrder
+ // protocol to set new description.
+ //
+ {
+ CHAR16 *ControllerName ;
+ CHAR16 *DeviceName ;
+ UINT16 PortNumber = 0xff ;
+ UINTN NumberOfCharacters = 0, DeviceNameLength = 0;
+ EFI_HANDLE Handle ;
+ EFI_FIXED_BOOT_ORDER_PROTOCOL *Fbo = NULL ;
+ EFI_GUID FixedBootOrderGuid = FIXED_BOOT_ORDER_GUID ;
+
+ Status = pBS->LocateProtocol(&FixedBootOrderGuid, NULL, &Fbo);
+ Handle = GetPhysicalBlockIoHandle(FileSystemHandle);
+ if (GetControllerName(Handle, &ControllerName) && !EFI_ERROR(Status))
+ {
+ DeviceNameLength = (Wcslen(ControllerName)+1)*sizeof(CHAR16) ;
+ DeviceName = MallocZ(DeviceNameLength) ;
+ PortNumber = GetHDDPort( Handle );
+ NumberOfCharacters = Swprintf_s(DeviceName, DeviceNameLength, L"%s", ControllerName);
+ DeviceNameLength = RemoveTrailingSpaces(DeviceName, NumberOfCharacters);
+ if ( DeviceNameLength )
+ {
+ FBO_DEVICE_INFORM *inform ;
+ CHAR16 *String ;
+ UINTN StringLength = DeviceNameLength*sizeof(CHAR16)
+ + Wcslen(NameMap->BootOptionName)*sizeof(CHAR16)
+ + 0xf ;
+ String = MallocZ(StringLength) ;
+ if ( PortNumber != 0xff )
+ {
+ Swprintf_s ( String,
+ StringLength,
+ L"%s (P%d: %s)",
+ NameMap->BootOptionName,
+ PortNumber,
+ DeviceName );
+ TRACE((-1, "EfiOsBootOrder.c Reset the Boot Option Name:%S \n", String)) ;
+ }
+ else // It don't have port number
+ {
+ Swprintf_s ( String,
+ StringLength,
+ L"%s (%s)",
+ NameMap->BootOptionName,
+ DeviceName );
+ TRACE((-1, "EfiOsBootOrder.c Reset the Boot Option Name:%S \n", String)) ;
+ }
+
+ inform = MallocZ(sizeof(FBO_DEVICE_INFORM)) ;
+ inform->DevName = String ;
+ inform->DevPath = MallocZ(DPLength(DevicePath)) ;
+ MemCpy(inform->DevPath, DevicePath, DPLength(DevicePath)) ;
+ Status = Fbo->SetNewDescription(inform) ;
+ if (EFI_ERROR(Status))
+ TRACE((-1, "Can't set new description with fbo protocol")) ;
+ }
+ pBS->FreePool(DeviceName) ;
+ }
+ }
+#endif
+
+ if ( CheckBootOptionMatch( DevicePath ) == EFI_SUCCESS )
+ {
+ TRACE((-1,"CheckBootOptionMatch Matched.....\n" ));
+ pBS->FreePool(DevicePath);
+ return TRUE;
+ }
+
+ Option = CreateBootOption(BootOptionList);
+ Option->Attributes = LOAD_OPTION_ACTIVE; //(EIP138397)
+ Option->FwBootOption = DefaultFwBootOption;
+
+ pBS->AllocatePool (
+ EfiBootServicesData,
+ ((Wcslen(NameMap->BootOptionName) + 1) * sizeof(CHAR16)),
+ &Option->Description);
+
+ MemCpy(Option->Description,
+ NameMap->BootOptionName,
+ ((Wcslen(NameMap->BootOptionName) + 1) * sizeof(CHAR16)) );
+
+
+ Option->FilePathList = DevicePath;
+ Option->FilePathListLength = OptionSize;
+
+ {
+ VOID **ptr = NULL ;
+ ptr = MallocZ(sizeof(VOID**)
+ * (NewEfiOsOptionDpListCount+1)) ;
+ if (ptr)
+ {
+ MemCpy(ptr, NewEfiOsOptionDpList, sizeof(VOID**)
+ * NewEfiOsOptionDpListCount) ;
+ *(ptr+NewEfiOsOptionDpListCount) = Option->FilePathList ;
+
+ NewEfiOsOptionDpListCount++ ;
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ NewEfiOsOptionDpList = (EFI_DEVICE_PATH_PROTOCOL**)ptr ;
+ }
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootOptionWithUefiFileName
+//
+// Description: Create boot option with uefi file name if there is no other matched path.
+//
+// Input: EFI_HANDLE Handle - Handle to locate file system
+// UINT16 MatchedBootablePathCount - Count of matched bootable files
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateBootOptionWithUefiFileName(EFI_HANDLE Handle)
+{
+ EFI_STATUS Status;
+ EFI_FILE_PROTOCOL *FileProtocol;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem;
+
+ if(!Handle)
+ return;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem
+ );
+
+ if(!EFI_ERROR(Status))
+ {
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol
+ );
+ if(!EFI_ERROR(Status))
+ {
+ EFI_FILE_PROTOCOL* NewFileProtocol;
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ EFI_BOOT_FILE_NAME,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if(!EFI_ERROR(Status))
+ {
+ static NAME_MAP NameMap = {EFI_BOOT_FILE_NAME, NAME_OF_UEFI_OS};
+ CreateTargetEfiOsBootOptionFuncPtr(Handle, &NameMap);
+
+ NewFileProtocol->Close(NewFileProtocol);
+ }
+ }
+ }
+}
+
+/**
+ Search bootable path then create boot option.
+
+ @param Handle Handle to locate file system.
+
+ @retval EFI_SUCCESS Do not encounter any errors.
+ @retval !=EFI_SUCESS Any errors.
+**/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SearchBootablePathAndCreateBootOption
+//
+// Description: Search bootable path then create boot option.
+//
+// Input: EFI_HANDLE Handle - Handle to locate file system
+//
+// Output: EFI_SUCCESS - Do not encounter any errors
+// !=EFI_SUCCESS - Any errors
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SearchBootablePathAndCreateBootOption(EFI_HANDLE Handle)
+{
+ EFI_STATUS Status;
+ UINT16 MatchedBootablePathCount = 0;
+ UINT16 AUTO_BOOT_ENTRY_COUNT = GetEfiOsBootNameItemCount();
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem;
+ EFI_FILE_PROTOCOL *FileProtocol;
+
+ UINTN j;
+
+ if(!Handle) return EFI_INVALID_PARAMETER;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "HandleProtocol(SimpleFileSystem): %r\n", Status));
+ return Status;
+ }
+
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "OpenVolume: %r\n", Status));
+ return Status;
+ }
+
+ for (j = 0; j < AUTO_BOOT_ENTRY_COUNT; j++) {
+
+ EFI_FILE_PROTOCOL* NewFileProtocol;
+
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ FILE_NAME_MAPS[j].FilePath,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+
+ TRACE((-1, "Open(%S): %r\n", FILE_NAME_MAPS[j].FilePath, Status));
+ if (EFI_ERROR(Status)) continue;
+
+ if(CreateTargetEfiOsBootOptionFuncPtr(Handle, &FILE_NAME_MAPS[j]))
+ MatchedBootablePathCount++;
+
+ NewFileProtocol->Close(NewFileProtocol);
+ }
+
+#if CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY == 1
+ if(!MatchedBootablePathCount)
+ CreateBootOptionWithUefiFileName(Handle);
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateEfiOsBootOption
+//
+// Description: Try to find UEFI OSs and create the boot options for them if
+// they haven't been listed in BootOptionList.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS - Do not encounter any errors
+// !=EFI_SUCCESS - Any errors
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateEfiOsBootOption(VOID)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE* HandleBuffer = NULL;
+ UINTN HandleCount;
+ UINTN i;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "LocateHandleBuffer: %r\n", Status));
+ return Status;
+ }
+ // For each handle found, check if eLink files exist.
+ for (i = 0; i < HandleCount; i++) {
+
+ Status=pBS->HandleProtocol( HandleBuffer[i], &gEfiBlockIoProtocolGuid, &BlkIo );
+ if ( EFI_ERROR(Status) || BlkIo->Media->RemovableMedia ) continue; //skip removable device
+
+ DealWithEfiOsBootOptionFuncPtr(HandleBuffer[i]);
+ }
+
+ if ( HandleBuffer )
+ pBS->FreePool(HandleBuffer);
+
+ return EFI_SUCCESS;
+}
+
+ //(EIP138397+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveAmiMaskDevicePath
+//
+// Description: Remove the AMI specific device path from SrcDevicePath.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *SrcDevicePath - Device Path that has AMI
+// mask device path.
+// UINT16 DevicePathSize - Size of SrcDevicePath.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+RemoveAmiMaskDevicePath( EFI_DEVICE_PATH_PROTOCOL **SrcDevicePath, UINT16 DevicePathSize)
+{
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath = *SrcDevicePath;
+ EFI_GUID AmiMaskedDevicePathGuid = AMI_MASKED_DEVICE_PATH_GUID;
+
+ if( TmpDevicePath->Type == HARDWARE_DEVICE_PATH
+ && TmpDevicePath->SubType == HW_VENDOR_DP
+ && guidcmp(&AmiMaskedDevicePathGuid, &((VENDOR_DEVICE_PATH*)TmpDevicePath)->Guid) == 0 )
+ {
+
+ do{
+
+ if( TmpDevicePath->Type == MEDIA_DEVICE_PATH
+ && TmpDevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ *(SrcDevicePath) = TmpDevicePath;
+ break;
+ }
+ else
+ {
+ DevicePathSize -= (*(UINT16*)&(TmpDevicePath)->Length[0]);
+ TmpDevicePath = NEXT_NODE( TmpDevicePath );
+ }
+
+ }while( DevicePathSize > 0 );
+ }
+}
+ //<(EIP138397+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsOsCreatedBootOption
+//
+// Description: Check whether input boot option number is created by OS.
+//
+// Input: UINT16 BootOptionNumber - Number to check.
+//
+// Output: BOOLEAN
+// TRUE Created by OS.
+// FALSE Isn't created by OS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsOsCreatedBootOption(UINT16 BootOptionNumber)
+{
+ EFI_STATUS Status;
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+ UINT16* EfiOsBootOrder = NULL;
+ UINTN Size = 0;
+ BOOLEAN Ret = TRUE;
+
+ Status = GetEfiVariable(
+ L"EfiOsBootOrder",
+ &EfiOsBootOptionNamesGuid,
+ NULL,
+ &Size,
+ &EfiOsBootOrder);
+
+ if(!EFI_ERROR(Status))
+ {
+ UINTN i;
+
+ Size = Size/sizeof(UINT16);
+ for(i = 0; i < Size; i++)
+ {
+ if(EfiOsBootOrder[i] == BootOptionNumber)
+ {
+ Ret = FALSE;
+ break;
+ }
+ }
+
+ pBS->FreePool(EfiOsBootOrder);
+ }
+
+ return Ret;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustEfiOsBootOrder
+//
+// Description: Remove the AMI specific device path from SrcDevicePath.
+//
+// Description: if UEFI OS is existed, kill the duplicated UEFI OS boot options
+// into one and move it to one of their boot order position, and kill
+// all UEFI OS boot options if deivces are disappeared in system.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AdjustEfiOsBootOrder(VOID)
+{
+ UINT16 *NewBootOrder = NULL; //(EIP138397)
+ UINT16 BootIndex=0;
+ UINT16 *BootOrder_Flag = NULL; //(EIP138397)
+ UINT16 *BootOrder = NULL;
+ UINTN BootOrderSize = 0;
+ EFI_STATUS Status;
+ BOOLEAN UpdateBootOrder=FALSE, FwBootOption = FALSE;
+ UINTN i, j;
+ EFI_LOAD_OPTION *NvramOption = NULL;
+ UINTN NvramOptionSize;
+
+ TRACE((-1,"EfiOsBootOrder.....\n"));
+
+ Status=GetEfiVariable(
+ L"BootOrder", &EfiVariableGuid, NULL, &BootOrderSize, &BootOrder);
+
+ if (EFI_ERROR(Status)) return;
+ //(EIP138397)>
+ NewBootOrder = MallocZ( BootOrderSize );
+ if( NewBootOrder == NULL ) return;
+ BootOrder_Flag = MallocZ( BootOrderSize );
+ if( BootOrder_Flag == NULL ) return;
+ //<(EIP138397)
+ for(i=0; i<BootOrderSize/sizeof(UINT16); i++)
+ {
+ UINTN DescriptionSize;
+ EFI_DEVICE_PATH_PROTOCOL *ScrDevicePath;
+ CHAR16 BootStr[9];
+ UINT32 *OptionalData;
+ UINTN OptionalDataSize;
+#if RemoveBootOptionWithoutFile
+ EFI_HANDLE DevHandle;
+#endif
+
+ TRACE((-1,"Get Boot Option Boot%04X\n", BootOrder[i]));
+ if( BootOrder_Flag[i] ) continue; //(EIP138397)
+ FwBootOption = FALSE;
+
+ // Get Boot Option
+ NvramOption = NULL;
+ NvramOptionSize =0;
+ Swprintf(BootStr,L"Boot%04X",BootOrder[i]);
+ Status=GetEfiVariable(
+ BootStr, &EfiVariableGuid, NULL, &NvramOptionSize, &NvramOption
+ );
+ if (EFI_ERROR(Status)) continue;
+
+ DescriptionSize = (Wcslen((CHAR16*)(NvramOption+1))+1)*sizeof(CHAR16);
+ ScrDevicePath =(EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(NvramOption+1)+DescriptionSize);
+
+ OptionalData = (UINT32*)( (UINT8*)ScrDevicePath + NvramOption->FilePathListLength); //(EIP138397+)
+ OptionalDataSize = (UINT8*)NvramOption + NvramOptionSize - (UINT8*)OptionalData; //(EIP138397+)
+
+ // Check is this a non FW boot option
+ if(OptionalDataSize == sizeof(UINT32) &&
+ (*OptionalData == AMI_SIMPLE_BOOT_OPTION_SIGNATURE) ||
+ (*OptionalData == AMI_GROUP_BOOT_OPTION_SIGNATURE) )
+ FwBootOption = TRUE;
+ //(EIP138397+)>
+ RemoveAmiMaskDevicePath(&ScrDevicePath, NvramOption->FilePathListLength);
+ //<(EIP138397+)
+#if RemoveBootOptionWithoutFile
+ // Check the File exist in EfiOsBootOptionNamesFilePathItem or not.
+ // If not exist , remove the variable.
+ if(FwBootOption)
+ {
+ DevHandle = GetGptPartitionHandle(ScrDevicePath);
+
+ if(DevHandle)
+ {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem = NULL;
+ EFI_FILE_PROTOCOL *FileProtocol = NULL;
+
+ Status = pBS->HandleProtocol (
+ DevHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem);
+
+
+ if(!EFI_ERROR(Status))
+ {
+ UINTN j;
+ UINT16 AUTO_BOOT_ENTRY_COUNT = GetEfiOsBootNameItemCount();
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol);
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ for (j = 0; j < AUTO_BOOT_ENTRY_COUNT; j++)
+ {
+ EFI_FILE_PROTOCOL* NewFileProtocol = NULL;
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ EFI_BOOT_FILE_NAME,
+ EFI_FILE_MODE_READ,
+ NULL );
+
+
+ if(!EFI_ERROR(Status))
+ NewFileProtocol->Close(NewFileProtocol);
+
+ if(Status == EFI_NOT_FOUND)
+ {
+ //Clear variable Boot####
+ Status = pRS->SetVariable(
+ BootStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+ BootOrder_Flag[i] = 1;
+ pBS->FreePool(NvramOption);
+ continue;
+ }
+ }
+ }
+ }
+ }
+#endif
+ if( ScrDevicePath->Type == MEDIA_DEVICE_PATH
+ && ScrDevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ EFI_HANDLE GptHandle;
+ TRACE((-1,"EfiOsBootOrder.c :: BootOrder[%x]=%x %S\n", i, BootOrder[i], (CHAR16*)(NvramOption+1) ));
+ GptHandle = GetGptPartitionHandle(ScrDevicePath);
+ TRACE((-1,"EfiOsBootOrder.c :: GptHandle=%d\n", GptHandle));
+
+ if( GptHandle != NULL)
+ {
+ // Only Non Fw Boot Option Kill Other Boot Option
+ // This module check duplicate Boot Option exist or not when create boot option
+ // So, ignore Fw Boot Option
+ if(FwBootOption)
+ continue;
+ for(j=0; j<BootOrderSize/sizeof(UINT16); j++)
+ {
+ CHAR16 BootStr2[9];
+ UINTN NvramOptionSize2 = 0;
+ EFI_LOAD_OPTION *NvramOption2 = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
+
+ if( BootOrder_Flag[j] || (i == j)) continue;
+
+ TRACE((-1,"EfiOsBootOrder.c :: Search BootOrder[%x]=%x\n", j, BootOrder[j]));
+ // Get Boot Option
+ NvramOption2 = NULL;
+ NvramOptionSize2 =0;
+ Swprintf(BootStr2,L"Boot%04X",BootOrder[j]);
+ Status=GetEfiVariable(
+ BootStr2, &EfiVariableGuid, NULL, &NvramOptionSize2, &NvramOption2
+ );
+ if (EFI_ERROR(Status)) continue;
+
+ DescriptionSize = (Wcslen((CHAR16*)(NvramOption2+1))+1)*sizeof(CHAR16);
+ DevicePath =(EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(NvramOption2+1)+DescriptionSize);
+#if KeepDuplicateNonFWBootOption
+ OptionalData = (UINT32*)( (UINT8*)DevicePath + NvramOption2->FilePathListLength);
+ OptionalDataSize = (UINT8*)NvramOption2 + NvramOptionSize2 - (UINT8*)OptionalData;
+ TRACE((-1, "OptionalDataSize(%X)\n", (UINT8*)NvramOption2 + NvramOptionSize2 - (UINT8*)OptionalData));
+ // Skip if this is a non FW boot option
+ if(OptionalDataSize != sizeof(UINT32) ||
+ ((*OptionalData != AMI_SIMPLE_BOOT_OPTION_SIGNATURE) &&
+ (*OptionalData != AMI_GROUP_BOOT_OPTION_SIGNATURE)))
+ {
+ pBS->FreePool(NvramOption2);
+ continue;
+ }
+#endif
+ //(EIP138397+)>
+ RemoveAmiMaskDevicePath(&DevicePath, NvramOption2->FilePathListLength);
+ //<(EIP138397+)
+
+ if( CompareHddDevicePath(ScrDevicePath, DevicePath) == EFI_SUCCESS ) //(EIP126686+)
+ {
+ UINTN ReserveIndex;
+ UINTN DeleteIndex;
+ CHAR16 *DeletedStr;
+
+ TRACE((-1,"EfiOsBootOrder.c :: Matched BootOrder[%x]=%x %S\n", j, BootOrder[j], (CHAR16*)(NvramOption2+1) ));
+
+ if(!DefaultFwBootOption && !IsOsCreatedBootOption(BootOrder[i]))
+ {
+ //
+ // BootOrder[i] is not created by OS, but BootOrder[j]
+ //
+ ReserveIndex = j;
+ DeleteIndex = i;
+ DeletedStr = BootStr;
+ }
+ else
+ {
+ ReserveIndex = i;
+ DeleteIndex = j;
+ DeletedStr = BootStr2;
+ }
+ //Delete EfiOsBootOptionNames boot option.
+ //Clear variable Boot####
+ pRS->SetVariable(
+ DeletedStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+
+ BootOrder_Flag[DeleteIndex] = 1;
+ UpdateBootOrder = TRUE;
+
+#if FIXED_BOOT_ORDER_SUPPORT
+ // Handle Fixed Boot Order Priority issue.
+ {
+ UINTN DevOrderSize = 0;
+ UEFI_DEVICE_ORDER *DevOrder = NULL, *DevOrder2 = NULL;
+ EFI_GUID gFixedBootOrderGuid = FIXED_BOOT_ORDER_GUID;
+ UINTN k = 0;
+ UINT32 Attrib = 0;
+
+ Status = GetEfiVariable(L"UefiDevOrder", &gFixedBootOrderGuid, &Attrib, &DevOrderSize, &DevOrder);
+ if(!EFI_ERROR(Status))
+ {
+ DevOrder2 = DevOrder;
+
+ for (DevOrder = DevOrder2
+ ; (UINT8*)DevOrder < (UINT8*)DevOrder2 + DevOrderSize
+ ; DevOrder = (UEFI_DEVICE_ORDER*)((UINT8*)DevOrder + DevOrder->Length + sizeof(DevOrder->Type)))
+ {
+ for (k = 0; k < DEVORDER_COUNT(DevOrder); k++)
+ {
+ TRACE((-1,"DevOrder->Device[%x] %x,BootOrder[DeleteIndex] = %x \n",k,DevOrder->Device[k], BootOrder[DeleteIndex]));
+ if(DevOrder->Device[k] == BootOrder[DeleteIndex])
+ {
+ DevOrder->Device[k] = BootOrder[ReserveIndex];
+ TRACE((-1,"BootOrder[ReserveIndex] %x \n",BootOrder[ReserveIndex]));
+ }
+ }
+ }
+ Status = pRS->SetVariable(L"UefiDevOrder", &gFixedBootOrderGuid, Attrib, DevOrderSize, DevOrder2);
+ pBS->FreePool(DevOrder2);
+ }
+ }
+#endif
+ }
+
+ pBS->FreePool(NvramOption2);
+ } //for (j=0; j<BootOrderSize/sizeof(UINT16); j++)
+ } //if ( GptHandle != NULL)
+ else
+ //GPT HDD NOT FOUND, Remove This BootOrder
+ {
+ if ( (((HARDDRIVE_DEVICE_PATH*)ScrDevicePath)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) &&
+ FwBootOption)
+ {
+ //Clear variable Boot####
+ Status = pRS->SetVariable(
+ BootStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+
+ UpdateBootOrder = TRUE;
+ BootOrder_Flag[i] = 1;
+ }
+ }
+ }
+
+ pBS->FreePool(NvramOption);
+ }
+
+ if( UpdateBootOrder )
+ {
+ TRACE((-1,"EfiOsBootOrder.c :: Update BootOrder, Dump New BootOrder \n" ));
+ for(i = 0 ; i < BootOrderSize/sizeof(UINT16) ; i++)
+ {
+ if(BootOrder_Flag[i])
+ continue;
+
+ TRACE((-1,"%x ",BootOrder[i]));
+ NewBootOrder[BootIndex++] = BootOrder[i];
+ }
+ TRACE((-1,"\n "));
+ pRS->SetVariable(
+ L"BootOrder", &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, BootIndex * sizeof(UINT16), NewBootOrder);
+ }
+
+ pBS->FreePool(NewBootOrder);
+ pBS->FreePool(BootOrder);
+
+}
+
+#if (CSM_SUPPORT == 1) && (RemoveLegacyGptHddDevice == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveLegacyGptHdd
+//
+// Description: Determine whether boot device is a UEFI HDD(GPT format).
+//
+// Input: BOOT_DEVICE Device - Boot device to be checked.
+//
+// Output: TRUE - Boot Device is a UEFI HDD..
+// FALSE - Boot Device is not a UEFI HDD.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN RemoveLegacyGptHdd(BOOT_DEVICE *Device){
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_STATUS Status;
+ UINT8 *Buffer = NULL;
+ UINTN index;
+ PARTITION_ENTRY *pEntries;
+
+ if ( Device->DeviceHandle == INVALID_HANDLE
+ || Device->BbsEntry == NULL
+ ) return FALSE;
+
+ if( Device->BbsEntry->DeviceType != BBS_HARDDISK ) return FALSE;
+
+ Status=pBS->HandleProtocol(
+ Device->DeviceHandle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+
+ if (EFI_ERROR(Status) || BlkIo->Media->RemovableMedia) return FALSE; //USB device?
+
+ Status = pBS->AllocatePool( EfiBootServicesData, BlkIo->Media->BlockSize, &Buffer );
+ if( Buffer == NULL ) return FALSE;
+
+ // read the first sector
+ BlkIo->ReadBlocks ( BlkIo,
+ BlkIo->Media->MediaId,
+ 0,
+ BlkIo->Media->BlockSize,
+ (VOID*)Buffer);
+
+ if(Buffer[0x1fe]==(UINT8)0x55 && Buffer[0x1ff]==(UINT8)0xaa) //MBR Signature
+ {
+ pEntries=(PARTITION_ENTRY *)(Buffer+0x1be);
+
+ for(index=0;index<4;index++)
+ {
+ if( pEntries[index].PartitionType==0xee) //Check GPT Partition?
+ {
+ pBS->FreePool( Buffer );
+ return TRUE; //Set Can't Boot.
+ }
+ } //for(index=0;index<4;index++)
+ }//if(Buffer[0x1fe]==0x55 && Buffer[0x1ff]==0xaa)
+
+ pBS->FreePool( Buffer );
+ return FALSE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSpecifiedUefiOsBootOption
+//
+// Description: Check whether specified uefi os boot option.
+//
+// Input: BOOT_OPTION Option - boot option to check.
+//
+// Output: TRUE - Is specified uefi os boot option
+// FALSE - Isn't specified uefi os boot option
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSpecifiedUefiOsBootOption(BOOT_OPTION *Option)
+{
+ UINTN i, j;
+ NAME_MAP UefiOsNameMap[] = {{EFI_BOOT_FILE_NAME, NAME_OF_UEFI_OS}, {NULL, NULL}};
+ NAME_MAP* NameMaps[] = {
+ FILE_NAME_MAPS,
+#if CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY == 1
+ UefiOsNameMap,
+#endif
+ NULL
+ };
+
+ if(!Option) return FALSE;
+
+ if(IsLegacyBootOption(Option)) return FALSE;
+
+ for(i = 0; NameMaps[i]; i++)
+ {
+ NAME_MAP *NameMapWalker = NameMaps[i];
+ for (j = 0; NameMapWalker[j].FilePath; j++)
+ {
+ // check option name length, if OptionName < FileNameMaps, don't skip boot option
+ if ( Wcslen(Option->Description) < Wcslen(NameMapWalker[j].BootOptionName))
+ continue ;
+ // check option string
+ if ( !MemCmp( Option->Description, NameMapWalker[j].BootOptionName,
+ Wcslen(NameMapWalker[j].BootOptionName)*sizeof(CHAR16)))
+ {
+ // check option device path.
+ EFI_DEVICE_PATH_PROTOCOL *Dp = Option->FilePathList ;
+ BOOLEAN HardDriveFlag=FALSE, MediaFilePathFlag=FALSE ;
+ while(!isEndNode(Dp))
+ {
+ if (Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_HARDDRIVE_DP)
+ HardDriveFlag = TRUE ;
+ if (Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_FILEPATH_DP)
+ MediaFilePathFlag = TRUE ;
+ Dp = NEXT_NODE(Dp) ;
+ }
+
+ if (HardDriveFlag && MediaFilePathFlag)
+ {
+ TRACE((-1,"%S don't normalize.\n", Option->Description )) ;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiOsName_NormalizeBootOptions
+//
+// Description: If normalization is enabled, regenerates all the description strings
+// and/or file path lists. This function override BDS kernel, because Uefi
+// Os Boot Option can't be normalize file path and names.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EfiOsName_NormalizeBootOptions(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ // Normalize boot options
+ //(regenerate the description string and the file path list)
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+
+ if ( !Option->FwBootOption || !IsBootOptionWithDevice(Option)
+ || Option->BootOptionNumber == INVALID_BOOT_OPTION_NUMBER
+ ) continue;
+
+ // Skip Uefi Hdd Os boot option
+ if (IsSpecifiedUefiOsBootOption(Option)) continue ;
+
+ if (NormalizeBootOptionDevicePath){
+ EFI_DEVICE_PATH_PROTOCOL *OldFilePathList = Option->FilePathList;
+ UINTN OldFilePathListLength = Option->FilePathListLength;
+ Option->FilePathList = NULL;
+ Option->FilePathListLength = 0;
+ BuildBootOptionFilePath(Option);
+ if (Option->FilePathList == NULL){
+ Option->FilePathList = OldFilePathList;
+ Option->FilePathListLength = OldFilePathListLength;
+ }else if (OldFilePathList != NULL){
+ pBS->FreePool(OldFilePathList);
+ }
+ }
+ if (NormalizeBootOptionName){
+ CHAR16 *OldDescription = Option->Description;
+ Option->Description = NULL;
+ ConstructBootOptionName(Option);
+ if (Option->Description == NULL)
+ Option->Description = OldDescription;
+ else if (OldDescription != NULL)
+ pBS->FreePool(OldDescription);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustNewUefiOsOptionPriority
+//
+// Description: Adjust new UEFI OS boot option priority.
+// Follow the policy NEW_UEFI_OS_OPTION_ORDER_POLICY
+// to change priority with new UEFI OS boot option.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AdjustNewUefiOsOptionPriority()
+{
+ EFI_STATUS Status;
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINTN Size;
+ UINTN x = 0;
+ UINT32 Priority = 0;
+ UINT8 NewOptionPolicy;
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+
+ TRACE((-1,"EfiOsBootOrder.c : Update new Uefi OS option priority\n")) ;
+
+ // if no new EFI OS boot option added, just return.
+ if (!NewEfiOsOptionDpListCount) return ;
+
+ Size = sizeof (UINT8);
+ Status = pRS->GetVariable (
+ L"NewOptionPolicy",
+ &EfiOsBootOptionNamesGuid,
+ NULL,
+ &Size,
+ (VOID *) &NewOptionPolicy
+ );
+
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ return;
+ }
+
+ if (NewOptionPolicy == 0)
+ {
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ return;
+ }
+ else if (NewOptionPolicy == 1)
+ {
+ Priority = LOWEST_BOOT_OPTION_PRIORITY ;
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->Priority < Priority)
+ Priority = Option->Priority ;
+ Option->Priority += (UINT32)NewEfiOsOptionDpListCount ;
+ }
+ }
+ else if (NewOptionPolicy == 2)
+ {
+ Priority = 0 ;
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->Priority > Priority)
+ Priority = Option->Priority + 1 ;
+ }
+ }
+
+ for ( x=0 ; x<NewEfiOsOptionDpListCount ; x++ )
+ {
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+
+ Dp = *(NewEfiOsOptionDpList+x);
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->FilePathList == Dp)
+ Option->Priority = Priority++ ;
+ }
+ }
+ NewEfiOsOptionDpListCount = 0 ;
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveEfiOsBootOrder
+//
+// Description: Save the boot order to check later,
+// then we can know which one is created by OS.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SaveEfiOsBootOrder()
+{
+ EFI_STATUS Status;
+ UINTN BootOrderSize = 0;
+ UINT16* BootOrder = NULL;
+
+ Status = GetEfiVariable(
+ L"BootOrder",
+ &EfiVariableGuid,
+ NULL,
+ &BootOrderSize,
+ &BootOrder);
+
+ if(!EFI_ERROR(Status))
+ {
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+
+ pRS->SetVariable(
+ L"EfiOsBootOrder",
+ &EfiOsBootOptionNamesGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ BootOrderSize,
+ (VOID*)BootOrder);
+
+ pBS->FreePool(BootOrder);
+ }
+}
+
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************