/** @file
  Main file for map shell level 2 command.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellLevel2CommandsLib.h"
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/BlockIo.h>
#include <Library/DevicePathLib.h>
#include <Library/HandleParsingLib.h>
#include <Library/SortLib.h>

/**
  Determine if a string has only numbers and letters.

  This is useful for such things as Map names which can only be letters and numbers.

  @param[in] String       pointer to the string to analyze,
  @param[in] Len          Number of characters to analyze.

  @retval TRUE            String has only numbers and letters
  @retval FALSE           String has at least one other character.
**/
BOOLEAN
IsNumberLetterOnly (
  IN CONST CHAR16  *String,
  IN CONST UINTN   Len
  )
{
  UINTN  Count;

  for (Count = 0; Count < Len && String != NULL && *String != CHAR_NULL; String++, Count++) {
    if (!(((*String >= L'a') && (*String <= L'z')) ||
          ((*String >= L'A') && (*String <= L'Z')) ||
          ((*String >= L'0') && (*String <= L'9')))
        )
    {
      return (FALSE);
    }
  }

  return (TRUE);
}

/**
  Do a search in the Target delimited list.

  @param[in] List         The list to seatch in.
  @param[in] MetaTarget   The item to search for. MetaMatching supported.
  @param[out] FullName    Optional pointer to an allocated buffer containing
                          the match.
  @param[in] Meta         TRUE to use MetaMatching.
  @param[in] SkipTrailingNumbers  TRUE to allow for numbers after the MetaTarget.
  @param[in] Target       The single character that delimits list
                          items (";" normally).
**/
BOOLEAN
SearchList (
  IN CONST CHAR16   *List,
  IN CONST CHAR16   *MetaTarget,
  OUT CHAR16        **FullName OPTIONAL,
  IN CONST BOOLEAN  Meta,
  IN CONST BOOLEAN  SkipTrailingNumbers,
  IN CONST CHAR16   *Target

  )
{
  CHAR16        *TempList;
  CONST CHAR16  *ListWalker;
  BOOLEAN       Result;
  CHAR16        *TempSpot;

  for (ListWalker = List, TempList = NULL
       ; ListWalker != NULL && *ListWalker != CHAR_NULL
       ;
       )
  {
    TempList = StrnCatGrow (&TempList, NULL, ListWalker, 0);
    if (TempList == NULL) {
      ASSERT (TempList != NULL);
      return (FALSE);
    }

    TempSpot = StrStr (TempList, Target);
    if (TempSpot != NULL) {
      *TempSpot = CHAR_NULL;
    }

    while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter (TempList[StrLen (TempList)-1]) || TempList[StrLen (TempList)-1] == L':')) {
      TempList[StrLen (TempList)-1] = CHAR_NULL;
    }

    ListWalker = StrStr (ListWalker, Target);
    while (ListWalker != NULL && *ListWalker == *Target) {
      ListWalker++;
    }

    if (Meta) {
      Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget);
    } else {
      Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0);
    }

    if (Result) {
      if (FullName != NULL) {
        *FullName = TempList;
      } else {
        FreePool (TempList);
      }

      return (TRUE);
    }

    FreePool (TempList);
    TempList = NULL;
  }

  return (FALSE);
}

/**
  Determine what type of device is represented and return it's string.  The
  string is in allocated memory and must be callee freed.  The HII is is listed below.
  The actual string cannot be determined.

  @param[in] DevicePath     The device to analyze.

  @retval STR_MAP_MEDIA_UNKNOWN   The media type is unknown.
  @retval STR_MAP_MEDIA_HARDDISK  The media is a hard drive.
  @retval STR_MAP_MEDIA_CDROM     The media is a CD ROM.
  @retval STR_MAP_MEDIA_FLOPPY    The media is a floppy drive.
**/
CHAR16 *
GetDeviceMediaType (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  ACPI_HID_DEVICE_PATH  *Acpi;

  //
  //  Parse the device path:
  //  Devicepath sub type                 mediatype
  //    MEDIA_HANRDDRIVE_DP      ->       Hard Disk
  //    MEDIA_CDROM_DP           ->       CD Rom
  //    Acpi.HID = 0X0604        ->       Floppy
  //
  if (NULL == DevicePath) {
    return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);
  }

  for ( ; !IsDevicePathEndType (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
    if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {
      switch (DevicePathSubType (DevicePath)) {
        case MEDIA_HARDDRIVE_DP:
          return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_HARDDISK), NULL);
        case MEDIA_CDROM_DP:
          return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_CDROM), NULL);
      }
    } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) {
      Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;
      if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
        return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_FLOPPY), NULL);
      }
    }
  }

  return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);
}

