/** @file
  Main file for support of shell consist mapping.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "UefiShellCommandLib.h"
#include <Library/DevicePathLib.h>
#include <Library/SortLib.h>
#include <Library/UefiLib.h>
#include <Protocol/UsbIo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/SimpleFileSystem.h>

typedef enum {
  MTDTypeUnknown,
  MTDTypeFloppy,
  MTDTypeHardDisk,
  MTDTypeCDRom,
  MTDTypeEnd
} MTD_TYPE;

typedef struct {
  CHAR16    *Str;
  UINTN     Len;
} POOL_PRINT;

typedef struct {
  UINTN         Hi;
  MTD_TYPE      Mtd;
  POOL_PRINT    Csd;
  BOOLEAN       Digital;
} DEVICE_CONSIST_MAPPING_INFO;

typedef struct {
  MTD_TYPE    MTDType;
  CHAR16      *Name;
} MTD_NAME;

/**
  Serial Decode function.

  @param  DevPath          The Device path info.
  @param  MapInfo          The map info.
  @param  OrigDevPath      The original device path protocol.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
typedef
EFI_STATUS
(*SERIAL_DECODE_FUNCTION) (
  EFI_DEVICE_PATH_PROTOCOL     *DevPath,
  DEVICE_CONSIST_MAPPING_INFO  *MapInfo,
  EFI_DEVICE_PATH_PROTOCOL     *OrigDevPath
  );

typedef struct {
  UINT8                     Type;
  UINT8                     SubType;
  SERIAL_DECODE_FUNCTION    SerialFun;
  INTN (EFIAPI *CompareFun)(EFI_DEVICE_PATH_PROTOCOL *DevPath, EFI_DEVICE_PATH_PROTOCOL *DevPath2);
} DEV_PATH_CONSIST_MAPPING_TABLE;

/**
  Concatenates a formatted unicode string to allocated pool.
  The caller must free the resulting buffer.

  @param  Str      Tracks the allocated pool, size in use, and amount of pool allocated.
  @param  Fmt      The format string
  @param  ...      The data will be printed.

  @retval EFI_SUCCESS          The string is concatenated successfully.
  @retval EFI_OUT_OF_RESOURCES Out of resources.

**/
EFI_STATUS
EFIAPI
CatPrint (
  IN OUT POOL_PRINT  *Str,
  IN CHAR16          *Fmt,
  ...
  )
{
  UINT16   *AppendStr;
  VA_LIST  Args;
  UINTN    StringSize;
  CHAR16   *NewStr;

  AppendStr = AllocateZeroPool (0x1000);
  if (AppendStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  VA_START (Args, Fmt);
  UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
  VA_END (Args);
  if (NULL == Str->Str) {
    StringSize = StrSize (AppendStr);
    NewStr     = AllocateZeroPool (StringSize);
  } else {
    StringSize  = StrSize (AppendStr);
    StringSize += (StrSize (Str->Str) - sizeof (UINT16));

    NewStr = ReallocatePool (
               StrSize (Str->Str),
               StringSize,
               Str->Str
               );
  }

  if (NewStr == NULL) {
    FreePool (AppendStr);
    return EFI_OUT_OF_RESOURCES;
  }

  Str->Str = NewStr;
  StrCatS (Str->Str, StringSize/sizeof (CHAR16), AppendStr);
  Str->Len = StringSize;

  FreePool (AppendStr);
  return EFI_SUCCESS;
}

MTD_NAME  mMTDName[] = {
  {
    MTDTypeUnknown,
    L"F"
  },
  {
    MTDTypeFloppy,
    L"FP"
  },
  {
    MTDTypeHardDisk,
    L"HD"
  },
  {
    MTDTypeCDRom,
    L"CD"
  },
  {
    MTDTypeEnd,
    NULL
  }
};

/**
  Function to append a 64 bit number / 25 onto the string.

  @param[in, out] Str          The string so append onto.
  @param[in]      Num          The number to divide and append.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
AppendCSDNum2 (
  IN OUT POOL_PRINT  *Str,
  IN UINT64          Num
  )
{
  EFI_STATUS  Status;
  UINT64      Result;
  UINT32      Rem;

  ASSERT (Str != NULL);

  Result = DivU64x32Remainder (Num, 25, &Rem);
  if (Result > 0) {
    Status = AppendCSDNum2 (Str, Result);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return CatPrint (Str, L"%c", Rem + 'a');
}

/**
  Function to append a 64 bit number onto the mapping info.

  @param[in, out] MappingItem  The mapping info object to append onto.
  @param[in]      Num          The info to append.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.

**/
EFI_STATUS
AppendCSDNum (
  IN OUT DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN     UINT64                       Num
  )
{
  EFI_STATUS  Status;

  ASSERT (MappingItem != NULL);

  if (MappingItem->Digital) {
    Status = CatPrint (&MappingItem->Csd, L"%ld", Num);
  } else {
    Status = AppendCSDNum2 (&MappingItem->Csd, Num);
  }

  if (!EFI_ERROR (Status)) {
    MappingItem->Digital = (BOOLEAN) !(MappingItem->Digital);
  }

  return Status;
}

/**
  Function to append string into the mapping info.

  @param[in, out] MappingItem  The mapping info object to append onto.
  @param[in]      Str          The info to append.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
AppendCSDStr (
  IN OUT DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN     CHAR16                       *Str
  )
{
  CHAR16      *Index;
  EFI_STATUS  Status;

  ASSERT (Str != NULL && MappingItem != NULL);

  Status = EFI_SUCCESS;

  if (MappingItem->Digital) {
    //
    // To aVOID mult-meaning, the mapping is:
    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    //  0  16 2  3  4  5  6  7  8  9  10 11 12 13 14 15
    //
    for (Index = Str; *Index != 0; Index++) {
      switch (*Index) {
        case '0':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          Status = CatPrint (&MappingItem->Csd, L"%c", *Index);
          break;

        case '1':
          Status = CatPrint (&MappingItem->Csd, L"16");
          break;

        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
          Status = CatPrint (&MappingItem->Csd, L"1%c", *Index - 'a' + '0');
          break;

        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
          Status = CatPrint (&MappingItem->Csd, L"1%c", *Index - 'A' + '0');
          break;
      }

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  } else {
    for (Index = Str; *Index != 0; Index++) {
      //
      //  The mapping is:
      //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
      //  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p
      //
      if ((*Index >= '0') && (*Index <= '9')) {
        Status = CatPrint (&MappingItem->Csd, L"%c", *Index - '0' + 'a');
      } else if ((*Index >= 'a') && (*Index <= 'f')) {
        Status = CatPrint (&MappingItem->Csd, L"%c", *Index - 'a' + 'k');
      } else if ((*Index >= 'A') && (*Index <= 'F')) {
        Status = CatPrint (&MappingItem->Csd, L"%c", *Index - 'A' + 'k');
      }

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  }

  MappingItem->Digital = (BOOLEAN) !(MappingItem->Digital);

  return (EFI_SUCCESS);
}

/**
  Function to append a Guid to the mapping item.

  @param[in, out] MappingItem  The item to append onto.
  @param[in]      Guid         The guid to append.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
AppendCSDGuid (
  DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  EFI_GUID                     *Guid
  )
{
  CHAR16  Buffer[64];

  ASSERT (Guid != NULL && MappingItem != NULL);

  UnicodeSPrint (
    Buffer,
    0,
    L"%g",
    Guid
    );

  return AppendCSDStr (MappingItem, Buffer);
}

/**
  Function to compare 2 APCI device paths.

  @param[in] DevicePath1        The first device path to compare.
  @param[in] DevicePath2        The second device path to compare.

  @retval 0 The device paths represent the same device.
  @return   Non zero if the devices are different, zero otherwise.
**/
INTN
EFIAPI
DevPathCompareAcpi (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath1,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath2
  )
{
  ACPI_HID_DEVICE_PATH  *Acpi1;
  ACPI_HID_DEVICE_PATH  *Acpi2;

  if ((DevicePath1 == NULL) || (DevicePath2 == NULL)) {
    return (-2);
  }

  Acpi1 = (ACPI_HID_DEVICE_PATH *)DevicePath1;
  Acpi2 = (ACPI_HID_DEVICE_PATH *)DevicePath2;
  if ((Acpi1->HID > Acpi2->HID) || ((Acpi1->HID == Acpi2->HID) && (Acpi1->UID > Acpi2->UID))) {
    return 1;
  }

  if ((Acpi1->HID == Acpi2->HID) && (Acpi1->UID == Acpi2->UID)) {
    return 0;
  }

  return -1;
}

/**
  Function to compare 2 PCI device paths.

  @param[in] DevicePath1        The first device path to compare.
  @param[in] DevicePath2        The second device path to compare.

  @retval 0 The device paths represent the same device.
  @return   Non zero if the devices are different, zero otherwise.
**/
INTN
EFIAPI
DevPathComparePci (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath1,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath2
  )
{
  PCI_DEVICE_PATH  *Pci1;
  PCI_DEVICE_PATH  *Pci2;

  ASSERT (DevicePath1 != NULL);
  ASSERT (DevicePath2 != NULL);

  Pci1 = (PCI_DEVICE_PATH *)DevicePath1;
  Pci2 = (PCI_DEVICE_PATH *)DevicePath2;
  if ((Pci1->Device > Pci2->Device) || ((Pci1->Device == Pci2->Device) && (Pci1->Function > Pci2->Function))) {
    return 1;
  }

  if ((Pci1->Device == Pci2->Device) && (Pci1->Function == Pci2->Function)) {
    return 0;
  }

  return -1;
}

/**
  Do a comparison on 2 device paths.

  @param[in] DevicePath1   The first device path.
  @param[in] DevicePath2   The second device path.

  @retval 0 The 2 device paths are the same.
  @retval <0  DevicePath2 is greater than DevicePath1.
  @retval >0  DevicePath1 is greater than DevicePath2.
**/
INTN
EFIAPI
DevPathCompareDefault (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath1,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath2
  )
{
  UINTN  DevPathSize1;
  UINTN  DevPathSize2;

  ASSERT (DevicePath1 != NULL);
  ASSERT (DevicePath2 != NULL);

  DevPathSize1 = DevicePathNodeLength (DevicePath1);
  DevPathSize2 = DevicePathNodeLength (DevicePath2);
  if (DevPathSize1 > DevPathSize2) {
    return 1;
  } else if (DevPathSize1 < DevPathSize2) {
    return -1;
  } else {
    return CompareMem (DevicePath1, DevicePath2, DevPathSize1);
  }
}

/**
  DevicePathNode must be SerialHDD Channel type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialHardDrive (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  HARDDRIVE_DEVICE_PATH  *Hd;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Hd = (HARDDRIVE_DEVICE_PATH *)DevicePathNode;
  if (MappingItem->Mtd == MTDTypeUnknown) {
    MappingItem->Mtd = MTDTypeHardDisk;
  }

  return AppendCSDNum (MappingItem, Hd->PartitionNumber);
}

/**
  DevicePathNode must be SerialAtapi Channel type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialAtapi (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  ATAPI_DEVICE_PATH  *Atapi;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Atapi = (ATAPI_DEVICE_PATH *)DevicePathNode;
  return AppendCSDNum (MappingItem, (Atapi->PrimarySecondary * 2 + Atapi->SlaveMaster));
}

/**
  DevicePathNode must be SerialCDROM Channel type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialCdRom (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  CDROM_DEVICE_PATH  *Cd;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Cd               = (CDROM_DEVICE_PATH *)DevicePathNode;
  MappingItem->Mtd = MTDTypeCDRom;
  return AppendCSDNum (MappingItem, Cd->BootEntry);
}

/**
  DevicePathNode must be SerialFibre Channel type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialFibre (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS                Status;
  FIBRECHANNEL_DEVICE_PATH  *Fibre;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Fibre  = (FIBRECHANNEL_DEVICE_PATH *)DevicePathNode;
  Status = AppendCSDNum (MappingItem, Fibre->WWN);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Fibre->Lun);
  }

  return Status;
}

/**
  DevicePathNode must be SerialUart type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialUart (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS        Status;
  UART_DEVICE_PATH  *Uart;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Uart   = (UART_DEVICE_PATH *)DevicePathNode;
  Status = AppendCSDNum (MappingItem, Uart->BaudRate);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Uart->DataBits);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Uart->Parity);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Uart->StopBits);
  }

  return Status;
}

/**
  DevicePathNode must be SerialUSB type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialUsb (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  USB_DEVICE_PATH           *Usb;
  EFI_USB_IO_PROTOCOL       *UsbIo;
  EFI_HANDLE                TempHandle;
  EFI_STATUS                Status;
  USB_INTERFACE_DESCRIPTOR  InterfaceDesc;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Usb    = (USB_DEVICE_PATH *)DevicePathNode;
  Status = AppendCSDNum (MappingItem, Usb->ParentPortNumber);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Usb->InterfaceNumber);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (PcdGetBool (PcdUsbExtendedDecode)) {
    Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &DevicePath, &TempHandle);
    UsbIo  = NULL;
    if (!EFI_ERROR (Status)) {
      Status = gBS->OpenProtocol (TempHandle, &gEfiUsbIoProtocolGuid, (VOID **)&UsbIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    }

    if (!EFI_ERROR (Status)) {
      ASSERT (UsbIo != NULL);
      Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &InterfaceDesc);
      if (!EFI_ERROR (Status)) {
        if ((InterfaceDesc.InterfaceClass == USB_MASS_STORE_CLASS) && (MappingItem->Mtd == MTDTypeUnknown)) {
          switch (InterfaceDesc.InterfaceSubClass) {
            case USB_MASS_STORE_SCSI:
              MappingItem->Mtd = MTDTypeHardDisk;
              break;
            case USB_MASS_STORE_8070I:
            case USB_MASS_STORE_UFI:
              MappingItem->Mtd = MTDTypeFloppy;
              break;
            case USB_MASS_STORE_8020I:
              MappingItem->Mtd = MTDTypeCDRom;
              break;
          }
        }
      }
    }
  }

  return Status;
}

/**
  DevicePathNode must be SerialVendor type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialVendor (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS          Status;
  VENDOR_DEVICE_PATH  *Vendor;
  SAS_DEVICE_PATH     *Sas;
  UINTN               TargetNameLength;
  UINTN               Index;
  CHAR16              *Buffer;
  CHAR16              *NewBuffer;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Vendor = (VENDOR_DEVICE_PATH *)DevicePathNode;
  Status = AppendCSDGuid (MappingItem, &Vendor->Guid);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (CompareGuid (&gEfiSasDevicePathGuid, &Vendor->Guid)) {
    Sas    = (SAS_DEVICE_PATH *)Vendor;
    Status = AppendCSDNum (MappingItem, Sas->SasAddress);
    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, Sas->Lun);
    }

    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, Sas->DeviceTopology);
    }

    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, Sas->RelativeTargetPort);
    }
  } else {
    TargetNameLength = MIN (DevicePathNodeLength (DevicePathNode) - sizeof (VENDOR_DEVICE_PATH), PcdGet32 (PcdShellVendorExtendedDecode));
    if (TargetNameLength != 0) {
      //
      // String is 2 chars per data byte, plus NULL terminator
      //
      Buffer = AllocateZeroPool (((TargetNameLength * 2) + 1) * sizeof (CHAR16));
      if (Buffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Build the string data
      //
      for (Index = 0; Index < TargetNameLength; Index++) {
        NewBuffer = CatSPrint (Buffer, L"%02x", *((UINT8 *)Vendor + sizeof (VENDOR_DEVICE_PATH) + Index));
        if (NewBuffer == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        Buffer = NewBuffer;
      }

      //
      // Append the new data block
      //
      if (!EFI_ERROR (Status)) {
        Status = AppendCSDStr (MappingItem, Buffer);
      }

      FreePool (Buffer);
    }
  }

  return Status;
}

/**
  DevicePathNode must be SerialLun type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialLun (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  DEVICE_LOGICAL_UNIT_DEVICE_PATH  *Lun;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Lun = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *)DevicePathNode;
  return AppendCSDNum (MappingItem, Lun->Lun);
}

/**
  DevicePathNode must be SerialSata type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialSata (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS        Status;
  SATA_DEVICE_PATH  *Sata;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Sata   = (SATA_DEVICE_PATH  *)DevicePathNode;
  Status = AppendCSDNum (MappingItem, Sata->HBAPortNumber);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Sata->PortMultiplierPortNumber);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Sata->Lun);
  }

  return Status;
}

/**
  DevicePathNode must be SerialSCSI type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialIScsi (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS         Status;
  ISCSI_DEVICE_PATH  *IScsi;
  UINT8              *IScsiTargetName;
  CHAR16             *TargetName;
  UINTN              TargetNameLength;
  UINTN              Index;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Status = EFI_SUCCESS;

  if (PcdGetBool (PcdShellDecodeIScsiMapNames)) {
    IScsi  = (ISCSI_DEVICE_PATH  *)DevicePathNode;
    Status = AppendCSDNum (MappingItem, IScsi->NetworkProtocol);
    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, IScsi->LoginOption);
    }

    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, IScsi->Lun);
    }

    if (!EFI_ERROR (Status)) {
      Status = AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag);
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }

    TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH);
    if (TargetNameLength > 0) {
      TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16));
      if (TargetName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
      } else {
        IScsiTargetName = (UINT8 *)(IScsi + 1);
        for (Index = 0; Index < TargetNameLength; Index++) {
          TargetName[Index] = (CHAR16)IScsiTargetName[Index];
        }

        Status = AppendCSDStr (MappingItem, TargetName);
        FreePool (TargetName);
      }
    }
  }

  return Status;
}

/**
  DevicePathNode must be SerialI20 type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialI2O (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  I2O_DEVICE_PATH  *DevicePath_I20;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  DevicePath_I20 = (I2O_DEVICE_PATH *)DevicePathNode;
  return AppendCSDNum (MappingItem, DevicePath_I20->Tid);
}

/**
  DevicePathNode must be Mac Address type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialMacAddr (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  MAC_ADDR_DEVICE_PATH  *Mac;
  UINTN                 HwAddressSize;
  UINTN                 Index;
  CHAR16                Buffer[64];
  CHAR16                *PBuffer;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Mac = (MAC_ADDR_DEVICE_PATH *)DevicePathNode;

  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
  if ((Mac->IfType == 0x01) || (Mac->IfType == 0x00)) {
    HwAddressSize = 6;
  }

  for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN)Mac->MacAddress.Addr[Index]);
  }

  return AppendCSDStr (MappingItem, Buffer);
}

/**
  DevicePathNode must be InfiniBand type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialInfiniBand (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS              Status;
  INFINIBAND_DEVICE_PATH  *InfiniBand;
  UINTN                   Index;
  CHAR16                  Buffer[64];
  CHAR16                  *PBuffer;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  InfiniBand = (INFINIBAND_DEVICE_PATH *)DevicePathNode;
  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN)InfiniBand->PortGid[Index]);
  }

  Status = AppendCSDStr (MappingItem, Buffer);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, InfiniBand->ServiceId);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, InfiniBand->TargetPortId);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, InfiniBand->DeviceId);
  }

  return Status;
}

/**
  DevicePathNode must be IPv4 type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialIPv4 (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS        Status;
  IPv4_DEVICE_PATH  *Ip;
  CHAR16            Buffer[10];

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Ip = (IPv4_DEVICE_PATH *)DevicePathNode;
  UnicodeSPrint (
    Buffer,
    0,
    L"%02x%02x%02x%02x",
    (UINTN)Ip->LocalIpAddress.Addr[0],
    (UINTN)Ip->LocalIpAddress.Addr[1],
    (UINTN)Ip->LocalIpAddress.Addr[2],
    (UINTN)Ip->LocalIpAddress.Addr[3]
    );
  Status = AppendCSDStr (MappingItem, Buffer);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Ip->LocalPort);
  }

  if (!EFI_ERROR (Status)) {
    UnicodeSPrint (
      Buffer,
      0,
      L"%02x%02x%02x%02x",
      (UINTN)Ip->RemoteIpAddress.Addr[0],
      (UINTN)Ip->RemoteIpAddress.Addr[1],
      (UINTN)Ip->RemoteIpAddress.Addr[2],
      (UINTN)Ip->RemoteIpAddress.Addr[3]
      );
    Status = AppendCSDStr (MappingItem, Buffer);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Ip->RemotePort);
  }

  return Status;
}

/**
  DevicePathNode must be IPv6 type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialIPv6 (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS        Status;
  IPv6_DEVICE_PATH  *Ip;
  UINTN             Index;
  CHAR16            Buffer[64];
  CHAR16            *PBuffer;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Ip = (IPv6_DEVICE_PATH *)DevicePathNode;
  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN)Ip->LocalIpAddress.Addr[Index]);
  }

  Status = AppendCSDStr (MappingItem, Buffer);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Ip->LocalPort);
  }

  if (!EFI_ERROR (Status)) {
    for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
      UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN)Ip->RemoteIpAddress.Addr[Index]);
    }

    Status = AppendCSDStr (MappingItem, Buffer);
  }

  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Ip->RemotePort);
  }

  return Status;
}

/**
  DevicePathNode must be SCSI type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialScsi (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS        Status;
  SCSI_DEVICE_PATH  *Scsi;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Scsi   = (SCSI_DEVICE_PATH *)DevicePathNode;
  Status = AppendCSDNum (MappingItem, Scsi->Pun);
  if (!EFI_ERROR (Status)) {
    Status = AppendCSDNum (MappingItem, Scsi->Lun);
  }

  return Status;
}

/**
  DevicePathNode must be 1394 type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerial1394 (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  F1394_DEVICE_PATH  *DevicePath_F1394;
  CHAR16             Buffer[20];

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  DevicePath_F1394 = (F1394_DEVICE_PATH *)DevicePathNode;
  UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);
  return AppendCSDStr (MappingItem, Buffer);
}

/**
  If the node is floppy type then populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
  @param[in] DevicePath       Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialAcpi (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  ACPI_HID_DEVICE_PATH  *Acpi;

  ASSERT (DevicePathNode != NULL);
  ASSERT (MappingItem != NULL);

  Acpi = (ACPI_HID_DEVICE_PATH *)DevicePathNode;
  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
    if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
      MappingItem->Mtd = MTDTypeFloppy;
      return AppendCSDNum (MappingItem, Acpi->UID);
    }
  }

  return EFI_SUCCESS;
}

/**
  Empty function used for unknown devices.

  @param[in] DevicePathNode       Ignored.
  @param[in] MappingItem          Ignored.
  @param[in] DevicePath           Ignored.

  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_SUCCESS             The appending was successful.
**/
EFI_STATUS
DevPathSerialDefault (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  return EFI_SUCCESS;
}

DEV_PATH_CONSIST_MAPPING_TABLE  DevPathConsistMappingTable[] = {
  {
    HARDWARE_DEVICE_PATH,
    HW_PCI_DP,
    DevPathSerialDefault,
    DevPathComparePci
  },
  {
    ACPI_DEVICE_PATH,
    ACPI_DP,
    DevPathSerialAcpi,
    DevPathCompareAcpi
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_ATAPI_DP,
    DevPathSerialAtapi,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_SCSI_DP,
    DevPathSerialScsi,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_FIBRECHANNEL_DP,
    DevPathSerialFibre,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_1394_DP,
    DevPathSerial1394,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_USB_DP,
    DevPathSerialUsb,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_I2O_DP,
    DevPathSerialI2O,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_MAC_ADDR_DP,
    DevPathSerialMacAddr,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_IPv4_DP,
    DevPathSerialIPv4,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_IPv6_DP,
    DevPathSerialIPv6,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_INFINIBAND_DP,
    DevPathSerialInfiniBand,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_UART_DP,
    DevPathSerialUart,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_VENDOR_DP,
    DevPathSerialVendor,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_DEVICE_LOGICAL_UNIT_DP,
    DevPathSerialLun,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_SATA_DP,
    DevPathSerialSata,
    DevPathCompareDefault
  },
  {
    MESSAGING_DEVICE_PATH,
    MSG_ISCSI_DP,
    DevPathSerialIScsi,
    DevPathCompareDefault
  },
  {
    MEDIA_DEVICE_PATH,
    MEDIA_HARDDRIVE_DP,
    DevPathSerialHardDrive,
    DevPathCompareDefault
  },
  {
    MEDIA_DEVICE_PATH,
    MEDIA_CDROM_DP,
    DevPathSerialCdRom,
    DevPathCompareDefault
  },
  {
    MEDIA_DEVICE_PATH,
    MEDIA_VENDOR_DP,
    DevPathSerialVendor,
    DevPathCompareDefault
  },
  {
    0,
    0,
    NULL,
    NULL
  }
};

/**
  Function to determine if a device path node is Hi or not.

  @param[in] DevicePathNode   The node to check.

  @retval TRUE    The node is Hi.
  @retval FALSE   The node is not Hi.
**/
BOOLEAN
IsHIDevicePathNode (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode
  )
{
  ACPI_HID_DEVICE_PATH  *Acpi;

  ASSERT (DevicePathNode != NULL);

  if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {
    return TRUE;
  }

  if (DevicePathNode->Type == ACPI_DEVICE_PATH) {
    Acpi = (ACPI_HID_DEVICE_PATH *)DevicePathNode;
    switch (EISA_ID_TO_NUM (Acpi->HID)) {
      case 0x0301:
      case 0x0401:
      case 0x0501:
      case 0x0604:
        return FALSE;
    }

    return TRUE;
  }

  return FALSE;
}

/**
  Function to convert a standard device path structure into a Hi version.

  @param[in] DevicePath   The device path to convert.

  @return   the device path portion that is Hi.
**/
EFI_DEVICE_PATH_PROTOCOL *
GetHIDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  UINTN                     NonHIDevicePathNodeCount;
  UINTN                     Index;
  EFI_DEV_PATH              Node;
  EFI_DEVICE_PATH_PROTOCOL  *HIDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

  ASSERT (DevicePath != NULL);

  NonHIDevicePathNodeCount = 0;

  HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
  SetDevicePathEndNode (HIDevicePath);

  Node.DevPath.Type      = END_DEVICE_PATH_TYPE;
  Node.DevPath.SubType   = END_INSTANCE_DEVICE_PATH_SUBTYPE;
  Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);
  Node.DevPath.Length[1] = 0;

  while (!IsDevicePathEnd (DevicePath)) {
    if (IsHIDevicePathNode (DevicePath)) {
      for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {
        TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);
        FreePool (HIDevicePath);
        HIDevicePath = TempDevicePath;
      }

      TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);
      FreePool (HIDevicePath);
      HIDevicePath = TempDevicePath;
    } else {
      NonHIDevicePathNodeCount++;
    }

    //
    // Next device path node
    //
    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)NextDevicePathNode (DevicePath);
  }

  return HIDevicePath;
}

