/** @file
  Library functions which relate with boot option description.

Copyright (c) 2011 - 2017, 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 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;

  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);
    }
  }

  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(...)/Uri(...)
  //   ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)/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;
  }

  //
  // 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);
}
