/** @file
  Provides interface to shell internal functions for shell commands.

  Copyright (c) 2009 - 2014, 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 "UefiShellCommandLib.h"

// STATIC local variables
STATIC SHELL_COMMAND_INTERNAL_LIST_ENTRY  mCommandList;
STATIC SCRIPT_FILE_LIST                   mScriptList;
STATIC ALIAS_LIST                         mAliasList;
STATIC BOOLEAN                            mEchoState;
STATIC BOOLEAN                            mExitRequested;
STATIC UINT64                             mExitCode;
STATIC BOOLEAN                            mExitScript;
STATIC CHAR16                             *mProfileList;
STATIC UINTN                              mProfileListSize;
STATIC UINTN                              mFsMaxCount = 0;
STATIC UINTN                              mBlkMaxCount = 0;
STATIC BUFFER_LIST                        mFileHandleList;
STATIC CHAR16                             *mRawCmdLine = NULL;

STATIC CONST CHAR8 Hex[] = {
  '0',
  '1',
  '2',
  '3',
  '4',
  '5',
  '6',
  '7',
  '8',
  '9',
  'A',
  'B',
  'C',
  'D',
  'E',
  'F'
};

// global variables required by library class.
EFI_UNICODE_COLLATION_PROTOCOL    *gUnicodeCollation            = NULL;
SHELL_MAP_LIST                    gShellMapList;
SHELL_MAP_LIST                    *gShellCurDir                 = NULL;

CONST CHAR16* SupportLevel[] = {
  L"Minimal",
  L"Scripting",
  L"Basic",
  L"Interactive"
};

/**
  Function to make sure that the global protocol pointers are valid.
  must be called after constructor before accessing the pointers.
**/
EFI_STATUS
EFIAPI
CommandInit(
  VOID
  )
{
  EFI_STATUS Status;
  if (gUnicodeCollation == NULL) {
    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);
    if (EFI_ERROR(Status)) {
      return (EFI_DEVICE_ERROR);
    }
  }
  return (EFI_SUCCESS);
}

/**
  Return the pointer to the first occurrence of any character from a list of characters.

  @param[in] String                 The string to parse
  @param[in] CharacterList          The list of character to look for
  @param[in] IgnoreEscapedCharacter TRUE to ignore escaped characters

  @return The location of the first character in the String.
  @return Pointer to the ending NULL character of the String.
**/
CONST CHAR16*
EFIAPI
ShellFindFirstCharacter (
  IN CONST CHAR16  *String,
  IN CONST CHAR16  *CharacterList,
  IN CONST BOOLEAN IgnoreEscapedCharacter
  )
{
  UINTN WalkChar;
  UINTN WalkStr;

  for (WalkStr = 0; WalkStr < StrLen (String); WalkStr++) {
    if (IgnoreEscapedCharacter && (String[WalkStr] == L'^')) {
      WalkStr++;
      continue;
    }
    for (WalkChar = 0; WalkChar < StrLen (CharacterList); WalkChar++) {
      if (String[WalkStr] == CharacterList[WalkChar]) {
        return &String[WalkStr];
      }
    }
  }
  return &String[WalkStr];
}

/**
  Return the next parameter's end from a command line string.

  @param[in] String        the string to parse
**/
CONST CHAR16*
FindEndOfParameter(
  IN CONST CHAR16 *String
  )
{
  CONST CHAR16 *First;
  CONST CHAR16 *CloseQuote;

  First = ShellFindFirstCharacter (String, L" \"", TRUE);

  //
  // nothing, all one parameter remaining
  //
  if (*First == CHAR_NULL) {
    return (First);
  }

  //
  // If space before a quote (or neither found, i.e. both CHAR_NULL),
  // then that's the end.
  //
  if (*First == L' ') {
    return (First);
  }

  CloseQuote = ShellFindFirstCharacter (First+1, L"\"", TRUE);

  //
  // We did not find a terminator...
  //
  if (*CloseQuote == CHAR_NULL) {
    return (NULL);
  }

  return (FindEndOfParameter (CloseQuote+1));
}