/**
  Function to detemine if a handle has removable storage.

  @param[in] DevicePath             DevicePath to test.

  @retval TRUE                      The handle has removable storage.
  @retval FALSE                     The handle does not have removable storage.
**/
BOOLEAN
IsRemoveableDevice (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  if (NULL == DevicePath) {
    return FALSE;
  }

  while (!IsDevicePathEndType (DevicePath)) {
    if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) {
      switch (DevicePathSubType (DevicePath)) {
        case MSG_USB_DP:
        case MSG_SCSI_DP:
          return TRUE;
        default:
          return FALSE;
      }
    }

    DevicePath = NextDevicePathNode (DevicePath);
  }

  return FALSE;
}

/**
  Function to detemine if a something on the map list matches.

  @param[in] MapList          The pointer to the list to test.
  @param[in] Specific         The pointer to a specific name to test for.
  @param[in] TypeString       The pointer to the list of types.
  @param[in] Normal           Always show normal mappings.
  @param[in] Consist          Always show consistent mappings.

  @retval TRUE                The map should be displayed.
  @retval FALSE               The map should not be displayed.
**/
BOOLEAN
MappingListHasType (
  IN CONST CHAR16   *MapList,
  IN CONST CHAR16   *Specific,
  IN CONST CHAR16   *TypeString,
  IN CONST BOOLEAN  Normal,
  IN CONST BOOLEAN  Consist
  )
{
  CHAR16         *NewSpecific;
  RETURN_STATUS  Status;
  UINTN          Length;

  //
  // specific has priority
  //
  if (Specific != NULL) {
    Length = StrLen (Specific);
    //
    // Allocate enough buffer for Specific and potential ":"
    //
    NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16));
    if (NewSpecific == NULL) {
      return FALSE;
    }

    StrCpyS (NewSpecific, Length + 2, Specific);
    if (Specific[Length - 1] != L':') {
      Status = StrnCatS (NewSpecific, Length + 2, L":", StrLen (L":"));
      if (EFI_ERROR (Status)) {
        FreePool (NewSpecific);
        return FALSE;
      }
    }

    if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {
      FreePool (NewSpecific);
      return (TRUE);
    }

    FreePool (NewSpecific);
  }

  if (  Consist
     && (Specific == NULL)
     && (  SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";")
        || SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";")
        || SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";")
        || SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";")))
  {
    return (TRUE);
  }

  if (  Normal
     && (Specific == NULL)
     && (  SearchList (MapList, L"FS", NULL, FALSE, TRUE, L";")
        || SearchList (MapList, L"BLK", NULL, FALSE, TRUE, L";")))
  {
    return (TRUE);
  }

  if ((TypeString != NULL) && SearchList (MapList, TypeString, NULL, TRUE, TRUE, L";")) {
    return (TRUE);
  }

  return (FALSE);
}

