/** @file
  Library functions which relate with boot option description.

Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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 BmMiscBoot        If tiven device path doesn't match the above condition.

**/
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;
        }
    }
  }

  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;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  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';
      AsciiStrToUnicodeStrS (StrPtr, Description, VENDOR_IDENTIFICATION_LENGTH + 1);
      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';
      AsciiStrToUnicodeStrS (StrPtr, Description + VENDOR_IDENTIFICATION_LENGTH + 1, PRODUCT_IDENTIFICATION_LENGTH + 1);

      BmEliminateExtraSpaces (Description);
    }
  } else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoSdMmcInterfaceGuid)) {
    DevicePath = DevicePathFromHandle (Handle);
    if (DevicePath == NULL) {
      return NULL;
    }

    while (!IsDevicePathEnd (DevicePath) && (DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH)) {
      DevicePath = NextDevicePathNode (DevicePath);
    }

    if (IsDevicePathEnd (DevicePath)) {
      return NULL;
    }

    if (DevicePathSubType (DevicePath) == MSG_SD_DP) {
      Description = L"SD Device";
    } else if (DevicePathSubType (DevicePath) == MSG_EMMC_DP) {
      Description = L"eMMC Device";
    } else {
      return NULL;
    }

    Description = AllocateCopyPool (StrSize (Description), 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 description for network boot device.

  @param Handle                Controller handle.

  @return  The description string.
**/
CHAR16 *
BmGetNetworkDescription (
  IN EFI_HANDLE  Handle
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  MAC_ADDR_DEVICE_PATH      *Mac;
  VLAN_DEVICE_PATH          *Vlan;
  EFI_DEVICE_PATH_PROTOCOL  *Ip;
  EFI_DEVICE_PATH_PROTOCOL  *Uri;
  CHAR16                    *Description;
  UINTN                     DescriptionSize;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiLoadFileProtocolGuid,
                  NULL,
                  gImageHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath,
                  gImageHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status) || (DevicePath == NULL)) {
    return NULL;
  }

  //
  // The PXE device path is like:
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)
  //
  // The HTTP device path is like:
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)
  //
  while (!IsDevicePathEnd (DevicePath) &&
         ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) ||
          (DevicePathSubType (DevicePath) != MSG_MAC_ADDR_DP))
         )
  {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  if (IsDevicePathEnd (DevicePath)) {
    return NULL;
  }

  Mac        = (MAC_ADDR_DEVICE_PATH *)DevicePath;
  DevicePath = NextDevicePathNode (DevicePath);

  //
  // Locate the optional Vlan node
  //
  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
      (DevicePathSubType (DevicePath) == MSG_VLAN_DP)
      )
  {
    Vlan       = (VLAN_DEVICE_PATH *)DevicePath;
    DevicePath = NextDevicePathNode (DevicePath);
  } else {
    Vlan = NULL;
  }

  //
  // Skip the optional Wi-Fi node
  //
  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
      (DevicePathSubType (DevicePath) == MSG_WIFI_DP)
      )
  {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // Locate the IP node
  //
  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
      ((DevicePathSubType (DevicePath) == MSG_IPv4_DP) ||
       (DevicePathSubType (DevicePath) == MSG_IPv6_DP))
      )
  {
    Ip         = DevicePath;
    DevicePath = NextDevicePathNode (DevicePath);
  } else {
    Ip = NULL;
  }

  //
  // Skip the optional DNS node
  //
  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
      (DevicePathSubType (DevicePath) == MSG_DNS_DP)
      )
  {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // Locate the URI node
  //
  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
      (DevicePathSubType (DevicePath) == MSG_URI_DP)
      )
  {
    Uri        = DevicePath;
    DevicePath = NextDevicePathNode (DevicePath);
  } else {
    Uri = NULL;
  }

  //
  // Build description like below:
  //   "PXEv6 (MAC:112233445566 VLAN1)"
  //   "HTTPv4 (MAC:112233445566)"
  //
  DescriptionSize = sizeof (L"HTTPv6 (MAC:112233445566 VLAN65535)");
  Description     = AllocatePool (DescriptionSize);
  ASSERT (Description != NULL);
  UnicodeSPrint (
    Description,
    DescriptionSize,
    (Vlan == NULL) ?
    L"%sv%d (MAC:%02x%02x%02x%02x%02x%02x)" :
    L"%sv%d (MAC:%02x%02x%02x%02x%02x%02x VLAN%d)",
    (Uri == NULL) ? L"PXE" : L"HTTP",
    ((Ip == NULL) || (DevicePathSubType (Ip) == MSG_IPv4_DP)) ? 4 : 6,
    Mac->MacAddress.Addr[0],
    Mac->MacAddress.Addr[1],
    Mac->MacAddress.Addr[2],
    Mac->MacAddress.Addr[3],
    Mac->MacAddress.Addr[4],
    Mac->MacAddress.Addr[5],
    (Vlan == NULL) ? 0 : Vlan->VlanId
    );
  return Description;
}