/**
  Return the next parameter from a command line string.

  This function moves the next parameter from Walker into NextParameter and moves
  Walker up past that parameter for recursive calling.  When the final parameter
  is moved *Walker will be set to NULL;

  This will also remove all remaining ^ characters after processing.

  @param[in, out] Walker          pointer to string of command line.  Adjusted to
                                  reminaing command line on return
  @param[in, out] NextParameter   pointer to string of command line item extracted.
  @param[in]      Length          buffer size of TempParameter.
  @param[in]      StripQuotation  if TRUE then strip the quotation marks surrounding
                                  the parameters.

  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.
  @return   EFI_NOT_FOUND         A closing " could not be found on the specified string
**/
EFI_STATUS
EFIAPI
ShellGetNextParameter (
  IN OUT CHAR16   **Walker,
  IN OUT CHAR16   *NextParameter,
  IN CONST UINTN  Length,
  IN BOOLEAN      StripQuotation
  )
{
  CONST CHAR16 *NextDelim;

  if (Walker           == NULL
    ||*Walker          == NULL
    ||NextParameter    == NULL
    ){
    return EFI_INVALID_PARAMETER;
  }

  //
  // make sure we dont have any leading spaces
  //
  while ((*Walker)[0] == L' ') {
    (*Walker)++;
  }

  //
  // make sure we still have some params now...
  //
  if (StrLen(*Walker) == 0) {
    DEBUG_CODE (
      *Walker = NULL;
    );
    return (EFI_INVALID_PARAMETER);
  }

  NextDelim = FindEndOfParameter(*Walker);

  if (NextDelim == NULL){
    DEBUG_CODE (
      *Walker = NULL;
    );
    return (EFI_NOT_FOUND);
  }

  StrnCpyS(NextParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker);

  //
  // Add a CHAR_NULL if we didnt get one via the copy
  //
  if (*NextDelim != CHAR_NULL) {
    NextParameter[NextDelim - *Walker] = CHAR_NULL;
  }

  //
  // Update Walker for the next iteration through the function
  //
  *Walker = (CHAR16*)NextDelim;

  //
  // Remove any non-escaped quotes in the string
  // Remove any remaining escape characters in the string
  //
  for (NextDelim = ShellFindFirstCharacter(NextParameter, L"\"^", FALSE)
    ; *NextDelim != CHAR_NULL
    ; NextDelim = ShellFindFirstCharacter(NextDelim, L"\"^", FALSE)
    ) {
    if (*NextDelim == L'^') {

      //
      // eliminate the escape ^
      //
      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
      NextDelim++;
    } else if (*NextDelim == L'\"') {

      //
      // eliminate the unescaped quote
      //
      if (StripQuotation) {
        CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
      } else {
        NextDelim++;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Constructor for the Shell Command library.

  Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.

  @param ImageHandle    the image handle of the process
  @param SystemTable    the EFI System Table pointer

  @retval EFI_SUCCESS   the initialization was complete sucessfully
**/
RETURN_STATUS
EFIAPI
ShellCommandLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS        Status;
  InitializeListHead(&gShellMapList.Link);
  InitializeListHead(&mCommandList.Link);
  InitializeListHead(&mAliasList.Link);
  InitializeListHead(&mScriptList.Link);
  InitializeListHead(&mFileHandleList.Link);
  mEchoState = TRUE;

  mExitRequested    = FALSE;
  mExitScript       = FALSE;
  mProfileListSize  = 0;
  mProfileList      = NULL;

  if (gUnicodeCollation == NULL) {
    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);
    if (EFI_ERROR(Status)) {
      return (EFI_DEVICE_ERROR);
    }
  }

  return (RETURN_SUCCESS);
}

/**
  Frees list of file handles.

  @param[in] List     The list to free.
**/
VOID
EFIAPI
FreeFileHandleList (
  IN BUFFER_LIST *List
  )
{
  BUFFER_LIST               *BufferListEntry;

  if (List == NULL){
    return;
  }
  //
  // enumerate through the buffer list and free all memory
  //
  for ( BufferListEntry = ( BUFFER_LIST *)GetFirstNode(&List->Link)
      ; !IsListEmpty (&List->Link)
      ; BufferListEntry = (BUFFER_LIST *)GetFirstNode(&List->Link)
     ){
    RemoveEntryList(&BufferListEntry->Link);
    ASSERT(BufferListEntry->Buffer != NULL);
    SHELL_FREE_NON_NULL(((SHELL_COMMAND_FILE_HANDLE*)(BufferListEntry->Buffer))->Path);
    SHELL_FREE_NON_NULL(BufferListEntry->Buffer);
    SHELL_FREE_NON_NULL(BufferListEntry);
  }
}

/**
  Destructor for the library.  free any resources.

  @param ImageHandle    the image handle of the process
  @param SystemTable    the EFI System Table pointer

  @retval RETURN_SUCCESS this function always returns success
**/
RETURN_STATUS
EFIAPI
ShellCommandLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
  ALIAS_LIST                        *Node2;
  SCRIPT_FILE_LIST                  *Node3;
  SHELL_MAP_LIST                    *MapNode;
  //
  // enumerate throught the list and free all the memory
  //
  while (!IsListEmpty (&mCommandList.Link)) {
    Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode(&mCommandList.Link);
    RemoveEntryList(&Node->Link);
    SHELL_FREE_NON_NULL(Node->CommandString);
    FreePool(Node);
    DEBUG_CODE(Node = NULL;);
  }

  //
  // enumerate through the alias list and free all memory
  //
  while (!IsListEmpty (&mAliasList.Link)) {
    Node2 = (ALIAS_LIST *)GetFirstNode(&mAliasList.Link);
    RemoveEntryList(&Node2->Link);
    SHELL_FREE_NON_NULL(Node2->CommandString);
    SHELL_FREE_NON_NULL(Node2->Alias);
    SHELL_FREE_NON_NULL(Node2);
    DEBUG_CODE(Node2 = NULL;);
  }

  //
  // enumerate throught the list and free all the memory
  //
  while (!IsListEmpty (&mScriptList.Link)) {
    Node3 = (SCRIPT_FILE_LIST *)GetFirstNode(&mScriptList.Link);
    RemoveEntryList(&Node3->Link);
    DeleteScriptFileStruct(Node3->Data);
    FreePool(Node3);
  }

  //
  // enumerate throught the mappings list and free all the memory
  //
  if (!IsListEmpty(&gShellMapList.Link)) {
    for (MapNode = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
         ; !IsListEmpty (&gShellMapList.Link)
         ; MapNode = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
        ){
      ASSERT(MapNode != NULL);
      RemoveEntryList(&MapNode->Link);
      SHELL_FREE_NON_NULL(MapNode->DevicePath);
      SHELL_FREE_NON_NULL(MapNode->MapName);
      SHELL_FREE_NON_NULL(MapNode->CurrentDirectoryPath);
      FreePool(MapNode);
    }
  }
  if (!IsListEmpty(&mFileHandleList.Link)){
    FreeFileHandleList(&mFileHandleList);
  }

  if (mProfileList != NULL) {
    FreePool(mProfileList);
  }

  gUnicodeCollation            = NULL;
  gShellCurDir                 = NULL;

  return (RETURN_SUCCESS);
}

/**
  Find a dynamic command protocol instance given a command name string.

  @param CommandString  the command name string

  @return instance      the command protocol instance, if dynamic command instance found
  @retval NULL          no dynamic command protocol instance found for name
**/
CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *
EFIAPI
ShellCommandFindDynamicCommand (
  IN CONST CHAR16 *CommandString
  )
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          *CommandHandleList;
  EFI_HANDLE                          *NextCommand;
  EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *DynamicCommand;

  CommandHandleList = GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid);
  if (CommandHandleList == NULL) {
    //
    // not found or out of resources
    //
    return NULL; 
  }

  for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {
    Status = gBS->HandleProtocol(
      *NextCommand,
      &gEfiShellDynamicCommandProtocolGuid,
      (VOID **)&DynamicCommand
      );

    if (EFI_ERROR(Status)) {
      continue;
    }

    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)CommandString,
          (CHAR16*)DynamicCommand->CommandName) == 0 
          ){
        FreePool(CommandHandleList);
        return (DynamicCommand);
    }
  }

  FreePool(CommandHandleList);
  return (NULL);
}

/**
  Checks if a command exists as a dynamic command protocol instance

  @param[in] CommandString        The command string to check for on the list.
**/
BOOLEAN
EFIAPI
ShellCommandDynamicCommandExists (
  IN CONST CHAR16 *CommandString
  )
{
  return (BOOLEAN) ((ShellCommandFindDynamicCommand(CommandString) != NULL));
}

/**
  Checks if a command is already on the internal command list.

  @param[in] CommandString        The command string to check for on the list.
**/
BOOLEAN
EFIAPI
ShellCommandIsCommandOnInternalList(
  IN CONST  CHAR16 *CommandString
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;

  //
  // assert for NULL parameter
  //
  ASSERT(CommandString != NULL);

  //
  // check for the command
  //
  for ( Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode(&mCommandList.Link)
      ; !IsNull(&mCommandList.Link, &Node->Link)
      ; Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode(&mCommandList.Link, &Node->Link)
     ){
    ASSERT(Node->CommandString != NULL);
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)CommandString,
          Node->CommandString) == 0
       ){
      return (TRUE);
    }
  }
  return (FALSE);
}

/**
  Checks if a command exists, either internally or through the dynamic command protocol.

  @param[in] CommandString        The command string to check for on the list.
**/
BOOLEAN
EFIAPI
ShellCommandIsCommandOnList(
  IN CONST  CHAR16                      *CommandString
  )
{
  if (ShellCommandIsCommandOnInternalList(CommandString)) {
    return TRUE;
  }

  return ShellCommandDynamicCommandExists(CommandString);
}

/**
 Get the help text for a dynamic command.

  @param[in] CommandString        The command name.

  @retval NULL  No help text was found.
  @return       String of help text. Caller required to free.
**/
CHAR16*
EFIAPI
ShellCommandGetDynamicCommandHelp(
  IN CONST  CHAR16                      *CommandString
  )
{
  EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *DynamicCommand;

  DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *)ShellCommandFindDynamicCommand(CommandString);
  if (DynamicCommand == NULL) {
    return (NULL);
  }

  //
  // TODO: how to get proper language?
  //
  return DynamicCommand->GetHelp(DynamicCommand, "en"); 
}