/**
  Display a single map line for device Handle if conditions are met.

  @param[in] Verbose                TRUE to display (extra) verbose information.
  @param[in] Consist                TRUE to display consistent mappings.
  @param[in] Normal                 TRUE to display normal (not consist) mappings.
  @param[in] TypeString             pointer to string of filter types.
  @param[in] SFO                    TRUE to display output in Standard Output Format.
  @param[in] Specific               pointer to string for specific map to display.
  @param[in] Handle                 The handle to display from.

  @retval EFI_SUCCESS               The mapping was displayed.
**/
EFI_STATUS
PerformSingleMappingDisplay (
  IN CONST BOOLEAN     Verbose,
  IN CONST BOOLEAN     Consist,
  IN CONST BOOLEAN     Normal,
  IN CONST CHAR16      *TypeString,
  IN CONST BOOLEAN     SFO,
  IN CONST CHAR16      *Specific OPTIONAL,
  IN CONST EFI_HANDLE  Handle
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;
  CONST CHAR16              *MapList;
  CHAR16                    *CurrentName;
  CHAR16                    *MediaType;
  CHAR16                    *DevPathString;
  CHAR16                    *TempSpot;
  CHAR16                    *Alias;
  UINTN                     TempLen;
  BOOLEAN                   Removable;
  CONST CHAR16              *TempSpot2;

  Alias       = NULL;
  TempSpot2   = NULL;
  CurrentName = NULL;
  DevPath     = DevicePathFromHandle (Handle);
  DevPathCopy = DevPath;
  MapList     = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);
  if (MapList == NULL) {
    return EFI_NOT_FOUND;
  }

  if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) {
    return EFI_NOT_FOUND;
  }

  if (Normal || !Consist) {
    //
    // need the Normal here since people can use both on command line.  otherwise unused.
    //

    //
    // Allocate a name
    //
    CurrentName = NULL;
    CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);
    if (CurrentName == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    //
    // Chop off the other names that become "Alias(s)"
    // leaving just the normal name
    //
    TempSpot = StrStr (CurrentName, L";");
    if (TempSpot != NULL) {
      *TempSpot = CHAR_NULL;
    }
  } else {
    CurrentName = NULL;

    //
    // Skip the first name.  This is the standard name.
    //
    TempSpot = StrStr (MapList, L";");
    if (TempSpot != NULL) {
      TempSpot++;
    }

    SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");
    if (CurrentName == NULL) {
      SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");
    }

    if (CurrentName == NULL) {
      SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");
    }

    if (CurrentName == NULL) {
      SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";");
    }

    if (CurrentName == NULL) {
      //
      // We didnt find anything, so just the first one in the list...
      //
      CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);
      if (CurrentName == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }

      TempSpot = StrStr (CurrentName, L";");
      if (TempSpot != NULL) {
        *TempSpot = CHAR_NULL;
      }
    } else {
      Alias = StrnCatGrow (&Alias, 0, MapList, 0);
      if (Alias == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      TempSpot = StrStr (Alias, CurrentName);
      if (TempSpot != NULL) {
        TempSpot2 = StrStr (TempSpot, L";");
        if (TempSpot2 != NULL) {
          TempSpot2++; // Move past ";" from CurrentName
          CopyMem (TempSpot, TempSpot2, StrSize (TempSpot2));
        } else {
          *TempSpot = CHAR_NULL;
        }
      }

      if (Alias[StrLen (Alias)-1] == L';') {
        Alias[StrLen (Alias)-1] = CHAR_NULL;
      }
    }
  }

  DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE);
  TempLen       = StrLen (CurrentName);
  if (!SFO) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_MAP_ENTRY),
      gShellLevel2HiiHandle,
      CurrentName,
      Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""),
      DevPathString
      );
    if (Verbose) {
      //
      // also print handle, media type, removable (y/n), and current directory
      //
      MediaType = GetDeviceMediaType (DevPath);
      if (((TypeString != NULL) && (MediaType != NULL) && (StrStr (TypeString, MediaType) != NULL)) || (TypeString == NULL)) {
        Removable = IsRemoveableDevice (DevPath);
        TempSpot2 = ShellGetCurrentDir (CurrentName);
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),
          gShellLevel2HiiHandle,
          ConvertHandleToHandleIndex (Handle),
          MediaType,
          Removable ? L"Yes" : L"No",
          TempSpot2
          );
      }

      SHELL_FREE_NON_NULL (MediaType);
    }
  } else {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_MAP_SFO_MAPPINGS),
      gShellLevel2HiiHandle,
      CurrentName,
      DevPathString,
      Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"")
      );
  }

  SHELL_FREE_NON_NULL (DevPathString);
  SHELL_FREE_NON_NULL (CurrentName);
  SHELL_FREE_NON_NULL (Alias);
  return EFI_SUCCESS;
}