/**
  Function to walk the device path looking for a dumpable node.

  @param[in] MappingItem      The Item to fill with data.
  @param[in] DevicePath       The path of the item to get data on.

  @return EFI_SUCCESS         Always returns success.
**/
EFI_STATUS
GetDeviceConsistMappingInfo (
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem,
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_STATUS                Status;
  SERIAL_DECODE_FUNCTION    SerialFun;
  UINTN                     Index;
  EFI_DEVICE_PATH_PROTOCOL  *OriginalDevicePath;

  ASSERT (DevicePath != NULL);
  ASSERT (MappingItem != NULL);

  SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);
  OriginalDevicePath = DevicePath;

  while (!IsDevicePathEnd (DevicePath)) {
    //
    // Find the handler to dump this device path node and
    // initialize with generic function in case nothing is found
    //
    for (SerialFun = DevPathSerialDefault, Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {
      if ((DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type) &&
          (DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType)
          )
      {
        SerialFun = DevPathConsistMappingTable[Index].SerialFun;
        break;
      }
    }

    Status = SerialFun (DevicePath, MappingItem, OriginalDevicePath);
    if (EFI_ERROR (Status)) {
      SHELL_FREE_NON_NULL (MappingItem->Csd.Str);
      return Status;
    }

    //
    // Next device path node
    //
    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)NextDevicePathNode (DevicePath);
  }

  return EFI_SUCCESS;
}