/**
  Get the help text for an internal command.

  @param[in] CommandString        The command name.

  @retval NULL  No help text was found.
  @return       String of help text. Caller reuiqred to free.
**/
CHAR16*
EFIAPI
ShellCommandGetInternalCommandHelp(
  IN CONST  CHAR16                      *CommandString
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;

  //
  // assert for NULL parameter
  //
  ASSERT(CommandString != NULL);

  //
  // check for the command
  //
  for ( Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode(&mCommandList.Link)
      ; !IsNull(&mCommandList.Link, &Node->Link)
      ; Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode(&mCommandList.Link, &Node->Link)
     ){
    ASSERT(Node->CommandString != NULL);
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)CommandString,
          Node->CommandString) == 0
       ){
      return (HiiGetString(Node->HiiHandle, Node->ManFormatHelp, NULL));
    }
  }
  return (NULL);
}

/**
  Get the help text for a command.

  @param[in] CommandString        The command name.

  @retval NULL  No help text was found.
  @return       String of help text.Caller reuiqred to free.
**/
CHAR16*
EFIAPI
ShellCommandGetCommandHelp (
  IN CONST  CHAR16                      *CommandString
  )
{
  CHAR16      *HelpStr;
  HelpStr = ShellCommandGetInternalCommandHelp(CommandString);

  if (HelpStr == NULL) {
    HelpStr = ShellCommandGetDynamicCommandHelp(CommandString);
  }

  return HelpStr;
}


/**
  Registers handlers of type SHELL_RUN_COMMAND and
  SHELL_GET_MAN_FILENAME for each shell command.

  If the ShellSupportLevel is greater than the value of the
  PcdShellSupportLevel then return RETURN_UNSUPPORTED.

  Registers the handlers specified by GetHelpInfoHandler and CommandHandler
  with the command specified by CommandString. If the command named by
  CommandString has already been registered, then return
  RETURN_ALREADY_STARTED.

  If there are not enough resources available to register the handlers then
  RETURN_OUT_OF_RESOURCES is returned.

  If CommandString is NULL, then ASSERT().
  If GetHelpInfoHandler is NULL, then ASSERT().
  If CommandHandler is NULL, then ASSERT().
  If ProfileName is NULL, then ASSERT().

  @param[in]  CommandString         Pointer to the command name.  This is the
                                    name to look for on the command line in
                                    the shell.
  @param[in]  CommandHandler        Pointer to a function that runs the
                                    specified command.
  @param[in]  GetManFileName        Pointer to a function that provides man
                                    filename.
  @param[in]  ShellMinSupportLevel  minimum Shell Support Level which has this
                                    function.
  @param[in]  ProfileName           profile name to require for support of this
                                    function.
  @param[in]  CanAffectLE           indicates whether this command's return value
                                    can change the LASTERROR environment variable.
  @param[in]  HiiHandle             Handle of this command's HII entry.
  @param[in]  ManFormatHelp         HII locator for the help text.

  @retval  RETURN_SUCCESS           The handlers were registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to
                                    register the shell command.
  @retval RETURN_UNSUPPORTED        the ShellMinSupportLevel was higher than the
                                    currently allowed support level.
  @retval RETURN_ALREADY_STARTED    The CommandString represents a command that
                                    is already registered.  Only 1 handler set for
                                    a given command is allowed.
  @sa SHELL_GET_MAN_FILENAME
  @sa SHELL_RUN_COMMAND
**/
RETURN_STATUS
EFIAPI
ShellCommandRegisterCommandName (
  IN CONST  CHAR16                      *CommandString,
  IN        SHELL_RUN_COMMAND           CommandHandler,
  IN        SHELL_GET_MAN_FILENAME      GetManFileName,
  IN        UINT32                      ShellMinSupportLevel,
  IN CONST  CHAR16                      *ProfileName,
  IN CONST  BOOLEAN                     CanAffectLE,
  IN CONST  EFI_HANDLE                  HiiHandle,
  IN CONST  EFI_STRING_ID               ManFormatHelp
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Command;
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *PrevCommand;
  INTN LexicalMatchValue;

  //
  // Initialize local variables.
  //
  Command = NULL;
  PrevCommand = NULL;
  LexicalMatchValue = 0;

  //
  // ASSERTs for NULL parameters
  //
  ASSERT(CommandString  != NULL);
  ASSERT(GetManFileName != NULL);
  ASSERT(CommandHandler != NULL);
  ASSERT(ProfileName    != NULL);

  //
  // check for shell support level
  //
  if (PcdGet8(PcdShellSupportLevel) < ShellMinSupportLevel) {
    return (RETURN_UNSUPPORTED);
  }

  //
  // check for already on the list
  //
  if (ShellCommandIsCommandOnList(CommandString)) {
    return (RETURN_ALREADY_STARTED);
  }

  //
  // allocate memory for new struct
  //
  Node = AllocateZeroPool(sizeof(SHELL_COMMAND_INTERNAL_LIST_ENTRY));
  if (Node == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  Node->CommandString = AllocateCopyPool(StrSize(CommandString), CommandString);
  if (Node->CommandString == NULL) {
    FreePool (Node);
    return RETURN_OUT_OF_RESOURCES;
  }

  Node->GetManFileName  = GetManFileName;
  Node->CommandHandler  = CommandHandler;
  Node->LastError       = CanAffectLE;
  Node->HiiHandle       = HiiHandle;
  Node->ManFormatHelp   = ManFormatHelp;

  if ( StrLen(ProfileName)>0
    && ((mProfileList != NULL
    && StrStr(mProfileList, ProfileName) == NULL) || mProfileList == NULL)
   ){
    ASSERT((mProfileList == NULL && mProfileListSize == 0) || (mProfileList != NULL));
    if (mProfileList == NULL) {
      //
      // If this is the first make a leading ';'
      //
      StrnCatGrow(&mProfileList, &mProfileListSize, L";", 0);
    }
    StrnCatGrow(&mProfileList, &mProfileListSize, ProfileName, 0);
    StrnCatGrow(&mProfileList, &mProfileListSize, L";", 0);
  }

  //
  // Insert a new entry on top of the list
  //
  InsertHeadList (&mCommandList.Link, &Node->Link);

  //
  // Move a new registered command to its sorted ordered location in the list
  //
  for (Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode (&mCommandList.Link),
        PrevCommand = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode (&mCommandList.Link)
        ; !IsNull (&mCommandList.Link, &Command->Link)
        ; Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode (&mCommandList.Link, &Command->Link)) {

    //
    // Get Lexical Comparison Value between PrevCommand and Command list entry
    //
    LexicalMatchValue = gUnicodeCollation->StriColl (
                                             gUnicodeCollation,
                                             PrevCommand->CommandString,
                                             Command->CommandString
                                             );

    //
    // Swap PrevCommand and Command list entry if PrevCommand list entry
    // is alphabetically greater than Command list entry
    //
    if (LexicalMatchValue > 0){
      Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *) SwapListEntries (&PrevCommand->Link, &Command->Link);
    } else if (LexicalMatchValue < 0) {
      //
      // PrevCommand entry is lexically lower than Command entry
      //
      break;
    }
  }

  return (RETURN_SUCCESS);
}

