/** @file
  Main file for map shell level 2 command.

  Copyright (c) 2009 - 2017, 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>
  
  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 "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);
    ASSERT(TempList != NULL);
    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;
  
  //
  // specific has priority
  //
  if (Specific != NULL) {
    NewSpecific = AllocateCopyPool(StrSize(Specific) + sizeof(CHAR16), Specific);
    if (NewSpecific == NULL){
      return FALSE;
    }
    if (NewSpecific[StrLen(NewSpecific)-1] != L':') {
      Status = StrnCatS(NewSpecific, (StrSize(Specific) + sizeof(CHAR16))/sizeof(CHAR16), 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) {
    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      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);
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),
          gShellLevel2HiiHandle,
          ConvertHandleToHandleIndex(Handle),
          MediaType,
          Removable?L"Yes":L"No",
          TempSpot2
         );
      }
      SHELL_FREE_NON_NULL(MediaType);
    }
  } else {
    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      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) {
    ShellPrintHiiEx(-1, -1, NULL, 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) {
          ShellPrintHiiEx(-1, -1, NULL, 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) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);
    } else {
      ShellPrintHiiEx(-1, -1, NULL, 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
                   );
      }
    }
  }
}

/**
  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;
  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;

  ProblemParam  = NULL;
  Mapping       = NULL;
  SName         = NULL;
  ShellStatus   = SHELL_SUCCESS;
  MapAsHandle = NULL;

  //
  // 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) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);  
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    SfoMode   = ShellCommandLineGetFlag(Package, L"-sfo");
    ConstMode = ShellCommandLineGetFlag(Package, L"-c");
    NormlMode = ShellCommandLineGetFlag(Package, L"-f");
    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetRawValue(Package, 3) != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");  
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      //
      // 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")
         ){
          ShellPrintHiiEx(-1, -1, NULL, 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) {
                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");  
                ShellStatus = SHELL_ACCESS_DENIED;
              } else if (Status == EFI_NOT_FOUND) {
                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);  
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);  
                ShellStatus = SHELL_UNSUPPORTED;
              }
            }
          } else {
            ShellPrintHiiEx(-1, -1, NULL, 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)) {
            ShellPrintHiiEx(-1, -1, NULL, 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)) {
            ShellPrintHiiEx(-1, -1, NULL, 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':') {
            ShellPrintHiiEx(-1, -1, NULL, 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))) {
              ShellPrintHiiEx(-1, -1, NULL, 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:
                    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
                    break;
                  case SHELL_INVALID_PARAMETER:
                    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
                    break;
                  case SHELL_DEVICE_ERROR:
                    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);
                    break;
                  default:
                    ShellPrintHiiEx(-1, -1, NULL, 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 sucessful so do an output
            }
          } // got a valid map target
        } // got 2 variables
      } // we are adding a mapping
    } // got valid parameters
  }

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}

