/** @file
  Provides interface to shell internal functions for shell commands.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "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 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                  *gShellCurMapping = 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
  )
{
  UINTN                           NumHandles;
  EFI_HANDLE                      *Handles;
  EFI_UNICODE_COLLATION_PROTOCOL  *Uc;
  CHAR8                           *BestLanguage;
  UINTN                           Index;
  EFI_STATUS                      Status;
  CHAR8                           *PlatformLang;

  if (gUnicodeCollation == NULL) {
    GetEfiGlobalVariable2 (EFI_PLATFORM_LANG_VARIABLE_NAME, (VOID **)&PlatformLang, NULL);

    Status = gBS->LocateHandleBuffer (
                    ByProtocol,
                    &gEfiUnicodeCollation2ProtocolGuid,
                    NULL,
                    &NumHandles,
                    &Handles
                    );
    if (EFI_ERROR (Status)) {
      NumHandles = 0;
      Handles    = NULL;
    }

    for (Index = 0; Index < NumHandles; Index++) {
      //
      // Open Unicode Collation Protocol
      //
      Status = gBS->OpenProtocol (
                      Handles[Index],
                      &gEfiUnicodeCollation2ProtocolGuid,
                      (VOID **)&Uc,
                      gImageHandle,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (EFI_ERROR (Status)) {
        continue;
      }

      //
      // Without clue provided use the first Unicode Collation2 protocol.
      // This may happen when PlatformLang is NULL or when no installed Unicode
      // Collation2 protocol instance supports PlatformLang.
      //
      if (gUnicodeCollation == NULL) {
        gUnicodeCollation = Uc;
      }

      if (PlatformLang == NULL) {
        break;
      }

      //
      // Find the best matching matching language from the supported languages
      // of Unicode Collation2 protocol.
      //
      BestLanguage = GetBestLanguage (
                       Uc->SupportedLanguages,
                       FALSE,
                       PlatformLang,
                       NULL
                       );
      if (BestLanguage != NULL) {
        FreePool (BestLanguage);
        gUnicodeCollation = Uc;
        break;
      }
    }

    if (Handles != NULL) {
      FreePool (Handles);
    }

    if (PlatformLang != NULL) {
      FreePool (PlatformLang);
    }
  }

  return (gUnicodeCollation == NULL) ? EFI_UNSUPPORTED : 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 successfully
**/
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;

  Status = CommandInit ();
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return (RETURN_SUCCESS);
}

/**
  Frees list of file handles.

  @param[in] List     The list to free.
**/
VOID
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;
  gShellCurMapping  = 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 *
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
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
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 *
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 *
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_HII_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 successful.
  @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);
      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 successfully.
  @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;
  CONST CHAR16              *CurDir;
  CHAR16                    *SplitCurDir;
  CHAR16                    *MapName;
  SHELL_MAP_LIST            *MapListItem;

  ConsistMappingTable = NULL;
  SplitCurDir         = NULL;
  MapName             = NULL;
  MapListItem         = NULL;
  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);

    if (!EFI_ERROR (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);
        }
      }
    }

    if (ConsistMappingTable != NULL) {
      ShellCommandConsistMappingUnInitialize (ConsistMappingTable);
    }

    SHELL_FREE_NON_NULL (HandleList);
    SHELL_FREE_NON_NULL (DevicePathList);

    HandleList = NULL;

    //
    // gShellCurMapping point to node of current file system in the gShellMapList. When reset all mappings,
    // all nodes in the gShellMapList will be free. Then gShellCurMapping will be a dangling pointer, So,
    // after created new mappings, we should reset the gShellCurMapping pointer back to node of current file system.
    //
    if (gShellCurMapping != NULL) {
      gShellCurMapping = NULL;
      CurDir           = gEfiShellProtocol->GetEnv (L"cwd");
      if (CurDir != NULL) {
        MapName = AllocateCopyPool (StrSize (CurDir), CurDir);
        if (MapName == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        SplitCurDir = StrStr (MapName, L":");
        if (SplitCurDir == NULL) {
          SHELL_FREE_NON_NULL (MapName);
          return EFI_UNSUPPORTED;
        }

        *(SplitCurDir + 1) = CHAR_NULL;
        MapListItem        = ShellCommandFindMapItem (MapName);
        if (MapListItem != NULL) {
          gShellCurMapping = MapListItem;
        }

        SHELL_FREE_NON_NULL (MapName);
      }
    }
  } 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);

    Status = ShellCommandConsistMappingInitialize (&ConsistMappingTable);

    //
    // Assign new Mappings to remainders
    //
    for (Count = 0; !EFI_ERROR (Status) && HandleList[Count] != NULL; 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);
}