/**
  Return the boot description for LoadFile

  @param Handle                Controller handle.

  @return  The description string.
**/
CHAR16 *
BmGetLoadFileDescription (
  IN EFI_HANDLE  Handle
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;
  CHAR16                    *Description;
  EFI_LOAD_FILE_PROTOCOL    *LoadFile;

  Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFile);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Get the file name
  //
  Description = NULL;
  Status      = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&FilePath);
  if (!EFI_ERROR (Status)) {
    DevicePathNode = FilePath;
    while (!IsDevicePathEnd (DevicePathNode)) {
      if ((DevicePathNode->Type == MEDIA_DEVICE_PATH) && (DevicePathNode->SubType == MEDIA_FILEPATH_DP)) {
        Description = (CHAR16 *)(DevicePathNode + 1);
        break;
      }

      DevicePathNode = NextDevicePathNode (DevicePathNode);
    }
  }

  if (Description != NULL) {
    return AllocateCopyPool (StrSize (Description), Description);
  }

  return NULL;
}

/**
  Return the boot description for NVME boot device.

  @param Handle                Controller handle.

  @return  The description string.
**/
CHAR16 *
BmGetNvmeDescription (
  IN EFI_HANDLE  Handle
  )
{
  EFI_STATUS                                Status;
  EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL        *NvmePassthru;
  EFI_DEV_PATH_PTR                          DevicePath;
  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET  CommandPacket;
  EFI_NVM_EXPRESS_COMMAND                   Command;
  EFI_NVM_EXPRESS_COMPLETION                Completion;
  NVME_ADMIN_CONTROLLER_DATA                ControllerData;
  CHAR16                                    *Description;
  CHAR16                                    *Char;
  UINTN                                     Index;

  Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath.DevPath);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  Status = gBS->LocateDevicePath (&gEfiNvmExpressPassThruProtocolGuid, &DevicePath.DevPath, &Handle);
  if (EFI_ERROR (Status) ||
      (DevicePathType (DevicePath.DevPath) != MESSAGING_DEVICE_PATH) ||
      (DevicePathSubType (DevicePath.DevPath) != MSG_NVME_NAMESPACE_DP))
  {
    //
    // Do not return description when the Handle is not a child of NVME controller.
    //
    return NULL;
  }

  //
  // Send ADMIN_IDENTIFY command to NVME controller to get the model and serial number.
  //
  Status = gBS->HandleProtocol (Handle, &gEfiNvmExpressPassThruProtocolGuid, (VOID **)&NvmePassthru);
  ASSERT_EFI_ERROR (Status);

  ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
  ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
  ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));

  Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
  //
  // According to Nvm Express 1.1 spec Figure 38, When not used, the field shall be cleared to 0h.
  // For the Identify command, the Namespace Identifier is only used for the Namespace data structure.
  //
  Command.Nsid                 = 0;
  CommandPacket.NvmeCmd        = &Command;
  CommandPacket.NvmeCompletion = &Completion;
  CommandPacket.TransferBuffer = &ControllerData;
  CommandPacket.TransferLength = sizeof (ControllerData);
  CommandPacket.CommandTimeout = EFI_TIMER_PERIOD_SECONDS (5);
  CommandPacket.QueueType      = NVME_ADMIN_QUEUE;
  //
  // Set bit 0 (Cns bit) to 1 to identify a controller
  //
  Command.Cdw10 = 1;
  Command.Flags = CDW10_VALID;

  Status = NvmePassthru->PassThru (
                           NvmePassthru,
                           0,
                           &CommandPacket,
                           NULL
                           );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  Description = AllocateZeroPool (
                  (ARRAY_SIZE (ControllerData.Mn) + 1
                   + ARRAY_SIZE (ControllerData.Sn) + 1
                   + MAXIMUM_VALUE_CHARACTERS + 1
                  ) * sizeof (CHAR16)
                  );
  if (Description != NULL) {
    Char = Description;
    for (Index = 0; Index < ARRAY_SIZE (ControllerData.Mn); Index++) {
      *(Char++) = (CHAR16)ControllerData.Mn[Index];
    }

    *(Char++) = L' ';
    for (Index = 0; Index < ARRAY_SIZE (ControllerData.Sn); Index++) {
      *(Char++) = (CHAR16)ControllerData.Sn[Index];
    }

    *(Char++) = L' ';
    UnicodeValueToStringS (
      Char,
      sizeof (CHAR16) * (MAXIMUM_VALUE_CHARACTERS + 1),
      0,
      DevicePath.NvmeNamespace->NamespaceId,
      0
      );
    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;

    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,
  BmGetNetworkDescription,
  BmGetLoadFileDescription,
  BmGetNvmeDescription,
  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 < ARRAY_SIZE (mBmBootDescriptionHandlers); 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);
}