/**
  Delete Specific from the list of maps for device Handle.

  @param[in] Specific   The name to delete.
  @param[in] Handle     The device to look on.

  @retval EFI_SUCCESS     The delete was successful.
  @retval EFI_NOT_FOUND   Name was not a map on Handle.
**/
EFI_STATUS
PerformSingleMappingDelete (
  IN CONST CHAR16      *Specific,
  IN CONST EFI_HANDLE  Handle
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;
  CONST CHAR16              *MapList;
  CHAR16                    *CurrentName;

  DevPath     = DevicePathFromHandle (Handle);
  DevPathCopy = DevPath;
  MapList     = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);
  CurrentName = NULL;

  if (MapList == NULL) {
    return (EFI_NOT_FOUND);
  }

  //
  // if there is a specific and its not on the list...
  //
  if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {
    return (EFI_NOT_FOUND);
  }

  return (gEfiShellProtocol->SetMap (NULL, CurrentName));
}

CONST CHAR16  Cd[]   = L"cd*";
CONST CHAR16  Hd[]   = L"hd*";
CONST CHAR16  Fp[]   = L"fp*";
CONST CHAR16  AnyF[] = L"F*";

/**
  Function to display mapping information to the user.

  If Specific is specified then Consist and Normal will be ignored since information will
  be printed for the specific item only.

  @param[in] Verbose                TRUE to display (extra) verbose information.
  @param[in] Consist                TRUE to display consistent mappings.
  @param[in] Normal                 TRUE to display normal (not consist) mappings.
  @param[in] TypeString             Pointer to string of filter types.
  @param[in] SFO                    TRUE to display output in Standard Output Format.
  @param[in] Specific               Pointer to string for specific map to display.
  @param[in] Header                 TRUE to print the header block.

  @retval SHELL_SUCCESS               The display was printed.
  @retval SHELL_INVALID_PARAMETER     One of Consist or Normal must be TRUE if no Specific.

**/
SHELL_STATUS
PerformMappingDisplay (
  IN CONST BOOLEAN  Verbose,
  IN CONST BOOLEAN  Consist,
  IN CONST BOOLEAN  Normal,
  IN CONST CHAR16   *TypeString,
  IN CONST BOOLEAN  SFO,
  IN CONST CHAR16   *Specific OPTIONAL,
  IN CONST BOOLEAN  Header
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  *HandleBuffer;
  UINTN       BufferSize;
  UINTN       LoopVar;
  CHAR16      *Test;
  BOOLEAN     Found;

  if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
    return (SHELL_INVALID_PARAMETER);
  }

  if (TypeString != NULL) {
    Test = (CHAR16 *)Cd;
    if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
      Test = (CHAR16 *)Hd;
      if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
        Test = (CHAR16 *)Fp;
        if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString);
          return (SHELL_INVALID_PARAMETER);
        }
      } else if (Test == NULL) {
        Test = (CHAR16 *)AnyF;
      }
    }
  } else {
    Test = NULL;
  }

  if (Header) {
    //
    // Print the header
    //
    if (!SFO) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");
    }
  }

  BufferSize   = 0;
  HandleBuffer = NULL;

  //
  // Look up all SimpleFileSystems in the platform
  //
  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiSimpleFileSystemProtocolGuid,
                  NULL,
                  &BufferSize,
                  HandleBuffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocateZeroPool (BufferSize);
    if (HandleBuffer == NULL) {
      return (SHELL_OUT_OF_RESOURCES);
    }

    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiSimpleFileSystemProtocolGuid,
                    NULL,
                    &BufferSize,
                    HandleBuffer
                    );
  }

  //
  // Get the map name(s) for each one.
  //
  for ( LoopVar = 0, Found = FALSE
        ; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL
        ; LoopVar++
        )
  {
    Status = PerformSingleMappingDisplay (
               Verbose,
               Consist,
               Normal,
               Test,
               SFO,
               Specific,
               HandleBuffer[LoopVar]
               );
    if (!EFI_ERROR (Status)) {
      Found = TRUE;
    }
  }

  //
  // Look up all BlockIo in the platform
  //
  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  &BufferSize,
                  HandleBuffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    SHELL_FREE_NON_NULL (HandleBuffer);
    HandleBuffer = AllocateZeroPool (BufferSize);
    if (HandleBuffer == NULL) {
      return (SHELL_OUT_OF_RESOURCES);
    }

    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiBlockIoProtocolGuid,
                    NULL,
                    &BufferSize,
                    HandleBuffer
                    );
  }

  if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) {
    //
    // Get the map name(s) for each one.
    //
    for ( LoopVar = 0
          ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
          ; LoopVar++
          )
    {
      //
      // Skip any that were already done...
      //
      if (gBS->OpenProtocol (
                 HandleBuffer[LoopVar],
                 &gEfiSimpleFileSystemProtocolGuid,
                 NULL,
                 gImageHandle,
                 NULL,
                 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                 ) == EFI_SUCCESS)
      {
        continue;
      }

      Status = PerformSingleMappingDisplay (
                 Verbose,
                 Consist,
                 Normal,
                 Test,
                 SFO,
                 Specific,
                 HandleBuffer[LoopVar]
                 );
      if (!EFI_ERROR (Status)) {
        Found = TRUE;
      }
    }

    FreePool (HandleBuffer);
  }

  if (!Found) {
    if (Specific != NULL) {
      ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific);
    } else {
      ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");
    }
  }

  return (SHELL_SUCCESS);
}