/**
  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
EFIAPI
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 > '~') ? '.' : 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 *
EFIAPI
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;
}

/**
  ORDERED_COLLECTION_USER_COMPARE function for SHELL_SORT_UNIQUE_NAME objects.

  @param[in] Unique1AsVoid  The first SHELL_SORT_UNIQUE_NAME object (Unique1),
                            passed in as a pointer-to-VOID.

  @param[in] Unique2AsVoid  The second SHELL_SORT_UNIQUE_NAME object (Unique2),
                            passed in as a pointer-to-VOID.

  @retval <0  If Unique1 compares less than Unique2.

  @retval  0  If Unique1 compares equal to Unique2.

  @retval >0  If Unique1 compares greater than Unique2.
**/
STATIC
INTN
EFIAPI
UniqueNameCompare (
  IN CONST VOID  *Unique1AsVoid,
  IN CONST VOID  *Unique2AsVoid
  )
{
  CONST SHELL_SORT_UNIQUE_NAME  *Unique1;
  CONST SHELL_SORT_UNIQUE_NAME  *Unique2;

  Unique1 = Unique1AsVoid;
  Unique2 = Unique2AsVoid;

  //
  // We need to cast away CONST for EFI_UNICODE_COLLATION_STRICOLL.
  //
  return gUnicodeCollation->StriColl (
                              gUnicodeCollation,
                              (CHAR16 *)Unique1->Alias,
                              (CHAR16 *)Unique2->Alias
                              );
}

/**
  ORDERED_COLLECTION_KEY_COMPARE function for SHELL_SORT_UNIQUE_NAME objects.

  @param[in] UniqueAliasAsVoid  The CHAR16 string UniqueAlias, passed in as a
                                pointer-to-VOID.

  @param[in] UniqueAsVoid       The SHELL_SORT_UNIQUE_NAME object (Unique),
                                passed in as a pointer-to-VOID.

  @retval <0  If UniqueAlias compares less than Unique->Alias.

  @retval  0  If UniqueAlias compares equal to Unique->Alias.

  @retval >0  If UniqueAlias compares greater than Unique->Alias.
**/
STATIC
INTN
EFIAPI
UniqueNameAliasCompare (
  IN CONST VOID  *UniqueAliasAsVoid,
  IN CONST VOID  *UniqueAsVoid
  )
{
  CONST CHAR16                  *UniqueAlias;
  CONST SHELL_SORT_UNIQUE_NAME  *Unique;

  UniqueAlias = UniqueAliasAsVoid;
  Unique      = UniqueAsVoid;

  //
  // We need to cast away CONST for EFI_UNICODE_COLLATION_STRICOLL.
  //
  return gUnicodeCollation->StriColl (
                              gUnicodeCollation,
                              (CHAR16 *)UniqueAlias,
                              (CHAR16 *)Unique->Alias
                              );
}