/**
  Function to get the current Profile string.

  @retval NULL  There are no installed profiles.
  @return       A semi-colon delimited list of profiles.
**/
CONST CHAR16 *
EFIAPI
ShellCommandGetProfileList (
  VOID
  )
{
  return (mProfileList);
}

/**
  Checks if a command string has been registered for CommandString and if so it runs
  the previously registered handler for that command with the command line.

  If CommandString is NULL, then ASSERT().

  If Sections is specified, then each section name listed will be compared in a casesensitive
  manner, to the section names described in Appendix B UEFI Shell 2.0 spec. If the section exists,
  it will be appended to the returned help text. If the section does not exist, no
  information will be returned. If Sections is NULL, then all help text information
  available will be returned.

  @param[in]  CommandString          Pointer to the command name.  This is the name
                                     found on the command line in the shell.
  @param[in, out] RetVal             Pointer to the return vaule from the command handler.

  @param[in, out]  CanAffectLE       indicates whether this command's return value
                                     needs to be placed into LASTERROR environment variable.

  @retval RETURN_SUCCESS            The handler was run.
  @retval RETURN_NOT_FOUND          The CommandString did not match a registered
                                    command name.
  @sa SHELL_RUN_COMMAND
**/
RETURN_STATUS
EFIAPI
ShellCommandRunCommandHandler (
  IN CONST CHAR16               *CommandString,
  IN OUT SHELL_STATUS           *RetVal,
  IN OUT BOOLEAN                *CanAffectLE OPTIONAL
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY   *Node;
  EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *DynamicCommand;

  //
  // assert for NULL parameters
  //
  ASSERT(CommandString != NULL);

  //
  // check for the command
  //
  for ( Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode(&mCommandList.Link)
      ; !IsNull(&mCommandList.Link, &Node->Link)
      ; Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode(&mCommandList.Link, &Node->Link)
     ){
    ASSERT(Node->CommandString != NULL);
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)CommandString,
          Node->CommandString) == 0
      ){
      if (CanAffectLE != NULL) {
        *CanAffectLE = Node->LastError;
      }
      if (RetVal != NULL) {
        *RetVal = Node->CommandHandler(NULL, gST);
      } else {
        Node->CommandHandler(NULL, gST);
      }
      return (RETURN_SUCCESS);
    }
  }

  //
  // An internal command was not found, try to find a dynamic command
  //
  DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *)ShellCommandFindDynamicCommand(CommandString);
  if (DynamicCommand != NULL) {
    if (RetVal != NULL) {
      *RetVal = DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);
    } else {
      DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);
    }
    return (RETURN_SUCCESS);
  }

  return (RETURN_NOT_FOUND);
}

/**
  Checks if a command string has been registered for CommandString and if so it
  returns the MAN filename specified for that command.

  If CommandString is NULL, then ASSERT().

  @param[in]  CommandString         Pointer to the command name.  This is the name
                                    found on the command line in the shell.\

  @retval NULL                      the commandString was not a registered command.
  @return other                     the name of the MAN file.
  @sa SHELL_GET_MAN_FILENAME
**/
CONST CHAR16*
EFIAPI
ShellCommandGetManFileNameHandler (
  IN CONST CHAR16               *CommandString
  )
{
  SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;

  //
  // assert for NULL parameters
  //
  ASSERT(CommandString != NULL);

  //
  // check for the command
  //
  for ( Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode(&mCommandList.Link)
      ; !IsNull(&mCommandList.Link, &Node->Link)
      ; Node = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode(&mCommandList.Link, &Node->Link)
     ){
    ASSERT(Node->CommandString != NULL);
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)CommandString,
          Node->CommandString) == 0
       ){
      return (Node->GetManFileName());
    }
  }
  return (NULL);
}

/**
  Get the list of all available shell internal commands.  This is a linked list
  (via LIST_ENTRY structure).  enumerate through it using the BaseLib linked
  list functions.  do not modify the values.

  @param[in] Sort       TRUE to alphabetically sort the values first.  FALSE otherwise.

  @return a Linked list of all available shell commands.
**/
CONST COMMAND_LIST*
EFIAPI
ShellCommandGetCommandList (
  IN CONST BOOLEAN Sort
  )
{
//  if (!Sort) {
//    return ((COMMAND_LIST*)(&mCommandList));
//  }
  return ((COMMAND_LIST*)(&mCommandList));
}

/**
  Registers aliases to be set as part of the initialization of the shell application.

  If Command is NULL, then ASSERT().
  If Alias is NULL, then ASSERT().

  @param[in]  Command               Pointer to the Command
  @param[in]  Alias                 Pointer to Alias

  @retval  RETURN_SUCCESS           The handlers were registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to
                                    register the shell command.
**/
RETURN_STATUS
EFIAPI
ShellCommandRegisterAlias (
  IN CONST CHAR16                       *Command,
  IN CONST CHAR16                       *Alias
  )
{
  ALIAS_LIST *Node;
  ALIAS_LIST *CommandAlias;
  ALIAS_LIST *PrevCommandAlias; 
  INTN       LexicalMatchValue;

  //
  // Asserts for NULL
  //
  ASSERT(Command != NULL);
  ASSERT(Alias   != NULL);

  //
  // allocate memory for new struct
  //
  Node = AllocateZeroPool(sizeof(ALIAS_LIST));
  if (Node == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  Node->CommandString = AllocateCopyPool(StrSize(Command), Command);
  if (Node->CommandString == NULL) {
    FreePool (Node);
    return RETURN_OUT_OF_RESOURCES;
  }
  Node->Alias = AllocateCopyPool(StrSize(Alias), Alias);
  if (Node->Alias == NULL) {
    FreePool (Node->CommandString);
    FreePool (Node);
    return RETURN_OUT_OF_RESOURCES;
  }

  InsertHeadList (&mAliasList.Link, &Node->Link);

  //
  // Move a new pre-defined registered alias to its sorted ordered location in the list
  //
  for ( CommandAlias = (ALIAS_LIST *)GetFirstNode (&mAliasList.Link),
         PrevCommandAlias = (ALIAS_LIST *)GetFirstNode (&mAliasList.Link)
       ; !IsNull (&mAliasList.Link, &CommandAlias->Link)
       ; CommandAlias = (ALIAS_LIST *) GetNextNode (&mAliasList.Link, &CommandAlias->Link) ) {
    //
    // Get Lexical comparison value between PrevCommandAlias and CommandAlias List Entry
    //
    LexicalMatchValue = gUnicodeCollation->StriColl (
                                             gUnicodeCollation,
                                             PrevCommandAlias->Alias,
                                             CommandAlias->Alias
                                             );

    //
    // Swap PrevCommandAlias and CommandAlias list entry if PrevCommandAlias list entry
    // is alphabetically greater than CommandAlias list entry
    // 
    if (LexicalMatchValue > 0) {
      CommandAlias = (ALIAS_LIST *) SwapListEntries (&PrevCommandAlias->Link, &CommandAlias->Link);
    } else if (LexicalMatchValue < 0) {
      //
      // PrevCommandAlias entry is lexically lower than CommandAlias entry
      //
      break;
    }
  }

  return (RETURN_SUCCESS);
}

/**
  Get the list of all shell alias commands.  This is a linked list
  (via LIST_ENTRY structure).  enumerate through it using the BaseLib linked
  list functions.  do not modify the values.

  @return a Linked list of all requested shell alias'.
**/
CONST ALIAS_LIST*
EFIAPI
ShellCommandGetInitAliasList (
  VOID
  )
{
    return (&mAliasList);
}

/**
  Determine if a given alias is on the list of built in alias'.

  @param[in] Alias              The alias to test for

  @retval TRUE                  The alias is a built in alias
  @retval FALSE                 The alias is not a built in alias
**/
BOOLEAN
EFIAPI
ShellCommandIsOnAliasList(
  IN CONST CHAR16 *Alias
  )
{
  ALIAS_LIST *Node;

  //
  // assert for NULL parameter
  //
  ASSERT(Alias != NULL);

  //
  // check for the Alias
  //
  for ( Node = (ALIAS_LIST *)GetFirstNode(&mAliasList.Link)
      ; !IsNull(&mAliasList.Link, &Node->Link)
      ; Node = (ALIAS_LIST *)GetNextNode(&mAliasList.Link, &Node->Link)
     ){
    ASSERT(Node->CommandString != NULL);
    ASSERT(Node->Alias != NULL);
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)Alias,
          Node->CommandString) == 0
       ){
      return (TRUE);
    }
    if (gUnicodeCollation->StriColl(
          gUnicodeCollation,
          (CHAR16*)Alias,
          Node->Alias) == 0
       ){
      return (TRUE);
    }
  }
  return (FALSE);
}