/**
  Perform a mapping display and parse for multiple types in the TypeString.

  @param[in] Verbose      TRUE to use verbose output.
  @param[in] Consist      TRUE to display consistent names.
  @param[in] Normal       TRUE to display normal names.
  @param[in] TypeString   An optional comma-delimited list of types.
  @param[in] SFO          TRUE to display in SFO format.  See Spec.
  @param[in] Specific     An optional specific map name to display alone.

  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
  @retval SHELL_SUCCESS             The display was successful.
  @sa PerformMappingDisplay
**/
SHELL_STATUS
PerformMappingDisplay2 (
  IN CONST BOOLEAN  Verbose,
  IN CONST BOOLEAN  Consist,
  IN CONST BOOLEAN  Normal,
  IN CONST CHAR16   *TypeString,
  IN CONST BOOLEAN  SFO,
  IN CONST CHAR16   *Specific OPTIONAL
  )
{
  CONST CHAR16  *TypeWalker;
  SHELL_STATUS  ShellStatus;
  CHAR16        *Comma;

  if (TypeString == NULL) {
    return (PerformMappingDisplay (Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));
  }

  ShellStatus = SHELL_SUCCESS;
  for (TypeWalker = TypeString; TypeWalker != NULL && *TypeWalker != CHAR_NULL;) {
    Comma = StrStr (TypeWalker, L",");
    if (Comma == NULL) {
      if (ShellStatus == SHELL_SUCCESS) {
        ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
      } else {
        PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
      }

      break;
    } else {
      *Comma = CHAR_NULL;
      if (ShellStatus == SHELL_SUCCESS) {
        ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
      } else {
        PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
      }

      *Comma     = L',';
      TypeWalker = Comma + 1;
    }
  }

  return (ShellStatus);
}