/**
  Function to initialize the table for creating consistent map names.

  @param[out] Table             The pointer to pointer to pointer to DevicePathProtocol object.

  @retval EFI_SUCCESS           The table was created successfully.
**/
EFI_STATUS
EFIAPI
ShellCommandConsistMappingInitialize (
  OUT EFI_DEVICE_PATH_PROTOCOL  ***Table
  )
{
  EFI_HANDLE                       *HandleBuffer;
  UINTN                            HandleNum;
  UINTN                            HandleLoop;
  EFI_DEVICE_PATH_PROTOCOL         **TempTable;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL         *HIDevicePath;
  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFileSystem;
  UINTN                            Index;
  EFI_STATUS                       Status;

  HandleBuffer = NULL;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDevicePathProtocolGuid,
                  NULL,
                  &HandleNum,
                  &HandleBuffer
                  );
  ASSERT_EFI_ERROR (Status);

  TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
  if (TempTable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (HandleLoop = 0; HandleLoop < HandleNum; HandleLoop++) {
    DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);
    if (DevicePath == NULL) {
      continue;
    }

    HIDevicePath = GetHIDevicePath (DevicePath);
    if (HIDevicePath == NULL) {
      continue;
    }

    Status = gBS->HandleProtocol (
                    HandleBuffer[HandleLoop],
                    &gEfiBlockIoProtocolGuid,
                    (VOID **)&BlockIo
                    );
    if (EFI_ERROR (Status)) {
      Status = gBS->HandleProtocol (
                      HandleBuffer[HandleLoop],
                      &gEfiSimpleFileSystemProtocolGuid,
                      (VOID **)&SimpleFileSystem
                      );
      if (EFI_ERROR (Status)) {
        FreePool (HIDevicePath);
        continue;
      }
    }

    for (Index = 0; TempTable[Index] != NULL; Index++) {
      if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {
        FreePool (HIDevicePath);
        break;
      }
    }

    if (TempTable[Index] == NULL) {
      TempTable[Index] = HIDevicePath;
    }
  }

  for (Index = 0; TempTable[Index] != NULL; Index++) {
  }

  PerformQuickSort (TempTable, Index, sizeof (EFI_DEVICE_PATH_PROTOCOL *), DevicePathCompare);
  *Table = TempTable;

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return EFI_SUCCESS;
}