/**
  Function to determine current state of ECHO.  Echo determines if lines from scripts
  and ECHO commands are enabled.

  @retval TRUE    Echo is currently enabled
  @retval FALSE   Echo is currently disabled
**/
BOOLEAN
EFIAPI
ShellCommandGetEchoState(
  VOID
  )
{
  return (mEchoState);
}

/**
  Function to set current state of ECHO.  Echo determines if lines from scripts
  and ECHO commands are enabled.

  If State is TRUE, Echo will be enabled.
  If State is FALSE, Echo will be disabled.

  @param[in] State      How to set echo.
**/
VOID
EFIAPI
ShellCommandSetEchoState(
  IN BOOLEAN State
  )
{
  mEchoState = State;
}

/**
  Indicate that the current shell or script should exit.

  @param[in] ScriptOnly   TRUE if exiting a script; FALSE otherwise.
  @param[in] ErrorCode    The 64 bit error code to return.
**/
VOID
EFIAPI
ShellCommandRegisterExit (
  IN BOOLEAN      ScriptOnly,
  IN CONST UINT64 ErrorCode
  )
{
  mExitRequested = (BOOLEAN)(!mExitRequested);
  if (mExitRequested) {
    mExitScript    = ScriptOnly;
  } else {
    mExitScript    = FALSE;
  }
  mExitCode = ErrorCode;
}

/**
  Retrieve the Exit indicator.

  @retval TRUE      Exit was indicated.
  @retval FALSE     Exis was not indicated.
**/
BOOLEAN
EFIAPI
ShellCommandGetExit (
  VOID
  )
{
  return (mExitRequested);
}

/**
  Retrieve the Exit code.

  If ShellCommandGetExit returns FALSE than the return from this is undefined.

  @return the value passed into RegisterExit.
**/
UINT64
EFIAPI
ShellCommandGetExitCode (
  VOID
  )
{
  return (mExitCode);
}
/**
  Retrieve the Exit script indicator.

  If ShellCommandGetExit returns FALSE than the return from this is undefined.

  @retval TRUE      ScriptOnly was indicated.
  @retval FALSE     ScriptOnly was not indicated.
**/
BOOLEAN
EFIAPI
ShellCommandGetScriptExit (
  VOID
  )
{
  return (mExitScript);
}

/**
  Function to cleanup all memory from a SCRIPT_FILE structure.

  @param[in] Script     The pointer to the structure to cleanup.
**/
VOID
EFIAPI
DeleteScriptFileStruct (
  IN SCRIPT_FILE *Script
  )
{
  UINT8       LoopVar;

  if (Script == NULL) {
    return;
  }

  for (LoopVar = 0 ; LoopVar < Script->Argc ; LoopVar++) {
    SHELL_FREE_NON_NULL(Script->Argv[LoopVar]);
  }
  if (Script->Argv != NULL) {
    SHELL_FREE_NON_NULL(Script->Argv);
  }
  Script->CurrentCommand = NULL;
  while (!IsListEmpty (&Script->CommandList)) {
    Script->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetFirstNode(&Script->CommandList);
    if (Script->CurrentCommand != NULL) {
      RemoveEntryList(&Script->CurrentCommand->Link);
      if (Script->CurrentCommand->Cl != NULL) {
        SHELL_FREE_NON_NULL(Script->CurrentCommand->Cl);
      }
      if (Script->CurrentCommand->Data != NULL) {
        SHELL_FREE_NON_NULL(Script->CurrentCommand->Data);
      }
      SHELL_FREE_NON_NULL(Script->CurrentCommand);
    }
  }
  SHELL_FREE_NON_NULL(Script->ScriptName);
  SHELL_FREE_NON_NULL(Script);
}

/**
  Function to return a pointer to the currently running script file object.

  @retval NULL        A script file is not currently running.
  @return             A pointer to the current script file object.
**/
SCRIPT_FILE*
EFIAPI
ShellCommandGetCurrentScriptFile (
  VOID
  )
{
  SCRIPT_FILE_LIST *List;
  if (IsListEmpty (&mScriptList.Link)) {
    return (NULL);
  }
  List = ((SCRIPT_FILE_LIST*)GetFirstNode(&mScriptList.Link));
  return (List->Data);
}

/**
  Function to set a new script as the currently running one.

  This function will correctly stack and unstack nested scripts.

  @param[in] Script   Pointer to new script information structure.  if NULL
                      will remove and de-allocate the top-most Script structure.

  @return             A pointer to the current running script file after this
                      change.  NULL if removing the final script.
**/
SCRIPT_FILE*
EFIAPI
ShellCommandSetNewScript (
  IN SCRIPT_FILE *Script OPTIONAL
  )
{
  SCRIPT_FILE_LIST *Node;
  if (Script == NULL) {
    if (IsListEmpty (&mScriptList.Link)) {
      return (NULL);
    }
    Node = (SCRIPT_FILE_LIST *)GetFirstNode(&mScriptList.Link);
    RemoveEntryList(&Node->Link);
    DeleteScriptFileStruct(Node->Data);
    FreePool(Node);
  } else {
    Node = AllocateZeroPool(sizeof(SCRIPT_FILE_LIST));
    if (Node == NULL) {
      return (NULL);
    }
    Node->Data = Script;
    InsertHeadList(&mScriptList.Link, &Node->Link);
  }
  return (ShellCommandGetCurrentScriptFile());
}