/**
  Delete a specific map.

  @param[in] Specific  The pointer to the name of the map to delete.

  @retval EFI_INVALID_PARAMETER     Specific was NULL.
  @retval EFI_SUCCESS               The operation was successful.
  @retval EFI_NOT_FOUND             Specific could not be found.
**/
EFI_STATUS
PerformMappingDelete (
  IN CONST CHAR16  *Specific
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  *HandleBuffer;
  UINTN       BufferSize;
  UINTN       LoopVar;
  BOOLEAN     Deleted;

  if (Specific == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  BufferSize   = 0;
  HandleBuffer = NULL;
  Deleted      = FALSE;

  //
  // Look up all SimpleFileSystems in the platform
  //
  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiDevicePathProtocolGuid,
                  NULL,
                  &BufferSize,
                  HandleBuffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocateZeroPool (BufferSize);
    if (HandleBuffer == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiDevicePathProtocolGuid,
                    NULL,
                    &BufferSize,
                    HandleBuffer
                    );
  }

  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (HandleBuffer);
    return (Status);
  }

  if (HandleBuffer != NULL) {
    //
    // Get the map name(s) for each one.
    //
    for ( LoopVar = 0
          ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
          ; LoopVar++
          )
    {
      if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
        Deleted = TRUE;
      }
    }
  }

  //
  // Look up all BlockIo in the platform
  //
  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  &BufferSize,
                  HandleBuffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    FreePool (HandleBuffer);
    HandleBuffer = AllocateZeroPool (BufferSize);
    if (HandleBuffer == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiBlockIoProtocolGuid,
                    NULL,
                    &BufferSize,
                    HandleBuffer
                    );
  }

  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (HandleBuffer);
    return (Status);
  }

  if (HandleBuffer != NULL) {
    //
    // Get the map name(s) for each one.
    //
    for ( LoopVar = 0
          ; LoopVar < BufferSize / sizeof (EFI_HANDLE)
          ; LoopVar++
          )
    {
      //
      // Skip any that were already done...
      //
      if (gBS->OpenProtocol (
                 HandleBuffer[LoopVar],
                 &gEfiDevicePathProtocolGuid,
                 NULL,
                 gImageHandle,
                 NULL,
                 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                 ) == EFI_SUCCESS)
      {
        continue;
      }

      if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
        Deleted = TRUE;
      }
    }
  }

  SHELL_FREE_NON_NULL (HandleBuffer);
  if (!Deleted) {
    return (EFI_NOT_FOUND);
  }

  return (EFI_SUCCESS);
}

/**
  function to add a mapping from mapping.

  This function will get the device path associated with the mapping and call SetMap.

  @param[in] Map         The Map to add a mapping for
  @param[in] SName       The name of the new mapping

  @retval SHELL_SUCCESS             the mapping was added
  @retval SHELL_INVALID_PARAMETER   the device path for Map could not be retrieved.
  @return                           Shell version of a return value from EfiShellProtocol->SetMap

**/
SHELL_STATUS
AddMappingFromMapping (
  IN CONST CHAR16  *Map,
  IN CONST CHAR16  *SName
  )
{
  CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_STATUS                      Status;
  CHAR16                          *NewSName;
  RETURN_STATUS                   StrRetStatus;

  NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
  if (NewSName == NULL) {
    return (SHELL_OUT_OF_RESOURCES);
  }

  if (NewSName[StrLen (NewSName)-1] != L':') {
    StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));
    if (EFI_ERROR (StrRetStatus)) {
      FreePool (NewSName);
      return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));
    }
  }

  if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
    FreePool (NewSName);
    return (SHELL_INVALID_PARAMETER);
  }

  DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map);
  if (DevPath == NULL) {
    FreePool (NewSName);
    return (SHELL_INVALID_PARAMETER);
  }

  Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
  FreePool (NewSName);
  if (EFI_ERROR (Status)) {
    return (SHELL_DEVICE_ERROR);
  }

  return (SHELL_SUCCESS);
}

/**
  function to add a mapping from an EFI_HANDLE.

  This function will get the device path associated with the Handle and call SetMap.

  @param[in] Handle       The handle to add a mapping for
  @param[in] SName        The name of the new mapping

  @retval SHELL_SUCCESS           the mapping was added
  @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.
  @return                         Shell version of a return value from either
                                  gBS->OpenProtocol or EfiShellProtocol->SetMap

**/
SHELL_STATUS
AddMappingFromHandle (
  IN CONST EFI_HANDLE  Handle,
  IN CONST CHAR16      *SName
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_STATUS                Status;
  CHAR16                    *NewSName;
  RETURN_STATUS             StrRetStatus;

  NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
  if (NewSName == NULL) {
    return (SHELL_OUT_OF_RESOURCES);
  }

  if (NewSName[StrLen (NewSName)-1] != L':') {
    StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));
    if (EFI_ERROR (StrRetStatus)) {
      FreePool (NewSName);
      return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));
    }
  }

  if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
    FreePool (NewSName);
    return (SHELL_INVALID_PARAMETER);
  }

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevPath,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    FreePool (NewSName);
    return (SHELL_DEVICE_ERROR);
  }

  Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
  FreePool (NewSName);
  if (EFI_ERROR (Status)) {
    return (SHELL_DEVICE_ERROR);
  }

  return (SHELL_SUCCESS);
}