/**
  Function to uninitialize the table for creating consistent map names.

  The parameter must have been received from ShellCommandConsistMappingInitialize.

  @param[out] Table             The pointer to pointer to DevicePathProtocol object.

  @retval EFI_SUCCESS           The table was deleted successfully.
**/
EFI_STATUS
EFIAPI
ShellCommandConsistMappingUnInitialize (
  EFI_DEVICE_PATH_PROTOCOL  **Table
  )
{
  UINTN  Index;

  ASSERT (Table  != NULL);

  for (Index = 0; Table[Index] != NULL; Index++) {
    FreePool (Table[Index]);
  }

  FreePool (Table);
  return EFI_SUCCESS;
}

/**
  Create a consistent mapped name for the device specified by DevicePath
  based on the Table.

  This must be called after ShellCommandConsistMappingInitialize() and
  before ShellCommandConsistMappingUnInitialize() is called.

  @param[in] DevicePath   The pointer to the dev path for the device.
  @param[in] Table        The Table of mapping information.

  @retval NULL            A consistent mapped name could not be created.
  @return                 A pointer to a string allocated from pool with the device name.
**/
CHAR16 *
EFIAPI
ShellCommandConsistMappingGenMappingName (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN EFI_DEVICE_PATH_PROTOCOL  **Table
  )
{
  EFI_STATUS                   Status;
  POOL_PRINT                   Str;
  DEVICE_CONSIST_MAPPING_INFO  MappingInfo;
  EFI_DEVICE_PATH_PROTOCOL     *HIDevicePath;
  UINTN                        Index;

  ASSERT (DevicePath         != NULL);
  ASSERT (Table  != NULL);

  HIDevicePath = GetHIDevicePath (DevicePath);
  if (HIDevicePath == NULL) {
    return NULL;
  }

  for (Index = 0; Table[Index] != NULL; Index++) {
    if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {
      break;
    }
  }

  FreePool (HIDevicePath);
  if (Table[Index] == NULL) {
    return NULL;
  }

  MappingInfo.Hi      = Index;
  MappingInfo.Mtd     = MTDTypeUnknown;
  MappingInfo.Digital = FALSE;

  Status = GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  SetMem (&Str, sizeof (Str), 0);
  for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {
    if (MappingInfo.Mtd == mMTDName[Index].MTDType) {
      break;
    }
  }

  if (mMTDName[Index].MTDType != MTDTypeEnd) {
    Status = CatPrint (&Str, L"%s", mMTDName[Index].Name);
  }

  if (!EFI_ERROR (Status)) {
    Status = CatPrint (&Str, L"%d", (UINTN)MappingInfo.Hi);
  }

  if (!EFI_ERROR (Status) && (MappingInfo.Csd.Str != NULL)) {
    Status = CatPrint (&Str, L"%s", MappingInfo.Csd.Str);
    FreePool (MappingInfo.Csd.Str);
  }

  if (!EFI_ERROR (Status) && (Str.Str != NULL)) {
    Status = CatPrint (&Str, L":");
  }

  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (Str.Str);
    return NULL;
  }

  return Str.Str;
}

/**
  Function to search the list of mappings for the node on the list based on the key.

  @param[in] MapKey       String Key to search for on the map

  @return the node on the list.
**/
SHELL_MAP_LIST *
EFIAPI
ShellCommandFindMapItem (
  IN CONST CHAR16  *MapKey
  )
{
  SHELL_MAP_LIST  *MapListItem;

  for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
        ; !IsNull (&gShellMapList.Link, &MapListItem->Link)
        ; MapListItem = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &MapListItem->Link)
        )
  {
    if (gUnicodeCollation->StriColl (gUnicodeCollation, MapListItem->MapName, (CHAR16 *)MapKey) == 0) {
      return (MapListItem);
    }
  }

  return (NULL);
}