/**
  Function to generate the next default mapping name.

  If the return value is not NULL then it must be callee freed.

  @param Type                   What kind of mapping name to make.

  @retval NULL                  a memory allocation failed.
  @return a new map name string
**/
CHAR16*
EFIAPI
ShellCommandCreateNewMappingName(
  IN CONST SHELL_MAPPING_TYPE Type
  )
{
  CHAR16  *String;
  ASSERT(Type < MappingTypeMax);

  String = NULL;

  String = AllocateZeroPool(PcdGet8(PcdShellMapNameLength) * sizeof(String[0]));
  UnicodeSPrint(
    String,
    PcdGet8(PcdShellMapNameLength) * sizeof(String[0]),
    Type == MappingTypeFileSystem?L"FS%d:":L"BLK%d:",
    Type == MappingTypeFileSystem?mFsMaxCount++:mBlkMaxCount++);

  return (String);
}

/**
  Function to add a map node to the list of map items and update the "path" environment variable (optionally).

  If Path is TRUE (during initialization only), the path environment variable will also be updated to include
  default paths on the new map name...

  Path should be FALSE when this function is called from the protocol SetMap function.

  @param[in] Name               The human readable mapped name.
  @param[in] DevicePath         The Device Path for this map.
  @param[in] Flags              The Flags attribute for this map item.
  @param[in] Path               TRUE to update path, FALSE to skip this step (should only be TRUE during initialization).

  @retval EFI_SUCCESS           The addition was sucessful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_INVALID_PARAMETER A parameter was invalid.
**/
EFI_STATUS
EFIAPI
ShellCommandAddMapItemAndUpdatePath(
  IN CONST CHAR16                   *Name,
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  IN CONST UINT64                   Flags,
  IN CONST BOOLEAN                  Path
  )
{
  EFI_STATUS      Status;
  SHELL_MAP_LIST  *MapListNode;
  CONST CHAR16    *OriginalPath;
  CHAR16          *NewPath;
  UINTN           NewPathSize;

  NewPathSize = 0;
  NewPath = NULL;
  OriginalPath = NULL;
  Status = EFI_SUCCESS;

  MapListNode = AllocateZeroPool(sizeof(SHELL_MAP_LIST));
  if (MapListNode == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  } else {
    MapListNode->Flags = Flags;
    MapListNode->MapName = AllocateCopyPool(StrSize(Name), Name);
    MapListNode->DevicePath = DuplicateDevicePath(DevicePath);
    if ((MapListNode->MapName == NULL) || (MapListNode->DevicePath == NULL)){
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      InsertTailList(&gShellMapList.Link, &MapListNode->Link);
    }
  }
  if (EFI_ERROR(Status)) {
    if (MapListNode != NULL) {
      if (MapListNode->DevicePath != NULL) {
        FreePool(MapListNode->DevicePath);
      }
      if (MapListNode->MapName != NULL) {
        FreePool(MapListNode->MapName);
      }
      FreePool(MapListNode);
    }
  } else if (Path) {
    //
    // Since there was no error and Path was TRUE
    // Now add the correct path for that mapping
    //
    OriginalPath = gEfiShellProtocol->GetEnv(L"path");
    ASSERT((NewPath == NULL && NewPathSize == 0) || (NewPath != NULL));
    if (OriginalPath != NULL) {
      StrnCatGrow(&NewPath, &NewPathSize, OriginalPath, 0);
    } else {
      StrnCatGrow(&NewPath, &NewPathSize, L".\\", 0);
    }
    StrnCatGrow(&NewPath, &NewPathSize, L";", 0);
    StrnCatGrow(&NewPath, &NewPathSize, Name, 0);
    StrnCatGrow(&NewPath, &NewPathSize, L"\\efi\\tools\\;", 0);
    StrnCatGrow(&NewPath, &NewPathSize, Name, 0);
    StrnCatGrow(&NewPath, &NewPathSize, L"\\efi\\boot\\;", 0);
    StrnCatGrow(&NewPath, &NewPathSize, Name, 0);
    StrnCatGrow(&NewPath, &NewPathSize, L"\\", 0);

    Status = gEfiShellProtocol->SetEnv(L"path", NewPath, TRUE);
    ASSERT_EFI_ERROR(Status);
    FreePool(NewPath);
  }
  return (Status);
}

/**
  Creates the default map names for each device path in the system with
  a protocol depending on the Type.

  Creates the consistent map names for each device path in the system with
  a protocol depending on the Type.

  Note: This will reset all mappings in the system("map -r").

  Also sets up the default path environment variable if Type is FileSystem.

  @retval EFI_SUCCESS           All map names were created sucessfully.
  @retval EFI_NOT_FOUND         No protocols were found in the system.
  @return                       Error returned from gBS->LocateHandle().

  @sa LocateHandle
**/
EFI_STATUS
EFIAPI
ShellCommandCreateInitialMappingsAndPaths(
  VOID
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                *HandleList;
  UINTN                     Count;
  EFI_DEVICE_PATH_PROTOCOL  **DevicePathList;
  CHAR16                    *NewDefaultName;
  CHAR16                    *NewConsistName;
  EFI_DEVICE_PATH_PROTOCOL  **ConsistMappingTable;
  SHELL_MAP_LIST            *MapListNode;

  HandleList  = NULL;

  //
  // Reset the static members back to zero
  //
  mFsMaxCount = 0;
  mBlkMaxCount = 0;

  gEfiShellProtocol->SetEnv(L"path", L"", TRUE);

  //
  // First empty out the existing list.
  //
  if (!IsListEmpty(&gShellMapList.Link)) {
    for ( MapListNode = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
        ; !IsListEmpty(&gShellMapList.Link)
        ; MapListNode = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
       ){
          RemoveEntryList(&MapListNode->Link);
          SHELL_FREE_NON_NULL(MapListNode->DevicePath);
          SHELL_FREE_NON_NULL(MapListNode->MapName);
          SHELL_FREE_NON_NULL(MapListNode->CurrentDirectoryPath);
          FreePool(MapListNode);
    } // for loop
  }

  //
  // Find each handle with Simple File System
  //
  HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);
  if (HandleList != NULL) {
    //
    // Do a count of the handles
    //
    for (Count = 0 ; HandleList[Count] != NULL ; Count++);

    //
    // Get all Device Paths
    //
    DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
    if (DevicePathList == NULL) {
      SHELL_FREE_NON_NULL (HandleList);
      return EFI_OUT_OF_RESOURCES;
    }

    for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
      DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
    }

    //
    // Sort all DevicePaths
    //
    PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);

    ShellCommandConsistMappingInitialize(&ConsistMappingTable);
    //
    // Assign new Mappings to all...
    //
    for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
      //
      // Get default name first
      //
      NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);
      ASSERT(NewDefaultName != NULL);
      Status = ShellCommandAddMapItemAndUpdatePath(NewDefaultName, DevicePathList[Count], 0, TRUE);
      ASSERT_EFI_ERROR(Status);
      FreePool(NewDefaultName);

      //
      // Now do consistent name
      //
      NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);
      if (NewConsistName != NULL) {
        Status = ShellCommandAddMapItemAndUpdatePath(NewConsistName, DevicePathList[Count], 0, FALSE);
        ASSERT_EFI_ERROR(Status);
        FreePool(NewConsistName);
      }
    }

    ShellCommandConsistMappingUnInitialize(ConsistMappingTable);

    SHELL_FREE_NON_NULL(HandleList);
    SHELL_FREE_NON_NULL(DevicePathList);

    HandleList = NULL;
  } else {
    Count = (UINTN)-1;
  }

  //
  // Find each handle with Block Io
  //
  HandleList = GetHandleListByProtocol(&gEfiBlockIoProtocolGuid);
  if (HandleList != NULL) {
    for (Count = 0 ; HandleList[Count] != NULL ; Count++);

    //
    // Get all Device Paths
    //
    DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
    if (DevicePathList == NULL) {
      SHELL_FREE_NON_NULL (HandleList);
      return EFI_OUT_OF_RESOURCES;
    }

    for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
      DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
    }

    //
    // Sort all DevicePaths
    //
    PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);

    //
    // Assign new Mappings to all...
    //
    for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
      //
      // Get default name first
      //
      NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeBlockIo);
      ASSERT(NewDefaultName != NULL);
      Status = ShellCommandAddMapItemAndUpdatePath(NewDefaultName, DevicePathList[Count], 0, FALSE);
      ASSERT_EFI_ERROR(Status);
      FreePool(NewDefaultName);
    }

    SHELL_FREE_NON_NULL(HandleList);
    SHELL_FREE_NON_NULL(DevicePathList);
  } else if (Count == (UINTN)-1) {
    return (EFI_NOT_FOUND);
  }

  return (EFI_SUCCESS);
}