STATIC CONST SHELL_PARAM_ITEM  MapParamList[] = {
  { L"-d",   TypeValue },
  { L"-r",   TypeFlag  },
  { L"-v",   TypeFlag  },
  { L"-c",   TypeFlag  },
  { L"-f",   TypeFlag  },
  { L"-u",   TypeFlag  },
  { L"-t",   TypeValue },
  { L"-sfo", TypeValue },
  { NULL,    TypeMax   }
};

/**
  The routine issues dummy read for every physical block device to cause
  the BlockIo re-installed if media change happened.
**/
VOID
ProbeForMediaChange (
  VOID
  )
{
  EFI_STATUS             Status;
  UINTN                  HandleCount;
  EFI_HANDLE             *Handles;
  EFI_BLOCK_IO_PROTOCOL  *BlockIo;
  UINTN                  Index;

  gBS->LocateHandleBuffer (
         ByProtocol,
         &gEfiBlockIoProtocolGuid,
         NULL,
         &HandleCount,
         &Handles
         );
  //
  // Probe for media change for every physical block io
  //
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    Handles[Index],
                    &gEfiBlockIoProtocolGuid,
                    (VOID **)&BlockIo
                    );
    if (!EFI_ERROR (Status)) {
      if (!BlockIo->Media->LogicalPartition) {
        //
        // Per spec:
        //   The function (ReadBlocks) must return EFI_NO_MEDIA or
        //   EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe
        //   for changes in media state.
        //
        BlockIo->ReadBlocks (
                   BlockIo,
                   BlockIo->Media->MediaId,
                   0,
                   0,
                   NULL
                   );
      }
    }
  }
}

