Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu...@intel.com>
Cc: Feng Tian <feng.t...@intel.com>
Cc: Siyuan Fu <siyuan...@intel.com>
---
 MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c   | 576 --------------------
 .../Library/UefiBootManagerLib/BmBootDescription.c | 586 +++++++++++++++++++++
 .../Library/UefiBootManagerLib/InternalBm.h        |  69 +--
 .../UefiBootManagerLib/UefiBootManagerLib.inf      |   3 +-
 4 files changed, 613 insertions(+), 621 deletions(-)
 create mode 100644 MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c

diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c 
b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
index 18f835a..0b86cb9 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
@@ -15,19 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "InternalBm.h"
 
-#define VENDOR_IDENTIFICATION_OFFSET     3
-#define VENDOR_IDENTIFICATION_LENGTH     8
-#define PRODUCT_IDENTIFICATION_OFFSET    11
-#define PRODUCT_IDENTIFICATION_LENGTH    16
-
-CONST UINT16 mBmUsbLangId    = 0x0409; // English
-CHAR16       mBmUefiPrefix[] = L"UEFI ";
-
 EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION  mBmRefreshLegacyBootOption = NULL;
 EFI_BOOT_MANAGER_LEGACY_BOOT                 mBmLegacyBoot              = NULL;
 
-LIST_ENTRY mPlatformBootDescriptionHandlers = INITIALIZE_LIST_HEAD_VARIABLE 
(mPlatformBootDescriptionHandlers);
-
 ///
 /// This GUID is used for an EFI Variable that stores the front device pathes
 /// for a partial device path that starts with the HD node.