/**
  Add mappings for any devices without one.  Do not change any existing maps.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
EFIAPI
ShellCommandUpdateMapping (
  VOID
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                *HandleList;
  UINTN                     Count;
  EFI_DEVICE_PATH_PROTOCOL  **DevicePathList;
  CHAR16                    *NewDefaultName;
  CHAR16                    *NewConsistName;
  EFI_DEVICE_PATH_PROTOCOL  **ConsistMappingTable;

  HandleList  = NULL;
  Status      = EFI_SUCCESS;

  //
  // remove mappings that represent removed devices.
  //

  //
  // Find each handle with Simple File System
  //
  HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);
  if (HandleList != NULL) {
    //
    // Do a count of the handles
    //
    for (Count = 0 ; HandleList[Count] != NULL ; Count++);

    //
    // Get all Device Paths
    //
    DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
    if (DevicePathList == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
      DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
    }

    //
    // Sort all DevicePaths
    //
    PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);

    ShellCommandConsistMappingInitialize(&ConsistMappingTable);

    //
    // Assign new Mappings to remainders
    //
    for (Count = 0 ; !EFI_ERROR(Status) && HandleList[Count] != NULL && !EFI_ERROR(Status); Count++) {
      //
      // Skip ones that already have
      //
      if (gEfiShellProtocol->GetMapFromDevicePath(&DevicePathList[Count]) != NULL) {
        continue;
      }
      //
      // Get default name
      //
      NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);
      if (NewDefaultName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }

      //
      // Call shell protocol SetMap function now...
      //
      Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewDefaultName);

      if (!EFI_ERROR(Status)) {
        //
        // Now do consistent name
        //
        NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);
        if (NewConsistName != NULL) {
          Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewConsistName);
          FreePool(NewConsistName);
        }
      }

      FreePool(NewDefaultName);
    }
    ShellCommandConsistMappingUnInitialize(ConsistMappingTable);
    SHELL_FREE_NON_NULL(HandleList);
    SHELL_FREE_NON_NULL(DevicePathList);

    HandleList = NULL;
  } else {
    Count = (UINTN)-1;
  }
  //
  // Do it all over again for gEfiBlockIoProtocolGuid
  //

  return (Status);
}

/**
  Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.

  @param[in] Handle     The SHELL_FILE_HANDLE to convert.

  @return a EFI_FILE_PROTOCOL* representing the same file.
**/
EFI_FILE_PROTOCOL*
EFIAPI
ConvertShellHandleToEfiFileProtocol(
  IN CONST SHELL_FILE_HANDLE Handle
  )
{
  return ((EFI_FILE_PROTOCOL*)(Handle));
}

/**
  Converts a EFI_FILE_PROTOCOL* to an SHELL_FILE_HANDLE.

  @param[in] Handle     The pointer to EFI_FILE_PROTOCOL to convert.
  @param[in] Path       The path to the file for verification.

  @return               A SHELL_FILE_HANDLE representing the same file.
  @retval NULL          There was not enough memory.
**/
SHELL_FILE_HANDLE
EFIAPI
ConvertEfiFileProtocolToShellHandle(
  IN CONST EFI_FILE_PROTOCOL *Handle,
  IN CONST CHAR16            *Path
  )
{
  SHELL_COMMAND_FILE_HANDLE *Buffer;
  BUFFER_LIST               *NewNode;

  if (Path != NULL) {
    Buffer              = AllocateZeroPool(sizeof(SHELL_COMMAND_FILE_HANDLE));
    if (Buffer == NULL) {
      return (NULL);
    }
    NewNode             = AllocateZeroPool(sizeof(BUFFER_LIST));
    if (NewNode == NULL) {
      SHELL_FREE_NON_NULL(Buffer);
      return (NULL);
    }
    Buffer->FileHandle  = (EFI_FILE_PROTOCOL*)Handle;
    Buffer->Path        = StrnCatGrow(&Buffer->Path, NULL, Path, 0);
    if (Buffer->Path == NULL) {
      SHELL_FREE_NON_NULL(NewNode);
      SHELL_FREE_NON_NULL(Buffer);
      return (NULL);
    }
    NewNode->Buffer     = Buffer;

    InsertHeadList(&mFileHandleList.Link, &NewNode->Link);
  }
  return ((SHELL_FILE_HANDLE)(Handle));
}

/**
  Find the path that was logged with the specified SHELL_FILE_HANDLE.

  @param[in] Handle     The SHELL_FILE_HANDLE to query on.

  @return A pointer to the path for the file.
**/
CONST CHAR16*
EFIAPI
ShellFileHandleGetPath(
  IN CONST SHELL_FILE_HANDLE Handle
  )
{
  BUFFER_LIST               *Node;

  for (Node = (BUFFER_LIST*)GetFirstNode(&mFileHandleList.Link)
    ;  !IsNull(&mFileHandleList.Link, &Node->Link)
    ;  Node = (BUFFER_LIST*)GetNextNode(&mFileHandleList.Link, &Node->Link)
   ){
    if ((Node->Buffer) && (((SHELL_COMMAND_FILE_HANDLE *)Node->Buffer)->FileHandle == Handle)){
      return (((SHELL_COMMAND_FILE_HANDLE *)Node->Buffer)->Path);
    }
  }
  return (NULL);
}