/** Main function of the 'Map' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdMap (
  LIST_ENTRY  *Package
  )
{
  EFI_STATUS    Status;
  CONST CHAR16  *SName;
  CONST CHAR16  *Mapping;
  EFI_HANDLE    MapAsHandle;
  SHELL_STATUS  ShellStatus;
  BOOLEAN       SfoMode;
  BOOLEAN       ConstMode;
  BOOLEAN       NormlMode;
  CONST CHAR16  *Param1;
  CONST CHAR16  *TypeString;
  UINTN         TempStringLength;

  Mapping     = NULL;
  SName       = NULL;
  ShellStatus = SHELL_SUCCESS;
  MapAsHandle = NULL;

  //
  // check for "-?"
  //
  SfoMode   = ShellCommandLineGetFlag (Package, L"-sfo");
  ConstMode = ShellCommandLineGetFlag (Package, L"-c");
  NormlMode = ShellCommandLineGetFlag (Package, L"-f");
  if (ShellCommandLineGetFlag (Package, L"-?")) {
    ASSERT (FALSE);
    return ShellStatus;
  } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");
    return SHELL_INVALID_PARAMETER;
  }

  //
  // Deleting a map name...
  //
  if (ShellCommandLineGetFlag (Package, L"-d")) {
    if (  ShellCommandLineGetFlag (Package, L"-r")
       || ShellCommandLineGetFlag (Package, L"-v")
       || ConstMode
       || NormlMode
       || ShellCommandLineGetFlag (Package, L"-u")
       || ShellCommandLineGetFlag (Package, L"-t")
          )
    {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      SName = ShellCommandLineGetValue (Package, L"-d");
      if (SName != NULL) {
        Status = PerformMappingDelete (SName);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_ACCESS_DENIED) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
            ShellStatus = SHELL_ACCESS_DENIED;
          } else if (Status == EFI_NOT_FOUND) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
            ShellStatus = SHELL_UNSUPPORTED;
          }
        }
      } else {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
        ShellStatus = SHELL_INVALID_PARAMETER;
      }
    }
  } else if (  ShellCommandLineGetFlag (Package, L"-r")
               //               || ShellCommandLineGetFlag(Package, L"-v")
            || ConstMode
            || NormlMode
            || ShellCommandLineGetFlag (Package, L"-u")
            || ShellCommandLineGetFlag (Package, L"-t")
               )
  {
    ProbeForMediaChange ();
    if ( ShellCommandLineGetFlag (Package, L"-r")) {
      //
      // Do the reset
      //
      Status = ShellCommandCreateInitialMappingsAndPaths ();
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
        ShellStatus = SHELL_UNSUPPORTED;
      }
    }

    if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) {
      //
      // Do the Update
      //
      Status = ShellCommandUpdateMapping ();
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
        ShellStatus = SHELL_UNSUPPORTED;
      }
    }

    if (ShellStatus == SHELL_SUCCESS) {
      Param1     = ShellCommandLineGetRawValue (Package, 1);
      TypeString = ShellCommandLineGetValue (Package, L"-t");
      if (  !ConstMode
         && !NormlMode
         && (TypeString  == NULL)
            )
      {
        //
        // now do the display...
        //
        ShellStatus = PerformMappingDisplay (
                        ShellCommandLineGetFlag (Package, L"-v"),
                        TRUE,
                        TRUE,
                        NULL,
                        SfoMode,
                        Param1,
                        TRUE
                        );
      } else {
        //
        // now do the display...
        //
        ShellStatus = PerformMappingDisplay2 (
                        ShellCommandLineGetFlag (Package, L"-v"),
                        ConstMode,
                        NormlMode,
                        TypeString,
                        SfoMode,
                        Param1
                        );
      }
    }
  } else {
    //
    // adding or displaying (there were no flags)
    //
    SName   = ShellCommandLineGetRawValue (Package, 1);
    Mapping = ShellCommandLineGetRawValue (Package, 2);
    if (  (SName == NULL)
       && (Mapping == NULL)
          )
    {
      //
      // display only since no flags
      //
      ShellStatus = PerformMappingDisplay (
                      ShellCommandLineGetFlag (Package, L"-v"),
                      TRUE,
                      TRUE,
                      NULL,
                      SfoMode,
                      NULL,
                      TRUE
                      );
    } else if (  (SName == NULL)
              || (Mapping == NULL)
                 )
    {
      //
      // Display only the one specified
      //
      ShellStatus = PerformMappingDisplay (
                      FALSE,
                      FALSE,
                      FALSE,
                      NULL,
                      SfoMode,
                      SName, // note the variable here...
                      TRUE
                      );
    } else {
      if (ShellIsHexOrDecimalNumber (Mapping, TRUE, FALSE)) {
        MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping));
      } else {
        MapAsHandle = NULL;
      }

      if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        TempStringLength = StrLen (SName);
        if (!IsNumberLetterOnly (SName, TempStringLength-((SName[TempStringLength-1] == L':') ? 1 : 0))) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }

        if (ShellStatus == SHELL_SUCCESS) {
          if (MapAsHandle != NULL) {
            ShellStatus = AddMappingFromHandle (MapAsHandle, SName);
          } else {
            ShellStatus = AddMappingFromMapping (Mapping, SName);
          }

          if (ShellStatus != SHELL_SUCCESS) {
            switch (ShellStatus) {
              case SHELL_ACCESS_DENIED:
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
                break;
              case SHELL_INVALID_PARAMETER:
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
                break;
              case SHELL_DEVICE_ERROR:
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);
                break;
              default:
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT);
            }
          } else {
            //
            // now do the display...
            //
            ShellStatus = PerformMappingDisplay (
                            FALSE,
                            FALSE,
                            FALSE,
                            NULL,
                            SfoMode,
                            SName,
                            TRUE
                            );
          } // we were successful so do an output
        }
      } // got a valid map target
    } // got 2 variables
  } // we are adding a mapping

  return ShellStatus;
}

/**
  Function for 'map' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunMap (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  ProblemParam = NULL;
  ShellStatus  = SHELL_SUCCESS;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  Status = CommandInit ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdMap (Package);

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}
