/** @file
  Main file for support of shell consist mapping.

  Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution. The full text of the license may be found at
  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 "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);
}