/**
  Sort an EFI_SHELL_FILE_INFO list, optionally moving duplicates to a separate
  list.

  @param[in,out] FileList  The list of EFI_SHELL_FILE_INFO objects to sort.

                           If FileList is NULL on input, then FileList is
                           considered an empty, hence already sorted, list.

                           Otherwise, if (*FileList) is NULL on input, then
                           EFI_INVALID_PARAMETER is returned.

                           Otherwise, the caller is responsible for having
                           initialized (*FileList)->Link with
                           InitializeListHead(). No other fields in the
                           (**FileList) head element are accessed by this
                           function.

                           On output, (*FileList) is sorted according to Order.
                           If Duplicates is NULL on input, then duplicate
                           elements are preserved, sorted stably, on
                           (*FileList). If Duplicates is not NULL on input,
                           then duplicates are moved (stably sorted) to the
                           new, dynamically allocated (*Duplicates) list.

  @param[out] Duplicates   If Duplicates is NULL on input, (*FileList) will be
                           a monotonically ordered list on output, with
                           duplicates stably sorted.

                           If Duplicates is not NULL on input, (*FileList) will
                           be a strictly monotonically oredered list on output,
                           with duplicates separated (stably sorted) to
                           (*Duplicates). All fields except Link will be
                           zero-initialized in the (**Duplicates) head element.
                           If no duplicates exist, then (*Duplicates) is set to
                           NULL on output.

  @param[in] Order         Determines the comparison operation between
                           EFI_SHELL_FILE_INFO objects.

  @retval EFI_INVALID_PARAMETER  (UINTN)Order is greater than or equal to
                                 (UINTN)ShellSortFileListMax. Neither the
                                 (*FileList) nor the (*Duplicates) list has
                                 been modified.

  @retval EFI_INVALID_PARAMETER  (*FileList) was NULL on input. Neither the
                                 (*FileList) nor the (*Duplicates) list has
                                 been modified.

  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed. Neither the
                                 (*FileList) nor the (*Duplicates) list has
                                 been modified.

  @retval EFI_SUCCESS            Sorting successful, including the case when
                                 FileList is NULL on input.
**/
EFI_STATUS
EFIAPI
ShellSortFileList (
  IN OUT EFI_SHELL_FILE_INFO   **FileList,
  OUT EFI_SHELL_FILE_INFO      **Duplicates OPTIONAL,
  IN     SHELL_SORT_FILE_LIST  Order
  )
{
  LIST_ENTRY                *FilesHead;
  ORDERED_COLLECTION        *Sort;
  LIST_ENTRY                *FileEntry;
  EFI_SHELL_FILE_INFO       *FileInfo;
  SHELL_SORT_UNIQUE_NAME    *Unique;
  EFI_STATUS                Status;
  EFI_SHELL_FILE_INFO       *Dupes;
  LIST_ENTRY                *NextFileEntry;
  CONST CHAR16              *Alias;
  ORDERED_COLLECTION_ENTRY  *SortEntry;
  LIST_ENTRY                *TargetFileList;
  ORDERED_COLLECTION_ENTRY  *NextSortEntry;
  VOID                      *UniqueAsVoid;

  if ((UINTN)Order >= (UINTN)ShellSortFileListMax) {
    return EFI_INVALID_PARAMETER;
  }

  if (FileList == NULL) {
    //
    // FileList is considered empty, hence already sorted, with no duplicates.
    //
    if (Duplicates != NULL) {
      *Duplicates = NULL;
    }

    return EFI_SUCCESS;
  }

  if (*FileList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  FilesHead = &(*FileList)->Link;

  //
  // Collect all the unique names.
  //
  Sort = OrderedCollectionInit (UniqueNameCompare, UniqueNameAliasCompare);
  if (Sort == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  BASE_LIST_FOR_EACH (FileEntry, FilesHead) {
    FileInfo = (EFI_SHELL_FILE_INFO *)FileEntry;

    //
    // Try to record the name of this file as a unique name.
    //
    Unique = AllocatePool (sizeof (*Unique));
    if (Unique == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto UninitSort;
    }

    Unique->Alias = ((Order == ShellSortFileListByFileName) ?
                     FileInfo->FileName :
                     FileInfo->FullName);
    InitializeListHead (&Unique->SameNameList);

    Status = OrderedCollectionInsert (Sort, NULL, Unique);
    if (EFI_ERROR (Status)) {
      //
      // Only two errors are possible: memory allocation failed, or this name
      // has been encountered before. In either case, the
      // SHELL_SORT_UNIQUE_NAME object being constructed has to be released.
      //
      FreePool (Unique);
      //
      // Memory allocation failure is fatal, while having seen the same name
      // before is normal.
      //
      if (Status == EFI_OUT_OF_RESOURCES) {
        goto UninitSort;
      }

      ASSERT (Status == EFI_ALREADY_STARTED);
    }
  }

  //
  // Set Dupes to suppress incorrect compiler/analyzer warnings.
  //
  Dupes = NULL;

  //
  // If separation of duplicates has been requested, allocate the list for
  // them.
  //
  if (Duplicates != NULL) {
    Dupes = AllocateZeroPool (sizeof (*Dupes));
    if (Dupes == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto UninitSort;
    }

    InitializeListHead (&Dupes->Link);
  }

  //
  // No memory allocation beyond this point; thus, no chance to fail. We can
  // now migrate the EFI_SHELL_FILE_INFO objects from (*FileList) to Sort.
  //
  BASE_LIST_FOR_EACH_SAFE (FileEntry, NextFileEntry, FilesHead) {
    FileInfo = (EFI_SHELL_FILE_INFO *)FileEntry;
    //
    // Look up the SHELL_SORT_UNIQUE_NAME that matches FileInfo's name.
    //
    Alias = ((Order == ShellSortFileListByFileName) ?
             FileInfo->FileName :
             FileInfo->FullName);
    SortEntry = OrderedCollectionFind (Sort, Alias);
    ASSERT (SortEntry != NULL);
    Unique = OrderedCollectionUserStruct (SortEntry);
    //
    // Move FileInfo from (*FileList) to the end of the list of files whose
    // names all compare identical to FileInfo's name.
    //
    RemoveEntryList (&FileInfo->Link);
    InsertTailList (&Unique->SameNameList, &FileInfo->Link);
  }

  //
  // All EFI_SHELL_FILE_INFO objects originally in (*FileList) have been
  // distributed to Sort. Now migrate them back to (*FileList), advancing in
  // unique name order.
  //
  for (SortEntry = OrderedCollectionMin (Sort);
       SortEntry != NULL;
       SortEntry = OrderedCollectionNext (SortEntry))
  {
    Unique = OrderedCollectionUserStruct (SortEntry);
    //
    // The first FileInfo encountered for each unique name goes back on
    // (*FileList) unconditionally. Further FileInfo instances for the same
    // unique name -- that is, duplicates -- are either returned to (*FileList)
    // or separated, dependent on the caller's request.
    //
    TargetFileList = FilesHead;
    BASE_LIST_FOR_EACH_SAFE (FileEntry, NextFileEntry, &Unique->SameNameList) {
      RemoveEntryList (FileEntry);
      InsertTailList (TargetFileList, FileEntry);
      if (Duplicates != NULL) {
        TargetFileList = &Dupes->Link;
      }
    }
  }

  //
  // We're done. If separation of duplicates has been requested, output the
  // list of duplicates -- and free that list at once, if it's empty (i.e., if
  // no duplicates have been found).
  //
  if (Duplicates != NULL) {
    if (IsListEmpty (&Dupes->Link)) {
      FreePool (Dupes);
      *Duplicates = NULL;
    } else {
      *Duplicates = Dupes;
    }
  }

  Status = EFI_SUCCESS;

  //
  // Fall through.
  //
UninitSort:
  for (SortEntry = OrderedCollectionMin (Sort);
       SortEntry != NULL;
       SortEntry = NextSortEntry)
  {
    NextSortEntry = OrderedCollectionNext (SortEntry);
    OrderedCollectionDelete (Sort, SortEntry, &UniqueAsVoid);
    Unique = UniqueAsVoid;
    ASSERT (IsListEmpty (&Unique->SameNameList));
    FreePool (Unique);
  }

  OrderedCollectionUninit (Sort);

  return Status;
}