@@ -75,107 +65,6 @@ BmIsAutoCreateBootOption (
 }
 
 /**
-  For a bootable Device path, return its boot type.
-
-  @param  DevicePath                   The bootable device Path to check
-
-  @retval AcpiFloppyBoot               If given device path contains 
ACPI_DEVICE_PATH type device path node
-                                       which HID is floppy device.
-  @retval MessageAtapiBoot             If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_ATAPI_DP.
-  @retval MessageSataBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_SATA_DP.
-  @retval MessageScsiBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_SCSI_DP.
-  @retval MessageUsbBoot               If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_USB_DP.
-  @retval MessageNetworkBoot           If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_MAC_ADDR_DP, MSG_VLAN_DP,
-                                       MSG_IPv4_DP or MSG_IPv6_DP.
-  @retval MessageHttpBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
-                                       and its last device path node's subtype 
is MSG_URI_DP.
-  @retval UnsupportedBoot              If tiven device path doesn't match the 
above condition, it's not supported.
-
-**/
-BM_BOOT_TYPE
-BmDevicePathType (
-  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
-  )
-{
-  EFI_DEVICE_PATH_PROTOCOL      *Node;
-  EFI_DEVICE_PATH_PROTOCOL      *NextNode;
-
-  ASSERT (DevicePath != NULL);
-
-  for (Node = DevicePath; !IsDevicePathEndType (Node); Node = 
NextDevicePathNode (Node)) {
-    switch (DevicePathType (Node)) {
-
-      case ACPI_DEVICE_PATH:
-        if (EISA_ID_TO_NUM (((ACPI_HID_DEVICE_PATH *) Node)->HID) == 0x0604) {
-          return BmAcpiFloppyBoot;
-        }
-        break;
-
-      case HARDWARE_DEVICE_PATH:
-        if (DevicePathSubType (Node) == HW_CONTROLLER_DP) {
-          return BmHardwareDeviceBoot;
-        }
-        break;
-
-      case MESSAGING_DEVICE_PATH:
-        //
-        // Skip LUN device node
-        //
-        NextNode = Node;
-        do {
-          NextNode = NextDevicePathNode (NextNode);
-        } while (
-            (DevicePathType (NextNode) == MESSAGING_DEVICE_PATH) &&
-            (DevicePathSubType(NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP)
-            );
-
-        //
-        // If the device path not only point to driver device, it is not a 
messaging device path,
-        //
-        if (!IsDevicePathEndType (NextNode)) {
-          continue;
-        }
-
-        switch (DevicePathSubType (Node)) {
-        case MSG_ATAPI_DP:
-          return BmMessageAtapiBoot;
-          break;
-
-        case MSG_SATA_DP:
-          return BmMessageSataBoot;
-          break;
-
-        case MSG_USB_DP:
-          return BmMessageUsbBoot;
-          break;
-
-        case MSG_SCSI_DP:
-          return BmMessageScsiBoot;
-          break;
-
-        case MSG_MAC_ADDR_DP:
-        case MSG_VLAN_DP:
-        case MSG_IPv4_DP:
-        case MSG_IPv6_DP:
-          return BmMessageNetworkBoot;
-          break;
-
-        case MSG_URI_DP:
-          return BmMessageHttpBoot;
-          break;
-        }
-    }
-  }
-
-  return BmMiscBoot;
-}
-
-/**
   Find the boot option in the NV storage and return the option number.
 
   @param OptionToFind  Boot option to be checked.
@@ -455,411 +344,6 @@ BmMatchUsbClass (
 }
 
 /**
-  Eliminate the extra spaces in the Str to one space.
-
-  @param    Str     Input string info.
-**/
-VOID
-BmEliminateExtraSpaces (
-  IN CHAR16                    *Str
-  )
-{
-  UINTN                        Index;
-  UINTN                        ActualIndex;
-
-  for (Index = 0, ActualIndex = 0; Str[Index] != L'\0'; Index++) {
-    if ((Str[Index] != L' ') || ((ActualIndex > 0) && (Str[ActualIndex - 1] != 
L' '))) {
-      Str[ActualIndex++] = Str[Index];
-    }
-  }
-  Str[ActualIndex] = L'\0';
-}
-
-/**
-  Try to get the controller's ATA/ATAPI description.
-
-  @param Handle                Controller handle.
-
-  @return  The description string.
-**/
-CHAR16 *
-BmGetDescriptionFromDiskInfo (
-  IN EFI_HANDLE                Handle
-  )
-{
-  UINTN                        Index;
-  EFI_STATUS                   Status;
-  EFI_DISK_INFO_PROTOCOL       *DiskInfo;
-  UINT32                       BufferSize;
-  EFI_ATAPI_IDENTIFY_DATA      IdentifyData;
-  EFI_SCSI_INQUIRY_DATA        InquiryData;
-  CHAR16                       *Description;
-  UINTN                        Length;
-  CONST UINTN                  ModelNameLength    = 40;
-  CONST UINTN                  SerialNumberLength = 20;
-  CHAR8                        *StrPtr;
-  UINT8                        Temp;
-
-  Description  = NULL;
-
-  Status = gBS->HandleProtocol (
-                  Handle,
-                  &gEfiDiskInfoProtocolGuid,
-                  (VOID **) &DiskInfo
-                  );
-  if (EFI_ERROR (Status)) {
-    return NULL;
-  }
-
-  if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid) || 
-      CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) {
-    BufferSize   = sizeof (EFI_ATAPI_IDENTIFY_DATA);
-    Status = DiskInfo->Identify (
-                         DiskInfo,
-                         &IdentifyData,
-                         &BufferSize
-                         );
-    if (!EFI_ERROR (Status)) {
-      Description = AllocateZeroPool ((ModelNameLength + SerialNumberLength + 
2) * sizeof (CHAR16));
-      ASSERT (Description != NULL);
-      for (Index = 0; Index + 1 < ModelNameLength; Index += 2) {
-        Description[Index]     = (CHAR16) IdentifyData.ModelName[Index + 1];
-        Description[Index + 1] = (CHAR16) IdentifyData.ModelName[Index];
-      }
-
-      Length = Index;
-      Description[Length++] = L' ';
-
-      for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) {
-        Description[Length + Index]     = (CHAR16) IdentifyData.SerialNo[Index 
+ 1];
-        Description[Length + Index + 1] = (CHAR16) 
IdentifyData.SerialNo[Index];
-      }
-      Length += Index;
-      Description[Length++] = L'\0';
-      ASSERT (Length == ModelNameLength + SerialNumberLength + 2);
-
-      BmEliminateExtraSpaces (Description);
-    }
-  } else if (CompareGuid (&DiskInfo->Interface, 
&gEfiDiskInfoScsiInterfaceGuid)) {
-    BufferSize   = sizeof (EFI_SCSI_INQUIRY_DATA);
-    Status = DiskInfo->Inquiry (
-                         DiskInfo,
-                         &InquiryData,
-                         &BufferSize
-                         );
-    if (!EFI_ERROR (Status)) {
-      Description = AllocateZeroPool ((VENDOR_IDENTIFICATION_LENGTH + 
PRODUCT_IDENTIFICATION_LENGTH + 2) * sizeof (CHAR16));
-      ASSERT (Description != NULL);
-
-      //
-      // Per SCSI spec, EFI_SCSI_INQUIRY_DATA.Reserved_5_95[3 - 10] save the 
Verdor identification
-      // EFI_SCSI_INQUIRY_DATA.Reserved_5_95[11 - 26] save the product 
identification, 
-      // Here combine the vendor identification and product identification to 
the description.
-      //
-      StrPtr = (CHAR8 *) 
(&InquiryData.Reserved_5_95[VENDOR_IDENTIFICATION_OFFSET]);
-      Temp = StrPtr[VENDOR_IDENTIFICATION_LENGTH];
-      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = '\0';
-      AsciiStrToUnicodeStr (StrPtr, Description);
-      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = Temp;
-
-      //
-      // Add one space at the middle of vendor information and product 
information.
-      //
-      Description[VENDOR_IDENTIFICATION_LENGTH] = L' ';
-
-      StrPtr = (CHAR8 *) 
(&InquiryData.Reserved_5_95[PRODUCT_IDENTIFICATION_OFFSET]);
-      StrPtr[PRODUCT_IDENTIFICATION_LENGTH] = '\0';
-      AsciiStrToUnicodeStr (StrPtr, Description + VENDOR_IDENTIFICATION_LENGTH 
+ 1);
-
-      BmEliminateExtraSpaces (Description);
-    }
-  }
-
-  return Description;
-}
-
-/**
-  Try to get the controller's USB description.
-
-  @param Handle                Controller handle.
-
-  @return  The description string.
-**/
-CHAR16 *
-BmGetUsbDescription (
-  IN EFI_HANDLE                Handle
-  )
-{
-  EFI_STATUS                   Status;
-  EFI_USB_IO_PROTOCOL          *UsbIo;
-  CHAR16                       NullChar;
-  CHAR16                       *Manufacturer;
-  CHAR16                       *Product;
-  CHAR16                       *SerialNumber;
-  CHAR16                       *Description;
-  EFI_USB_DEVICE_DESCRIPTOR    DevDesc;
-  UINTN                        DescMaxSize;
-
-  Status = gBS->HandleProtocol (
-                  Handle,
-                  &gEfiUsbIoProtocolGuid,
-                  (VOID **) &UsbIo
-                  );
-  if (EFI_ERROR (Status)) {
-    return NULL;
-  }
-
-  NullChar = L'\0';
-
-  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
-  if (EFI_ERROR (Status)) {
-    return NULL;
-  }
-
-  Status = UsbIo->UsbGetStringDescriptor (
-                    UsbIo,
-                    mBmUsbLangId,
-                    DevDesc.StrManufacturer,
-                    &Manufacturer
-                    );
-  if (EFI_ERROR (Status)) {
-    Manufacturer = &NullChar;
-  }
-  
-  Status = UsbIo->UsbGetStringDescriptor (
-                    UsbIo,
-                    mBmUsbLangId,
-                    DevDesc.StrProduct,
-                    &Product
-                    );
-  if (EFI_ERROR (Status)) {
-    Product = &NullChar;
-  }
-  
-  Status = UsbIo->UsbGetStringDescriptor (
-                    UsbIo,
-                    mBmUsbLangId,
-                    DevDesc.StrSerialNumber,
-                    &SerialNumber
-                    );
-  if (EFI_ERROR (Status)) {
-    SerialNumber = &NullChar;
-  }
-
-  if ((Manufacturer == &NullChar) &&
-      (Product == &NullChar) &&
-      (SerialNumber == &NullChar)
-      ) {
-    return NULL;
-  }
-
-  DescMaxSize = StrSize (Manufacturer) + StrSize (Product) + StrSize 
(SerialNumber);
-  Description = AllocateZeroPool (DescMaxSize);
-  ASSERT (Description != NULL);
-  StrCatS (Description, DescMaxSize/sizeof(CHAR16), Manufacturer);
-  StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" ");
-
-  StrCatS (Description, DescMaxSize/sizeof(CHAR16), Product);  
-  StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" ");
-
-  StrCatS (Description, DescMaxSize/sizeof(CHAR16), SerialNumber);
-
-  if (Manufacturer != &NullChar) {
-    FreePool (Manufacturer);
-  }
-  if (Product != &NullChar) {
-    FreePool (Product);
-  }
-  if (SerialNumber != &NullChar) {
-    FreePool (SerialNumber);
-  }
-
-  BmEliminateExtraSpaces (Description);
-
-  return Description;
-}
-
-/**
-  Return the boot description for the controller based on the type.
-
-  @param Handle                Controller handle.
-
-  @return  The description string.
-**/
-CHAR16 *
-BmGetMiscDescription (
-  IN EFI_HANDLE                  Handle
-  )
-{
-  EFI_STATUS                      Status;
-  CHAR16                          *Description;
-  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
-
-  switch (BmDevicePathType (DevicePathFromHandle (Handle))) {
-  case BmAcpiFloppyBoot:
-    Description = L"Floppy";
-    break;
-
-  case BmMessageAtapiBoot:
-  case BmMessageSataBoot:
-    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) 
&BlockIo);
-    ASSERT_EFI_ERROR (Status);
-    //
-    // Assume a removable SATA device should be the DVD/CD device
-    //
-    Description = BlockIo->Media->RemovableMedia ? L"DVD/CDROM" : L"Hard 
Drive";
-    break;
-
-  case BmMessageUsbBoot:
-    Description = L"USB Device";
-    break;
-
-  case BmMessageScsiBoot:
-    Description = L"SCSI Device";
-    break;
-
-  case BmHardwareDeviceBoot:
-    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) 
&BlockIo);
-    if (!EFI_ERROR (Status)) {
-      Description = BlockIo->Media->RemovableMedia ? L"Removable Disk" : 
L"Hard Drive";
-    } else {
-      Description = L"Misc Device";
-    }
-    break;
-
-  case BmMessageNetworkBoot:
-    Description = L"Network";
-    break;
-
-  case BmMessageHttpBoot:
-    Description = L"Http";
-    break;
-
-  default:
-    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, 
(VOID **) &Fs);
-    if (!EFI_ERROR (Status)) {
-      Description = L"Non-Block Boot Device";
-    } else {
-      Description = L"Misc Device";
-    }
-    break;
-  }
-
-  return AllocateCopyPool (StrSize (Description), Description);
-}
-
-/**
-  Register the platform provided boot description handler.
-
-  @param Handler  The platform provided boot description handler
-
-  @retval EFI_SUCCESS          The handler was registered successfully.
-  @retval EFI_ALREADY_STARTED  The handler was already registered.
-  @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the 
registration.
-**/
-EFI_STATUS
-EFIAPI
-EfiBootManagerRegisterBootDescriptionHandler (
-  IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER  Handler
-  )
-{
-  LIST_ENTRY                                    *Link;
-  BM_BOOT_DESCRIPTION_ENTRY                    *Entry;
-
-  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)
-      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)
-      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)
-      ) {
-    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, 
BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);
-    if (Entry->Handler == Handler) {
-      return EFI_ALREADY_STARTED;
-    }
-  }
-
-  Entry = AllocatePool (sizeof (BM_BOOT_DESCRIPTION_ENTRY));
-  if (Entry == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Entry->Signature = BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE;
-  Entry->Handler   = Handler;
-  InsertTailList (&mPlatformBootDescriptionHandlers, &Entry->Link);
-  return EFI_SUCCESS;
-}
-
-BM_GET_BOOT_DESCRIPTION mBmBootDescriptionHandlers[] = {
-  BmGetUsbDescription,
-  BmGetDescriptionFromDiskInfo,
-  BmGetMiscDescription
-};
-
-/**
-  Return the boot description for the controller.
-
-  @param Handle                Controller handle.
-
-  @return  The description string.
-**/
-CHAR16 *
-BmGetBootDescription (
-  IN EFI_HANDLE                  Handle
-  )
-{
-  LIST_ENTRY                     *Link;
-  BM_BOOT_DESCRIPTION_ENTRY      *Entry;
-  CHAR16                         *Description;
-  CHAR16                         *DefaultDescription;
-  CHAR16                         *Temp;
-  UINTN                          Index;
-
-  //
-  // Firstly get the default boot description
-  //
-  DefaultDescription = NULL;
-  for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof 
(mBmBootDescriptionHandlers[0]); Index++) {
-    DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle);
-    if (DefaultDescription != NULL) {
-      //
-      // Avoid description confusion between UEFI & Legacy boot option by 
adding "UEFI " prefix
-      // ONLY for core provided boot description handler.
-      //
-      Temp = AllocatePool (StrSize (DefaultDescription) + sizeof 
(mBmUefiPrefix)); 
-      ASSERT (Temp != NULL);
-      StrCpyS ( Temp, 
-                (StrSize (DefaultDescription) + sizeof 
(mBmUefiPrefix))/sizeof(CHAR16), 
-                mBmUefiPrefix
-                );
-      StrCatS ( Temp, 
-                (StrSize (DefaultDescription) + sizeof 
(mBmUefiPrefix))/sizeof(CHAR16), 
-                DefaultDescription
-                );
-      FreePool (DefaultDescription);
-      DefaultDescription = Temp;
-      break;
-    }
-  }
-  ASSERT (DefaultDescription != NULL);
-
-  //
-  // Secondly query platform for the better boot description
-  //
-  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)
-      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)
-      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)
-      ) {
-    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, 
BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);
-    Description = Entry->Handler (Handle, DefaultDescription);
-    if (Description != NULL) {
-      FreePool (DefaultDescription);
-      return Description;
-    }
-  }
-
-  return DefaultDescription;
-}
-
-/**
   Check whether a USB device match the specified USB WWID device path. This
   function follows "Load Option Processing" behavior in UEFI specification.
 
@@ -2252,66 +1736,6 @@ BmMatchPartitionDevicePathNode (
 }
 
 /**
-  Enumerate all boot option descriptions and append " 2"/" 3"/... to make
-  unique description.
-
-  @param BootOptions            Array of boot options.
-  @param BootOptionCount        Count of boot options.
-**/
-VOID
-BmMakeBootOptionDescriptionUnique (
-  EFI_BOOT_MANAGER_LOAD_OPTION         *BootOptions,
-  UINTN                                BootOptionCount
-  )
-{
-  UINTN                                Base;
-  UINTN                                Index;
-  UINTN                                DescriptionSize;
-  UINTN                                MaxSuffixSize;
-  BOOLEAN                              *Visited;
-  UINTN                                MatchCount;
-
-  if (BootOptionCount == 0) {
-    return;
-  }
-
-  //
-  // Calculate the maximum buffer size for the number suffix.
-  // The initial sizeof (CHAR16) is for the blank space before the number.
-  //
-  MaxSuffixSize = sizeof (CHAR16);
-  for (Index = BootOptionCount; Index != 0; Index = Index / 10) {
-    MaxSuffixSize += sizeof (CHAR16);
-  }
-
-  Visited = AllocateZeroPool (sizeof (BOOLEAN) * BootOptionCount);
-  ASSERT (Visited != NULL);
-
-  for (Base = 0; Base < BootOptionCount; Base++) {
-    if (!Visited[Base]) {
-      MatchCount      = 1;
-      Visited[Base]   = TRUE;
-      DescriptionSize = StrSize (BootOptions[Base].Description);
-      for (Index = Base + 1; Index < BootOptionCount; Index++) {
-        if (!Visited[Index] && StrCmp (BootOptions[Base].Description, 
BootOptions[Index].Description) == 0) {
-          Visited[Index] = TRUE;
-          MatchCount++;
-          FreePool (BootOptions[Index].Description);
-          BootOptions[Index].Description = AllocatePool (DescriptionSize + 
MaxSuffixSize);
-          UnicodeSPrint (
-            BootOptions[Index].Description, DescriptionSize + MaxSuffixSize,
-            L"%s %d",
-            BootOptions[Base].Description, MatchCount
-            );
-        }
-      }
-    }
-  }
-
-  FreePool (Visited);
-}
-
-/**
   Emuerate all possible bootable medias in the following order:
   1. Removable BlockIo            - The boot option only points to the 
removable media
                                     device, like USB key, DVD, Floppy etc.
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c 
b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c
new file mode 100644
index 0000000..5c77e86
--- /dev/null
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c
@@ -0,0 +1,586 @@
+/** @file
+  Library functions which relate with boot option description.
+
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalBm.h"
+
+#define VENDOR_IDENTIFICATION_OFFSET     3
+#define VENDOR_IDENTIFICATION_LENGTH     8
+#define PRODUCT_IDENTIFICATION_OFFSET    11
+#define PRODUCT_IDENTIFICATION_LENGTH    16
+
+CONST UINT16 mBmUsbLangId    = 0x0409; // English
+CHAR16       mBmUefiPrefix[] = L"UEFI ";
+
+LIST_ENTRY mPlatformBootDescriptionHandlers = INITIALIZE_LIST_HEAD_VARIABLE 
(mPlatformBootDescriptionHandlers);
+
+/**
+  For a bootable Device path, return its boot type.
+
+  @param  DevicePath                   The bootable device Path to check
+
+  @retval AcpiFloppyBoot               If given device path contains 
ACPI_DEVICE_PATH type device path node
+                                       which HID is floppy device.
+  @retval MessageAtapiBoot             If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_ATAPI_DP.
+  @retval MessageSataBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_SATA_DP.
+  @retval MessageScsiBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_SCSI_DP.
+  @retval MessageUsbBoot               If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_USB_DP.
+  @retval MessageNetworkBoot           If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_MAC_ADDR_DP, MSG_VLAN_DP,
+                                       MSG_IPv4_DP or MSG_IPv6_DP.
+  @retval MessageHttpBoot              If given device path contains 
MESSAGING_DEVICE_PATH type device path node
+                                       and its last device path node's subtype 
is MSG_URI_DP.
+  @retval UnsupportedBoot              If tiven device path doesn't match the 
above condition, it's not supported.
+
+**/
+BM_BOOT_TYPE
+BmDevicePathType (
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *Node;
+  EFI_DEVICE_PATH_PROTOCOL      *NextNode;
+
+  ASSERT (DevicePath != NULL);
+
+  for (Node = DevicePath; !IsDevicePathEndType (Node); Node = 
NextDevicePathNode (Node)) {
+    switch (DevicePathType (Node)) {
+
+      case ACPI_DEVICE_PATH:
+        if (EISA_ID_TO_NUM (((ACPI_HID_DEVICE_PATH *) Node)->HID) == 0x0604) {
+          return BmAcpiFloppyBoot;
+        }
+        break;
+
+      case HARDWARE_DEVICE_PATH:
+        if (DevicePathSubType (Node) == HW_CONTROLLER_DP) {
+          return BmHardwareDeviceBoot;
+        }
+        break;
+
+      case MESSAGING_DEVICE_PATH:
+        //
+        // Skip LUN device node
+        //
+        NextNode = Node;
+        do {
+          NextNode = NextDevicePathNode (NextNode);
+        } while (
+            (DevicePathType (NextNode) == MESSAGING_DEVICE_PATH) &&
+            (DevicePathSubType(NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP)
+            );
+
+        //
+        // If the device path not only point to driver device, it is not a 
messaging device path,
+        //
+        if (!IsDevicePathEndType (NextNode)) {
+          continue;
+        }
+
+        switch (DevicePathSubType (Node)) {
+        case MSG_ATAPI_DP:
+          return BmMessageAtapiBoot;
+          break;
+
+        case MSG_SATA_DP:
+          return BmMessageSataBoot;
+          break;
+
+        case MSG_USB_DP:
+          return BmMessageUsbBoot;
+          break;
+
+        case MSG_SCSI_DP:
+          return BmMessageScsiBoot;
+          break;
+
+        case MSG_MAC_ADDR_DP:
+        case MSG_VLAN_DP:
+        case MSG_IPv4_DP:
+        case MSG_IPv6_DP:
+          return BmMessageNetworkBoot;
+          break;
+
+        case MSG_URI_DP:
+          return BmMessageHttpBoot;
+          break;
+        }
+    }
+  }
+
+  return BmMiscBoot;
+}
+
+/**
+  Eliminate the extra spaces in the Str to one space.
+
+  @param    Str     Input string info.
+**/
+VOID
+BmEliminateExtraSpaces (
+  IN CHAR16                    *Str
+  )
+{
+  UINTN                        Index;
+  UINTN                        ActualIndex;
+
+  for (Index = 0, ActualIndex = 0; Str[Index] != L'\0'; Index++) {
+    if ((Str[Index] != L' ') || ((ActualIndex > 0) && (Str[ActualIndex - 1] != 
L' '))) {
+      Str[ActualIndex++] = Str[Index];
+    }
+  }
+  Str[ActualIndex] = L'\0';
+}
+
+/**
+  Try to get the controller's ATA/ATAPI description.
+
+  @param Handle                Controller handle.
+
+  @return  The description string.
+**/
+CHAR16 *
+BmGetDescriptionFromDiskInfo (
+  IN EFI_HANDLE                Handle
+  )
+{
+  UINTN                        Index;
+  EFI_STATUS                   Status;
+  EFI_DISK_INFO_PROTOCOL       *DiskInfo;
+  UINT32                       BufferSize;
+  EFI_ATAPI_IDENTIFY_DATA      IdentifyData;
+  EFI_SCSI_INQUIRY_DATA        InquiryData;
+  CHAR16                       *Description;
+  UINTN                        Length;
+  CONST UINTN                  ModelNameLength    = 40;
+  CONST UINTN                  SerialNumberLength = 20;
+  CHAR8                        *StrPtr;
+  UINT8                        Temp;
+
+  Description  = NULL;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiDiskInfoProtocolGuid,
+                  (VOID **) &DiskInfo
+                  );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid) ||
+      CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) {
+    BufferSize   = sizeof (EFI_ATAPI_IDENTIFY_DATA);
+    Status = DiskInfo->Identify (
+                         DiskInfo,
+                         &IdentifyData,
+                         &BufferSize
+                         );
+    if (!EFI_ERROR (Status)) {
+      Description = AllocateZeroPool ((ModelNameLength + SerialNumberLength + 
2) * sizeof (CHAR16));
+      ASSERT (Description != NULL);
+      for (Index = 0; Index + 1 < ModelNameLength; Index += 2) {
+        Description[Index]     = (CHAR16) IdentifyData.ModelName[Index + 1];
+        Description[Index + 1] = (CHAR16) IdentifyData.ModelName[Index];
+      }
+
+      Length = Index;
+      Description[Length++] = L' ';
+
+      for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) {
+        Description[Length + Index]     = (CHAR16) IdentifyData.SerialNo[Index 
+ 1];
+        Description[Length + Index + 1] = (CHAR16) 
IdentifyData.SerialNo[Index];
+      }
+      Length += Index;
+      Description[Length++] = L'\0';
+      ASSERT (Length == ModelNameLength + SerialNumberLength + 2);
+
+      BmEliminateExtraSpaces (Description);
+    }
+  } else if (CompareGuid (&DiskInfo->Interface, 
&gEfiDiskInfoScsiInterfaceGuid)) {
+    BufferSize   = sizeof (EFI_SCSI_INQUIRY_DATA);
+    Status = DiskInfo->Inquiry (
+                         DiskInfo,
+                         &InquiryData,
+                         &BufferSize
+                         );
+    if (!EFI_ERROR (Status)) {
+      Description = AllocateZeroPool ((VENDOR_IDENTIFICATION_LENGTH + 
PRODUCT_IDENTIFICATION_LENGTH + 2) * sizeof (CHAR16));
+      ASSERT (Description != NULL);
+
+      //
+      // Per SCSI spec, EFI_SCSI_INQUIRY_DATA.Reserved_5_95[3 - 10] save the 
Verdor identification
+      // EFI_SCSI_INQUIRY_DATA.Reserved_5_95[11 - 26] save the product 
identification,
+      // Here combine the vendor identification and product identification to 
the description.
+      //
+      StrPtr = (CHAR8 *) 
(&InquiryData.Reserved_5_95[VENDOR_IDENTIFICATION_OFFSET]);
+      Temp = StrPtr[VENDOR_IDENTIFICATION_LENGTH];
+      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = '\0';
+      AsciiStrToUnicodeStr (StrPtr, Description);
+      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = Temp;
+
+      //
+      // Add one space at the middle of vendor information and product 
information.
+      //
+      Description[VENDOR_IDENTIFICATION_LENGTH] = L' ';
+
+      StrPtr = (CHAR8 *) 
(&InquiryData.Reserved_5_95[PRODUCT_IDENTIFICATION_OFFSET]);
+      StrPtr[PRODUCT_IDENTIFICATION_LENGTH] = '\0';
+      AsciiStrToUnicodeStr (StrPtr, Description + VENDOR_IDENTIFICATION_LENGTH 
+ 1);
+
+      BmEliminateExtraSpaces (Description);
+    }
+  }
+
+  return Description;
+}
+
+/**
+  Try to get the controller's USB description.
+
+  @param Handle                Controller handle.
+
+  @return  The description string.
+**/
+CHAR16 *
+BmGetUsbDescription (
+  IN EFI_HANDLE                Handle
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_USB_IO_PROTOCOL          *UsbIo;
+  CHAR16                       NullChar;
+  CHAR16                       *Manufacturer;
+  CHAR16                       *Product;
+  CHAR16                       *SerialNumber;
+  CHAR16                       *Description;
+  EFI_USB_DEVICE_DESCRIPTOR    DevDesc;
+  UINTN                        DescMaxSize;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &UsbIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  NullChar = L'\0';
+
+  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  Status = UsbIo->UsbGetStringDescriptor (
+                    UsbIo,
+                    mBmUsbLangId,
+                    DevDesc.StrManufacturer,
+                    &Manufacturer
+                    );
+  if (EFI_ERROR (Status)) {
+    Manufacturer = &NullChar;
+  }
+
+  Status = UsbIo->UsbGetStringDescriptor (
+                    UsbIo,
+                    mBmUsbLangId,
+                    DevDesc.StrProduct,
+                    &Product
+                    );
+  if (EFI_ERROR (Status)) {
+    Product = &NullChar;
+  }
+
+  Status = UsbIo->UsbGetStringDescriptor (
+                    UsbIo,
+                    mBmUsbLangId,
+                    DevDesc.StrSerialNumber,
+                    &SerialNumber
+                    );
+  if (EFI_ERROR (Status)) {
+    SerialNumber = &NullChar;
+  }
+
+  if ((Manufacturer == &NullChar) &&
+      (Product == &NullChar) &&
+      (SerialNumber == &NullChar)
+      ) {
+    return NULL;
+  }
+
+  DescMaxSize = StrSize (Manufacturer) + StrSize (Product) + StrSize 
(SerialNumber);
+  Description = AllocateZeroPool (DescMaxSize);
+  ASSERT (Description != NULL);
+  StrCatS (Description, DescMaxSize/sizeof(CHAR16), Manufacturer);
+  StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" ");
+
+  StrCatS (Description, DescMaxSize/sizeof(CHAR16), Product);
+  StrCatS (Description, DescMaxSize/sizeof(CHAR16), L" ");
+
+  StrCatS (Description, DescMaxSize/sizeof(CHAR16), SerialNumber);
+
+  if (Manufacturer != &NullChar) {
+    FreePool (Manufacturer);
+  }
+  if (Product != &NullChar) {
+    FreePool (Product);
+  }
+  if (SerialNumber != &NullChar) {
+    FreePool (SerialNumber);
+  }
+
+  BmEliminateExtraSpaces (Description);
+
+  return Description;
+}
+
+/**
+  Return the boot description for the controller based on the type.
+
+  @param Handle                Controller handle.
+
+  @return  The description string.
+**/
+CHAR16 *
+BmGetMiscDescription (
+  IN EFI_HANDLE                  Handle
+  )
+{
+  EFI_STATUS                      Status;
+  CHAR16                          *Description;
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
+
+  switch (BmDevicePathType (DevicePathFromHandle (Handle))) {
+  case BmAcpiFloppyBoot:
+    Description = L"Floppy";
+    break;
+
+  case BmMessageAtapiBoot:
+  case BmMessageSataBoot:
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) 
&BlockIo);
+    ASSERT_EFI_ERROR (Status);
+    //
+    // Assume a removable SATA device should be the DVD/CD device
+    //
+    Description = BlockIo->Media->RemovableMedia ? L"DVD/CDROM" : L"Hard 
Drive";
+    break;
+
+  case BmMessageUsbBoot:
+    Description = L"USB Device";
+    break;
+
+  case BmMessageScsiBoot:
+    Description = L"SCSI Device";
+    break;
+
+  case BmHardwareDeviceBoot:
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) 
&BlockIo);
+    if (!EFI_ERROR (Status)) {
+      Description = BlockIo->Media->RemovableMedia ? L"Removable Disk" : 
L"Hard Drive";
+    } else {
+      Description = L"Misc Device";
+    }
+    break;
+
+  case BmMessageNetworkBoot:
+    Description = L"Network";
+    break;
+
+  case BmMessageHttpBoot:
+    Description = L"Http";
+    break;
+
+  default:
+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, 
(VOID **) &Fs);
+    if (!EFI_ERROR (Status)) {
+      Description = L"Non-Block Boot Device";
+    } else {
+      Description = L"Misc Device";
+    }
+    break;
+  }
+
+  return AllocateCopyPool (StrSize (Description), Description);
+}
+
+/**
+  Register the platform provided boot description handler.
+
+  @param Handler  The platform provided boot description handler
+
+  @retval EFI_SUCCESS          The handler was registered successfully.
+  @retval EFI_ALREADY_STARTED  The handler was already registered.
+  @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the 
registration.
+**/
+EFI_STATUS
+EFIAPI
+EfiBootManagerRegisterBootDescriptionHandler (
+  IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER  Handler
+  )
+{
+  LIST_ENTRY                                    *Link;
+  BM_BOOT_DESCRIPTION_ENTRY                    *Entry;
+
+  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)
+      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)
+      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)
+      ) {
+    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, 
BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);
+    if (Entry->Handler == Handler) {
+      return EFI_ALREADY_STARTED;
+    }
+  }
+
+  Entry = AllocatePool (sizeof (BM_BOOT_DESCRIPTION_ENTRY));
+  if (Entry == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Entry->Signature = BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE;
+  Entry->Handler   = Handler;
+  InsertTailList (&mPlatformBootDescriptionHandlers, &Entry->Link);
+  return EFI_SUCCESS;
+}
+
+BM_GET_BOOT_DESCRIPTION mBmBootDescriptionHandlers[] = {
+  BmGetUsbDescription,
+  BmGetDescriptionFromDiskInfo,
+  BmGetMiscDescription
+};
+
+/**
+  Return the boot description for the controller.
+
+  @param Handle                Controller handle.
+
+  @return  The description string.
+**/
+CHAR16 *
+BmGetBootDescription (
+  IN EFI_HANDLE                  Handle
+  )
+{
+  LIST_ENTRY                     *Link;
+  BM_BOOT_DESCRIPTION_ENTRY      *Entry;
+  CHAR16                         *Description;
+  CHAR16                         *DefaultDescription;
+  CHAR16                         *Temp;
+  UINTN                          Index;
+
+  //
+  // Firstly get the default boot description
+  //
+  DefaultDescription = NULL;
+  for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof 
(mBmBootDescriptionHandlers[0]); Index++) {
+    DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle);
+    if (DefaultDescription != NULL) {
+      //
+      // Avoid description confusion between UEFI & Legacy boot option by 
adding "UEFI " prefix
+      // ONLY for core provided boot description handler.
+      //
+      Temp = AllocatePool (StrSize (DefaultDescription) + sizeof 
(mBmUefiPrefix));
+      ASSERT (Temp != NULL);
+      StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / 
sizeof (CHAR16), mBmUefiPrefix);
+      StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / 
sizeof (CHAR16), DefaultDescription);
+      FreePool (DefaultDescription);
+      DefaultDescription = Temp;
+      break;
+    }
+  }
+  ASSERT (DefaultDescription != NULL);
+
+  //
+  // Secondly query platform for the better boot description
+  //
+  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)
+      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)
+      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)
+      ) {
+    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, 
BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);
+    Description = Entry->Handler (Handle, DefaultDescription);
+    if (Description != NULL) {
+      FreePool (DefaultDescription);
+      return Description;
+    }
+  }
+
+  return DefaultDescription;
+}
+
+/**
+  Enumerate all boot option descriptions and append " 2"/" 3"/... to make
+  unique description.
+
+  @param BootOptions            Array of boot options.
+  @param BootOptionCount        Count of boot options.
+**/
+VOID
+BmMakeBootOptionDescriptionUnique (
+  EFI_BOOT_MANAGER_LOAD_OPTION         *BootOptions,
+  UINTN                                BootOptionCount
+  )
+{
+  UINTN                                Base;
+  UINTN                                Index;
+  UINTN                                DescriptionSize;
+  UINTN                                MaxSuffixSize;
+  BOOLEAN                              *Visited;
+  UINTN                                MatchCount;
+
+  if (BootOptionCount == 0) {
+    return;
+  }
+
+  //
+  // Calculate the maximum buffer size for the number suffix.
+  // The initial sizeof (CHAR16) is for the blank space before the number.
+  //
+  MaxSuffixSize = sizeof (CHAR16);
+  for (Index = BootOptionCount; Index != 0; Index = Index / 10) {
+    MaxSuffixSize += sizeof (CHAR16);
+  }
+
+  Visited = AllocateZeroPool (sizeof (BOOLEAN) * BootOptionCount);
+  ASSERT (Visited != NULL);
+
+  for (Base = 0; Base < BootOptionCount; Base++) {
+    if (!Visited[Base]) {
+      MatchCount      = 1;
+      Visited[Base]   = TRUE;
+      DescriptionSize = StrSize (BootOptions[Base].Description);
+      for (Index = Base + 1; Index < BootOptionCount; Index++) {
+        if (!Visited[Index] && StrCmp (BootOptions[Base].Description, 
BootOptions[Index].Description) == 0) {
+          Visited[Index] = TRUE;
+          MatchCount++;
+          FreePool (BootOptions[Index].Description);
+          BootOptions[Index].Description = AllocatePool (DescriptionSize + 
MaxSuffixSize);
+          UnicodeSPrint (
+            BootOptions[Index].Description, DescriptionSize + MaxSuffixSize,
+            L"%s %d",
+            BootOptions[Base].Description, MatchCount
+            );
+        }
+      }
+    }
+  }
+
+  FreePool (Visited);
+}
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h 
b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
index cfaeefe..c1514c3 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
+++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
@@ -167,28 +167,6 @@ typedef struct {
 #define BM_HOTKEY_FROM_LINK(a) CR (a, BM_HOTKEY, Link, BM_HOTKEY_SIGNATURE)
 
 /**
-  Get the image file buffer data and buffer size by its device path. 
-
-  @param FilePath  On input, a pointer to an allocated buffer containing the 
device
-                   path of the file.
-                   On output the pointer could be NULL when the function fails 
to
-                   load the boot option, or could point to an allocated buffer 
containing
-                   the device path of the file.
-                   It could be updated by either short-form device path 
expanding,
-                   or default boot file path appending.
-                   Caller is responsible to free it when it's non-NULL.
-  @param FileSize  A pointer to the size of the file buffer.
-
-  @retval NULL   File is NULL, or FileSize is NULL. Or, the file can't be 
found.
-  @retval other  The file buffer. The caller is responsible to free the memory.
-**/
-VOID *
-BmLoadEfiBootOption (
-  IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
-  OUT    UINTN                    *FileSize
-  );
-
-/**
   Get the Option Number that wasn't used.
 
   @param  LoadOptionType      Load option type.
@@ -221,28 +199,6 @@ BmWriteBootToOsPerformanceData (
   IN VOID       *Context
   );
 
-
-/**
-  Get the headers (dos, image, optional header) from an image
-
-  @param  Device                SimpleFileSystem device handle
-  @param  FileName              File name for the image
-  @param  DosHeader             Pointer to dos header
-  @param  Hdr                   The buffer in which to return the PE32, PE32+, 
or TE header.
-
-  @retval EFI_SUCCESS           Successfully get the machine type.
-  @retval EFI_NOT_FOUND         The file is not found.
-  @retval EFI_LOAD_ERROR        File is not a valid image file.
-
-**/
-EFI_STATUS
-BmGetImageHeader (
-  IN  EFI_HANDLE                  Device,
-  IN  CHAR16                      *FileName,
-  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
-  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
-  );
-
 /**
   This routine adjust the memory information for different memory type and 
   save them into the variables for next boot. It resets the system when
@@ -472,4 +428,29 @@ BmGetFileBufferFromLoadFileFileSystem (
   OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,
   OUT UINTN                           *FileSize
   );
+
+/**
+  Return the boot description for the controller.
+
+  @param Handle                Controller handle.
+
+  @return  The description string.
+**/
+CHAR16 *
+BmGetBootDescription (
+  IN EFI_HANDLE                  Handle
+  );
+
+/**
+  Enumerate all boot option descriptions and append " 2"/" 3"/... to make
+  unique description.
+
+  @param BootOptions            Array of boot options.
+  @param BootOptionCount        Count of boot options.
+**/
+VOID
+BmMakeBootOptionDescriptionUnique (
+  EFI_BOOT_MANAGER_LOAD_OPTION         *BootOptions,
+  UINTN                                BootOptionCount
+  );
 #endif // _INTERNAL_BM_H_
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf 
b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
index f1f6246..e9e74b1 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
@@ -5,7 +5,7 @@
 #  manipulation, hotkey registration, UEFI boot, connect/disconnect, console
 #  manipulation, driver health checking and etc.
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
 #  which accompanies this distribution.  The full text of the license may be 
found at
@@ -37,6 +37,7 @@
   BmMisc.c
   BmConsole.c
   BmBoot.c
+  BmBootDescription.c
   BmLoadOption.c
   BmHotkey.c
   BmDriverHealth.c
-- 
2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to