/**
  Remove a SHELL_FILE_HANDLE from the list of SHELL_FILE_HANDLES.

  @param[in] Handle     The SHELL_FILE_HANDLE to remove.

  @retval TRUE          The item was removed.
  @retval FALSE         The item was not found.
**/
BOOLEAN
EFIAPI
ShellFileHandleRemove(
  IN CONST SHELL_FILE_HANDLE Handle
  )
{
  BUFFER_LIST               *Node;

  for (Node = (BUFFER_LIST*)GetFirstNode(&mFileHandleList.Link)
    ;  !IsNull(&mFileHandleList.Link, &Node->Link)
    ;  Node = (BUFFER_LIST*)GetNextNode(&mFileHandleList.Link, &Node->Link)
   ){
    if ((Node->Buffer) && (((SHELL_COMMAND_FILE_HANDLE *)Node->Buffer)->FileHandle == Handle)){
      RemoveEntryList(&Node->Link);
      SHELL_FREE_NON_NULL(((SHELL_COMMAND_FILE_HANDLE *)Node->Buffer)->Path);
      SHELL_FREE_NON_NULL(Node->Buffer);
      SHELL_FREE_NON_NULL(Node);
      return (TRUE);
    }
  }
  return (FALSE);
}

/**
  Function to determine if a SHELL_FILE_HANDLE is at the end of the file.

  This will NOT work on directories.

  If Handle is NULL, then ASSERT.

  @param[in] Handle     the file handle

  @retval TRUE          the position is at the end of the file
  @retval FALSE         the position is not at the end of the file
**/
BOOLEAN
EFIAPI
ShellFileHandleEof(
  IN SHELL_FILE_HANDLE Handle
  )
{
  EFI_FILE_INFO *Info;
  UINT64        Pos;
  BOOLEAN       RetVal;

  //
  // ASSERT if Handle is NULL
  //
  ASSERT(Handle != NULL);

  gEfiShellProtocol->GetFilePosition(Handle, &Pos);
  Info = gEfiShellProtocol->GetFileInfo (Handle);
  gEfiShellProtocol->SetFilePosition(Handle, Pos);

  if (Info == NULL) {
    return (FALSE);
  }

  if (Pos == Info->FileSize) {
    RetVal = TRUE;
  } else {
    RetVal = FALSE;
  }

  FreePool (Info);

  return (RetVal);
}

/**
  Function to get the original CmdLine string for current command.

  @return     A pointer to the buffer of the original command string.
              It's the caller's responsibility to free the buffer.
**/
CHAR16*
EFIAPI
ShellGetRawCmdLine (
  VOID
  )
{
  if (mRawCmdLine == NULL) {
    return NULL;
  } else {
    return AllocateCopyPool(StrSize(mRawCmdLine), mRawCmdLine);
  }
}

/**
  Function to store the raw command string.

  The alias and variables have been replaced and spaces are trimmed.

  @param[in] CmdLine     the command line string to store.
**/
VOID
EFIAPI
ShellSetRawCmdLine (
  IN CONST CHAR16     *CmdLine
  )
{
  SHELL_FREE_NON_NULL(mRawCmdLine);

  if (CmdLine != NULL) {
    //
    // The spaces in the beginning and end are trimmed.
    //
    ASSERT (*CmdLine != L' ');
    ASSERT (CmdLine[StrLen (CmdLine) - 1] != L' ');
    mRawCmdLine = AllocateCopyPool (StrSize(CmdLine), CmdLine);
  }
}

/**
  Frees any BUFFER_LIST defined type.

  @param[in] List     The BUFFER_LIST object to free.
**/
VOID
EFIAPI
FreeBufferList (
  IN BUFFER_LIST *List
  )
{
  BUFFER_LIST               *BufferListEntry;

  if (List == NULL){
    return;
  }
  //
  // enumerate through the buffer list and free all memory
  //
  for ( BufferListEntry = ( BUFFER_LIST *)GetFirstNode(&List->Link)
      ; !IsListEmpty (&List->Link)
      ; BufferListEntry = (BUFFER_LIST *)GetFirstNode(&List->Link)
     ){
    RemoveEntryList(&BufferListEntry->Link);
    if (BufferListEntry->Buffer != NULL) {
      FreePool(BufferListEntry->Buffer);
    }
    FreePool(BufferListEntry);
  }
}

/**
  Dump some hexadecimal data to the screen.

  @param[in] Indent     How many spaces to indent the output.
  @param[in] Offset     The offset of the printing.
  @param[in] DataSize   The size in bytes of UserData.
  @param[in] UserData   The data to print out.
**/
VOID
DumpHex (
  IN UINTN        Indent,
  IN UINTN        Offset,
  IN UINTN        DataSize,
  IN VOID         *UserData
  )
{
  UINT8 *Data;

  CHAR8 Val[50];

  CHAR8 Str[20];

  UINT8 TempByte;
  UINTN Size;
  UINTN Index;

  Data = UserData;
  while (DataSize != 0) {
    Size = 16;
    if (Size > DataSize) {
      Size = DataSize;
    }

    for (Index = 0; Index < Size; Index += 1) {
      TempByte            = Data[Index];
      Val[Index * 3 + 0]  = Hex[TempByte >> 4];
      Val[Index * 3 + 1]  = Hex[TempByte & 0xF];
      Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
    }

    Val[Index * 3]  = 0;
    Str[Index]      = 0;
    ShellPrintEx(-1, -1, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);

    Data += Size;
    Offset += Size;
    DataSize -= Size;
  }
}

/**
  Dump HEX data into buffer.

  @param[in] Buffer     HEX data to be dumped in Buffer.
  @param[in] Indent     How many spaces to indent the output.
  @param[in] Offset     The offset of the printing.
  @param[in] DataSize   The size in bytes of UserData.
  @param[in] UserData   The data to print out.
**/
CHAR16*
CatSDumpHex (
  IN CHAR16  *Buffer,
  IN UINTN   Indent,
  IN UINTN   Offset,
  IN UINTN   DataSize,
  IN VOID    *UserData
  )
{
  UINT8   *Data;
  UINT8   TempByte;
  UINTN   Size;
  UINTN   Index;
  CHAR8   Val[50];
  CHAR8   Str[20];
  CHAR16  *RetVal;
  CHAR16  *TempRetVal;

  Data = UserData;
  RetVal = Buffer;
  while (DataSize != 0) {
    Size = 16;
    if (Size > DataSize) {
      Size = DataSize;
    }

    for (Index = 0; Index < Size; Index += 1) {
      TempByte            = Data[Index];
      Val[Index * 3 + 0]  = Hex[TempByte >> 4];
      Val[Index * 3 + 1]  = Hex[TempByte & 0xF];
      Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
    }

    Val[Index * 3]  = 0;
    Str[Index]      = 0;
    TempRetVal = CatSPrint (RetVal, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);
    SHELL_FREE_NON_NULL (RetVal);
    RetVal = TempRetVal;

    Data += Size;
    Offset += Size;
    DataSize -= Size;
  }

  return RetVal;
}
