/** @file
  Member functions of EFI_SHELL_PROTOCOL and functions for creation,
  manipulation, and initialization of EFI_SHELL_PROTOCOL.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Shell.h"

#define INIT_NAME_BUFFER_SIZE  128

/**
  Close an open file handle.

  This function closes a specified file handle. All "dirty" cached file data is
  flushed to the device, and the file is closed. In all cases the handle is
  closed.

  @param[in] FileHandle           The file handle to close.

  @retval EFI_SUCCESS             The file handle was closed successfully.
**/
EFI_STATUS
EFIAPI
EfiShellClose (
  IN SHELL_FILE_HANDLE  FileHandle
  )
{
  ShellFileHandleRemove (FileHandle);
  return (FileHandleClose (ConvertShellHandleToEfiFileProtocol (FileHandle)));
}

/**
  Internal worker to determine whether there is a BlockIo somewhere
  upon the device path specified.

  @param[in] DevicePath    The device path to test.

  @retval TRUE      gEfiBlockIoProtocolGuid was installed on a handle with this device path
  @retval FALSE     gEfiBlockIoProtocolGuid was not found.
**/
BOOLEAN
InternalShellProtocolIsBlockIoPresent (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathCopy;
  EFI_STATUS                Status;
  EFI_HANDLE                Handle;

  Handle = NULL;

  DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
  Status         = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathCopy, &Handle);

  if ((Handle != NULL) && (!EFI_ERROR (Status))) {
    return (TRUE);
  }

  return (FALSE);
}

/**
  Internal worker to determine whether there is a file system somewhere
  upon the device path specified.

  @param[in] DevicePath    The device path to test.

  @retval TRUE      gEfiSimpleFileSystemProtocolGuid was installed on a handle with this device path
  @retval FALSE     gEfiSimpleFileSystemProtocolGuid was not found.
**/
BOOLEAN
InternalShellProtocolIsSimpleFileSystemPresent (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathCopy;
  EFI_STATUS                Status;
  EFI_HANDLE                Handle;

  Handle = NULL;

  DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
  Status         = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &Handle);

  if ((Handle != NULL) && (!EFI_ERROR (Status))) {
    return (TRUE);
  }

  return (FALSE);
}

/**
  This function creates a mapping for a device path.

  If both DevicePath and Mapping are NULL, this will reset the mapping to default values.

  @param DevicePath             Points to the device path. If this is NULL and Mapping points to a valid mapping,
                                then the mapping will be deleted.
  @param Mapping                Points to the NULL-terminated mapping for the device path.  Must end with a ':'

  @retval EFI_SUCCESS           Mapping created or deleted successfully.
  @retval EFI_NO_MAPPING        There is no handle that corresponds exactly to DevicePath. See the
                                boot service function LocateDevicePath().
  @retval EFI_ACCESS_DENIED     The mapping is a built-in alias.
  @retval EFI_INVALID_PARAMETER Mapping was NULL
  @retval EFI_INVALID_PARAMETER Mapping did not end with a ':'
  @retval EFI_INVALID_PARAMETER DevicePath was not pointing at a device that had a SIMPLE_FILE_SYSTEM_PROTOCOL installed.
  @retval EFI_NOT_FOUND         There was no mapping found to delete
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed
**/
EFI_STATUS
EFIAPI
EfiShellSetMap (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath OPTIONAL,
  IN CONST CHAR16                    *Mapping
  )
{
  EFI_STATUS      Status;
  SHELL_MAP_LIST  *MapListNode;

  if (Mapping == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  if (Mapping[StrLen (Mapping)-1] != ':') {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Delete the mapping
  //
  if (DevicePath == NULL) {
    if (IsListEmpty (&gShellMapList.Link)) {
      return (EFI_NOT_FOUND);
    }

    for ( MapListNode = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
          ; !IsNull (&gShellMapList.Link, &MapListNode->Link)
          ; MapListNode = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &MapListNode->Link)
          )
    {
      if (StringNoCaseCompare (&MapListNode->MapName, &Mapping) == 0) {
        RemoveEntryList (&MapListNode->Link);
        SHELL_FREE_NON_NULL (MapListNode->DevicePath);
        SHELL_FREE_NON_NULL (MapListNode->MapName);
        SHELL_FREE_NON_NULL (MapListNode->CurrentDirectoryPath);
        FreePool (MapListNode);
        return (EFI_SUCCESS);
      }
    } // for loop

    //
    // We didn't find one to delete
    //
    return (EFI_NOT_FOUND);
  }

  //
  // make sure this is a valid to add device path
  //
  /// @todo add BlockIo to this test...
  if (  !InternalShellProtocolIsSimpleFileSystemPresent (DevicePath)
     && !InternalShellProtocolIsBlockIoPresent (DevicePath))
  {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // First make sure there is no old mapping
  //
  Status = EfiShellSetMap (NULL, Mapping);
  if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_FOUND)) {
    return (Status);
  }

  //
  // now add the new one.
  //
  Status = ShellCommandAddMapItemAndUpdatePath (Mapping, DevicePath, 0, FALSE);

  return (Status);
}

/**
  Gets the device path from the mapping.

  This function gets the device path associated with a mapping.

  @param Mapping                A pointer to the mapping

  @retval !=NULL                Pointer to the device path that corresponds to the
                                device mapping. The returned pointer does not need
                                to be freed.
  @retval NULL                  There is no device path associated with the
                                specified mapping.
**/
CONST EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
EfiShellGetDevicePathFromMap (
  IN CONST CHAR16  *Mapping
  )
{
  SHELL_MAP_LIST  *MapListItem;
  CHAR16          *NewName;
  UINTN           Size;

  NewName = NULL;
  Size    = 0;

  StrnCatGrow (&NewName, &Size, Mapping, 0);
  if (Mapping[StrLen (Mapping)-1] != L':') {
    StrnCatGrow (&NewName, &Size, L":", 0);
  }

  MapListItem = ShellCommandFindMapItem (NewName);

  FreePool (NewName);

  if (MapListItem != NULL) {
    return (MapListItem->DevicePath);
  }

  return (NULL);
}

/**
  Gets the mapping(s) that most closely matches the device path.

  This function gets the mapping which corresponds to the device path *DevicePath. If
  there is no exact match, then the mapping which most closely matches *DevicePath
  is returned, and *DevicePath is updated to point to the remaining portion of the
  device path. If there is an exact match, the mapping is returned and *DevicePath
  points to the end-of-device-path node.

  If there are multiple map names they will be semi-colon separated in the
  NULL-terminated string.

  @param DevicePath             On entry, points to a device path pointer. On
                                exit, updates the pointer to point to the
                                portion of the device path after the mapping.

  @retval NULL                  No mapping was found.
  @return !=NULL                Pointer to NULL-terminated mapping. The buffer
                                is callee allocated and should be freed by the caller.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetMapFromDevicePath (
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
  )
{
  SHELL_MAP_LIST  *Node;
  CHAR16          *PathForReturn;
  UINTN           PathSize;

  //  EFI_HANDLE                  PathHandle;
  //  EFI_HANDLE                  MapHandle;
  //  EFI_STATUS                  Status;
  //  EFI_DEVICE_PATH_PROTOCOL    *DevicePathCopy;
  //  EFI_DEVICE_PATH_PROTOCOL    *MapPathCopy;

  if ((DevicePath == NULL) || (*DevicePath == NULL)) {
    return (NULL);
  }

  PathForReturn = NULL;
  PathSize      = 0;

  for ( Node = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
        ; !IsNull (&gShellMapList.Link, &Node->Link)
        ; Node = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &Node->Link)
        )
  {
    //
    // check for exact match
    //
    if (DevicePathCompare (DevicePath, &Node->DevicePath) == 0) {
      ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
      if (PathSize != 0) {
        PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L";", 0);
      }

      PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, Node->MapName, 0);
    }
  }

  if (PathForReturn != NULL) {
    while (!IsDevicePathEndType (*DevicePath)) {
      *DevicePath = NextDevicePathNode (*DevicePath);
    }

    //
    // Do not call SetDevicePathEndNode() if the device path node is already the
    // end of an entire device path.
    //
    if (!IsDevicePathEnd (*DevicePath)) {
      SetDevicePathEndNode (*DevicePath);
    }
  }

  /*
    ///@todo finish code for inexact matches.
    if (PathForReturn == NULL) {
      PathSize = 0;

      DevicePathCopy = DuplicateDevicePath(*DevicePath);
      ASSERT(DevicePathCopy != NULL);
      Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &PathHandle);
      ASSERT_EFI_ERROR(Status);
      //
      //  check each of the device paths we have to get the root of the path for consist mappings
      //
      for ( Node = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
          ; !IsNull(&gShellMapList.Link, &Node->Link)
          ; Node = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &Node->Link)
         ){
        if ((Node->Flags & SHELL_MAP_FLAGS_CONSIST) == 0) {
          continue;
        }
        MapPathCopy = DuplicateDevicePath(Node->DevicePath);
        ASSERT(MapPathCopy != NULL);
        Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
        if (MapHandle == PathHandle) {

          *DevicePath = DevicePathCopy;

          MapPathCopy = NULL;
          DevicePathCopy = NULL;
          PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, Node->MapName, 0);
          PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L";", 0);
          break;
        }
      }
      //
      // now add on the non-consistent mappings
      //
      for ( Node = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
          ; !IsNull(&gShellMapList.Link, &Node->Link)
          ; Node = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &Node->Link)
         ){
        if ((Node->Flags & SHELL_MAP_FLAGS_CONSIST) != 0) {
          continue;
        }
        MapPathCopy = Node->DevicePath;
        ASSERT(MapPathCopy != NULL);
        Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
        if (MapHandle == PathHandle) {
          PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, Node->MapName, 0);
          PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L";", 0);
          break;
        }
      }
    }
  */

  return (AddBufferToFreeList (PathForReturn));
}

/**
  Converts a device path to a file system-style path.

  This function converts a device path to a file system path by replacing part, or all, of
  the device path with the file-system mapping. If there are more than one application
  file system mappings, the one that most closely matches Path will be used.

  @param Path                   The pointer to the device path

  @retval NULL                  the device path could not be found.
  @return all                   The pointer of the NULL-terminated file path. The path
                                is callee-allocated and should be freed by the caller.
**/
CHAR16 *
EFIAPI
EfiShellGetFilePathFromDevicePath (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Path
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathCopy;
  EFI_DEVICE_PATH_PROTOCOL  *MapPathCopy;
  SHELL_MAP_LIST            *MapListItem;
  CHAR16                    *PathForReturn;
  UINTN                     PathSize;
  EFI_HANDLE                PathHandle;
  EFI_HANDLE                MapHandle;
  EFI_STATUS                Status;
  FILEPATH_DEVICE_PATH      *FilePath;
  FILEPATH_DEVICE_PATH      *AlignedNode;

  PathForReturn = NULL;
  PathSize      = 0;

  DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)Path;
  ASSERT (DevicePathCopy != NULL);
  if (DevicePathCopy == NULL) {
    return (NULL);
  }

  /// @todo BlockIo?
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &PathHandle);

  if (EFI_ERROR (Status)) {
    return (NULL);
  }

  //
  //  check each of the device paths we have to get the root of the path
  //
  for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
        ; !IsNull (&gShellMapList.Link, &MapListItem->Link)
        ; MapListItem = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &MapListItem->Link)
        )
  {
    MapPathCopy = (EFI_DEVICE_PATH_PROTOCOL *)MapListItem->DevicePath;
    ASSERT (MapPathCopy != NULL);
    /// @todo BlockIo?
    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
    if (MapHandle == PathHandle) {
      ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
      PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, MapListItem->MapName, 0);
      //
      // go through all the remaining nodes in the device path
      //
      for ( FilePath = (FILEPATH_DEVICE_PATH *)DevicePathCopy
            ; !IsDevicePathEnd (&FilePath->Header)
            ; FilePath = (FILEPATH_DEVICE_PATH *)NextDevicePathNode (&FilePath->Header)
            )
      {
        //
        // If any node is not a file path node, then the conversion can not be completed
        //
        if ((DevicePathType (&FilePath->Header) != MEDIA_DEVICE_PATH) ||
            (DevicePathSubType (&FilePath->Header) != MEDIA_FILEPATH_DP))
        {
          if (PathForReturn != NULL) {
            FreePool (PathForReturn);
          }

          return NULL;
        }

        //
        // append the path part onto the filepath.
        //
        ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));

        AlignedNode = AllocateCopyPool (DevicePathNodeLength (FilePath), FilePath);
        if (AlignedNode == NULL) {
          if (PathForReturn != NULL) {
            FreePool (PathForReturn);
          }

          return NULL;
        }

        // File Path Device Path Nodes 'can optionally add a "\" separator to
        //  the beginning and/or the end of the Path Name string.'
        // (UEFI Spec 2.4 section 9.3.6.4).
        // If necessary, add a "\", but otherwise don't
        // (This is specified in the above section, and also implied by the
        //  UEFI Shell spec section 3.7)
        if ((PathSize != 0)                        &&
            (PathForReturn != NULL)                &&
            (PathForReturn[PathSize / sizeof (CHAR16) - 1] != L'\\') &&
            (AlignedNode->PathName[0]    != L'\\'))
        {
          PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L"\\", 1);
        }

        PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, AlignedNode->PathName, 0);
        FreePool (AlignedNode);
      } // for loop of remaining nodes
    }

    if (PathForReturn != NULL) {
      break;
    }
  } // for loop of paths to check

  return (PathForReturn);
}

/**
  Converts a file system style name to a device path.

  This function converts a file system style name to a device path, by replacing any
  mapping references to the associated device path.

  @param[in] Path               The pointer to the path.

  @return                       The pointer of the file path. The file path is callee
                                allocated and should be freed by the caller.
  @retval NULL                  The path could not be found.
  @retval NULL                  There was not enough available memory.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
EfiShellGetDevicePathFromFilePath (
  IN CONST CHAR16  *Path
  )
{
  CHAR16                          *MapName;
  CHAR16                          *NewPath;
  CONST CHAR16                    *Cwd;
  UINTN                           Size;
  CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePathCopy;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePathCopyForFree;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePathForReturn;
  EFI_HANDLE                      Handle;
  EFI_STATUS                      Status;

  if (Path == NULL) {
    return (NULL);
  }

  MapName = NULL;
  NewPath = NULL;

  if (StrStr (Path, L":") == NULL) {
    Cwd = EfiShellGetCurDir (NULL);
    if (Cwd == NULL) {
      return (NULL);
    }

    Size    = StrSize (Cwd) + StrSize (Path);
    NewPath = AllocateZeroPool (Size);
    if (NewPath == NULL) {
      return (NULL);
    }

    StrCpyS (NewPath, Size/sizeof (CHAR16), Cwd);
    StrCatS (NewPath, Size/sizeof (CHAR16), L"\\");
    if (*Path == L'\\') {
      Path++;
      while (PathRemoveLastItem (NewPath)) {
      }
    }

    StrCatS (NewPath, Size/sizeof (CHAR16), Path);
    DevicePathForReturn = EfiShellGetDevicePathFromFilePath (NewPath);
    FreePool (NewPath);
    return (DevicePathForReturn);
  }

  Size = 0;
  //
  // find the part before (but including) the : for the map name
  //
  ASSERT ((MapName == NULL && Size == 0) || (MapName != NULL));
  MapName = StrnCatGrow (&MapName, &Size, Path, (StrStr (Path, L":")-Path+1));
  if ((MapName == NULL) || (MapName[StrLen (MapName)-1] != L':')) {
    return (NULL);
  }

  //
  // look up the device path in the map
  //
  DevicePath = EfiShellGetDevicePathFromMap (MapName);
  if (DevicePath == NULL) {
    //
    // Must have been a bad Mapname
    //
    return (NULL);
  }

  //
  // make a copy for LocateDevicePath to modify (also save a pointer to call FreePool with)
  //
  DevicePathCopyForFree = DevicePathCopy = DuplicateDevicePath (DevicePath);
  if (DevicePathCopy == NULL) {
    FreePool (MapName);
    return (NULL);
  }

  //
  // get the handle
  //
  /// @todo BlockIo?
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &Handle);
  if (EFI_ERROR (Status)) {
    if (DevicePathCopyForFree != NULL) {
      FreePool (DevicePathCopyForFree);
    }

    FreePool (MapName);
    return (NULL);
  }

  //
  // build the full device path
  //
  if ((*(Path+StrLen (MapName)) != CHAR_NULL) &&
      (*(Path+StrLen (MapName)+1) == CHAR_NULL))
  {
    DevicePathForReturn = FileDevicePath (Handle, L"\\");
  } else {
    DevicePathForReturn = FileDevicePath (Handle, Path+StrLen (MapName));
  }

  FreePool (MapName);
  if (DevicePathCopyForFree != NULL) {
    FreePool (DevicePathCopyForFree);
  }

  return (DevicePathForReturn);
}

/**
  Gets the name of the device specified by the device handle.

  This function gets the user-readable name of the device specified by the device
  handle. If no user-readable name could be generated, then *BestDeviceName will be
  NULL and EFI_NOT_FOUND will be returned.

  If EFI_DEVICE_NAME_USE_COMPONENT_NAME is set, then the function will return the
  device's name using the EFI_COMPONENT_NAME2_PROTOCOL, if present on
  DeviceHandle.

  If EFI_DEVICE_NAME_USE_DEVICE_PATH is set, then the function will return the
  device's name using the EFI_DEVICE_PATH_PROTOCOL, if present on DeviceHandle.
  If both EFI_DEVICE_NAME_USE_COMPONENT_NAME and
  EFI_DEVICE_NAME_USE_DEVICE_PATH are set, then
  EFI_DEVICE_NAME_USE_COMPONENT_NAME will have higher priority.

  @param DeviceHandle           The handle of the device.
  @param Flags                  Determines the possible sources of component names.
                                Valid bits are:
                                  EFI_DEVICE_NAME_USE_COMPONENT_NAME
                                  EFI_DEVICE_NAME_USE_DEVICE_PATH
  @param Language               A pointer to the language specified for the device
                                name, in the same format as described in the UEFI
                                specification, Appendix M
  @param BestDeviceName         On return, points to the callee-allocated NULL-
                                terminated name of the device. If no device name
                                could be found, points to NULL. The name must be
                                freed by the caller...

  @retval EFI_SUCCESS           Get the name successfully.
  @retval EFI_NOT_FOUND         Fail to get the device name.
  @retval EFI_INVALID_PARAMETER Flags did not have a valid bit set.
  @retval EFI_INVALID_PARAMETER BestDeviceName was NULL
  @retval EFI_INVALID_PARAMETER DeviceHandle was NULL
**/
EFI_STATUS
EFIAPI
EfiShellGetDeviceName (
  IN EFI_HANDLE                   DeviceHandle,
  IN EFI_SHELL_DEVICE_NAME_FLAGS  Flags,
  IN CHAR8                        *Language,
  OUT CHAR16                      **BestDeviceName
  )
{
  EFI_STATUS                    Status;
  EFI_COMPONENT_NAME2_PROTOCOL  *CompName2;
  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
  EFI_HANDLE                    *HandleList;
  UINTN                         HandleCount;
  UINTN                         LoopVar;
  CHAR16                        *DeviceNameToReturn;
  CHAR8                         *Lang;
  UINTN                         ParentControllerCount;
  EFI_HANDLE                    *ParentControllerBuffer;
  UINTN                         ParentDriverCount;
  EFI_HANDLE                    *ParentDriverBuffer;

  if ((BestDeviceName == NULL) ||
      (DeviceHandle   == NULL)
      )
  {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // make sure one of the 2 supported bits is on
  //
  if (((Flags & EFI_DEVICE_NAME_USE_COMPONENT_NAME) == 0) &&
      ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) == 0))
  {
    return (EFI_INVALID_PARAMETER);
  }

  DeviceNameToReturn = NULL;
  *BestDeviceName    = NULL;
  HandleList         = NULL;
  HandleCount        = 0;
  Lang               = NULL;

  if ((Flags & EFI_DEVICE_NAME_USE_COMPONENT_NAME) != 0) {
    Status = ParseHandleDatabaseByRelationship (
               NULL,
               DeviceHandle,
               HR_DRIVER_BINDING_HANDLE|HR_DEVICE_DRIVER,
               &HandleCount,
               &HandleList
               );
    for (LoopVar = 0; LoopVar < HandleCount; LoopVar++) {
      //
      // Go through those handles until we get one that passes for GetComponentName
      //
      Status = gBS->OpenProtocol (
                      HandleList[LoopVar],
                      &gEfiComponentName2ProtocolGuid,
                      (VOID **)&CompName2,
                      gImageHandle,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (EFI_ERROR (Status)) {
        Status = gBS->OpenProtocol (
                        HandleList[LoopVar],
                        &gEfiComponentNameProtocolGuid,
                        (VOID **)&CompName2,
                        gImageHandle,
                        NULL,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
      }

      if (EFI_ERROR (Status)) {
        continue;
      }

      Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
      if (Lang == NULL) {
        continue;
      }

      Status = CompName2->GetControllerName (CompName2, DeviceHandle, NULL, Lang, &DeviceNameToReturn);
      FreePool (Lang);
      Lang = NULL;
      if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
        break;
      }
    }

    if (HandleList != NULL) {
      FreePool (HandleList);
    }

    //
    // Now check the parent controller using this as the child.
    //
    Status = PARSE_HANDLE_DATABASE_PARENTS (DeviceHandle, &ParentControllerCount, &ParentControllerBuffer);
    if ((DeviceNameToReturn == NULL) && !EFI_ERROR (Status)) {
      for (LoopVar = 0; LoopVar < ParentControllerCount; LoopVar++) {
        Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (ParentControllerBuffer[LoopVar], &ParentDriverCount, &ParentDriverBuffer);
        if (!EFI_ERROR (Status)) {
          for (HandleCount = 0; HandleCount < ParentDriverCount; HandleCount++) {
            //
            // try using that driver's component name with controller and our driver as the child.
            //
            Status = gBS->OpenProtocol (
                            ParentDriverBuffer[HandleCount],
                            &gEfiComponentName2ProtocolGuid,
                            (VOID **)&CompName2,
                            gImageHandle,
                            NULL,
                            EFI_OPEN_PROTOCOL_GET_PROTOCOL
                            );
            if (EFI_ERROR (Status)) {
              Status = gBS->OpenProtocol (
                              ParentDriverBuffer[HandleCount],
                              &gEfiComponentNameProtocolGuid,
                              (VOID **)&CompName2,
                              gImageHandle,
                              NULL,
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL
                              );
            }

            if (EFI_ERROR (Status)) {
              continue;
            }

            Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
            if (Lang == NULL) {
              continue;
            }

            Status = CompName2->GetControllerName (CompName2, ParentControllerBuffer[LoopVar], DeviceHandle, Lang, &DeviceNameToReturn);
            FreePool (Lang);
            Lang = NULL;
            if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
              break;
            }
          }

          SHELL_FREE_NON_NULL (ParentDriverBuffer);
          if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
            break;
          }
        }
      }

      SHELL_FREE_NON_NULL (ParentControllerBuffer);
    }

    //
    // dont return on fail since we will try device path if that bit is on
    //
    if (DeviceNameToReturn != NULL) {
      ASSERT (BestDeviceName != NULL);
      StrnCatGrow (BestDeviceName, NULL, DeviceNameToReturn, 0);
      return (EFI_SUCCESS);
    }
  }

  if ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) != 0) {
    Status = gBS->OpenProtocol (
                    DeviceHandle,
                    &gEfiDevicePathProtocolGuid,
                    (VOID **)&DevicePath,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      //
      // use device path to text on the device path
      //
      *BestDeviceName = ConvertDevicePathToText (DevicePath, TRUE, TRUE);
      return (EFI_SUCCESS);
    }
  }

  //
  // none of the selected bits worked.
  //
  return (EFI_NOT_FOUND);
}

/**
  Opens the root directory of a device on a handle

  This function opens the root directory of a device and returns a file handle to it.

  @param DeviceHandle           The handle of the device that contains the volume.
  @param FileHandle             On exit, points to the file handle corresponding to the root directory on the
                                device.

  @retval EFI_SUCCESS           Root opened successfully.
  @retval EFI_NOT_FOUND         EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory
                                could not be opened.
  @retval EFI_VOLUME_CORRUPTED  The data structures in the volume were corrupted.
  @retval EFI_DEVICE_ERROR      The device had an error.
  @retval Others                Error status returned from EFI_SIMPLE_FILE_SYSTEM_PROTOCOL->OpenVolume().
**/
EFI_STATUS
EFIAPI
EfiShellOpenRootByHandle (
  IN EFI_HANDLE          DeviceHandle,
  OUT SHELL_FILE_HANDLE  *FileHandle
  )
{
  EFI_STATUS                       Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFileSystem;
  EFI_FILE_PROTOCOL                *RealFileHandle;
  EFI_DEVICE_PATH_PROTOCOL         *DevPath;

  //
  // get the simple file system interface
  //
  Status = gBS->OpenProtocol (
                  DeviceHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **)&SimpleFileSystem,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return (EFI_NOT_FOUND);
  }

  Status = gBS->OpenProtocol (
                  DeviceHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevPath,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return (EFI_NOT_FOUND);
  }

  //
  // Open the root volume now...
  //
  Status = SimpleFileSystem->OpenVolume (SimpleFileSystem, &RealFileHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *FileHandle = ConvertEfiFileProtocolToShellHandle (RealFileHandle, EfiShellGetMapFromDevicePath (&DevPath));
  return (EFI_SUCCESS);
}

/**
  Opens the root directory of a device.

  This function opens the root directory of a device and returns a file handle to it.

  @param DevicePath             Points to the device path corresponding to the device where the
                                EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed.
  @param FileHandle             On exit, points to the file handle corresponding to the root directory on the
                                device.

  @retval EFI_SUCCESS           Root opened successfully.
  @retval EFI_NOT_FOUND         EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory
                                could not be opened.
  @retval EFI_VOLUME_CORRUPTED  The data structures in the volume were corrupted.
  @retval EFI_DEVICE_ERROR      The device had an error
  @retval EFI_INVALID_PARAMETER FileHandle is NULL.
**/
EFI_STATUS
EFIAPI
EfiShellOpenRoot (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT SHELL_FILE_HANDLE        *FileHandle
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  Handle;

  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // find the handle of the device with that device handle and the file system
  //
  /// @todo BlockIo?
  Status = gBS->LocateDevicePath (
                  &gEfiSimpleFileSystemProtocolGuid,
                  &DevicePath,
                  &Handle
                  );
  if (EFI_ERROR (Status)) {
    return (EFI_NOT_FOUND);
  }

  return (EfiShellOpenRootByHandle (Handle, FileHandle));
}

/**
  Returns whether any script files are currently being processed.

  @retval TRUE                 There is at least one script file active.
  @retval FALSE                No script files are active now.

**/
BOOLEAN
EFIAPI
EfiShellBatchIsActive (
  VOID
  )
{
  if (ShellCommandGetCurrentScriptFile () == NULL) {
    return (FALSE);
  }

  return (TRUE);
}

/**
  Worker function to open a file based on a device path.  this will open the root
  of the volume and then traverse down to the file itself.

  @param DevicePath               Device Path of the file.
  @param FileHandle               Pointer to the file upon a successful return.
  @param OpenMode                 mode to open file in.
  @param Attributes               the File Attributes to use when creating a new file.

  @retval EFI_SUCCESS             the file is open and FileHandle is valid
  @retval EFI_UNSUPPORTED         the device path contained non-path elements
  @retval other                   an error occurred.
**/
EFI_STATUS
InternalOpenFileDevicePath (
  IN OUT EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT SHELL_FILE_HANDLE            *FileHandle,
  IN UINT64                        OpenMode,
  IN UINT64                        Attributes OPTIONAL
  )
{
  EFI_STATUS            Status;
  FILEPATH_DEVICE_PATH  *FilePathNode;
  EFI_HANDLE            Handle;
  SHELL_FILE_HANDLE     ShellHandle;
  EFI_FILE_PROTOCOL     *Handle1;
  EFI_FILE_PROTOCOL     *Handle2;
  FILEPATH_DEVICE_PATH  *AlignedNode;

  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  *FileHandle  = NULL;
  Handle1      = NULL;
  Handle2      = NULL;
  Handle       = NULL;
  ShellHandle  = NULL;
  FilePathNode = NULL;
  AlignedNode  = NULL;

  Status = EfiShellOpenRoot (DevicePath, &ShellHandle);

  if (!EFI_ERROR (Status)) {
    Handle1 = ConvertShellHandleToEfiFileProtocol (ShellHandle);
    if (Handle1 != NULL) {
      //
      // chop off the beginning part before the file system part...
      //
      /// @todo BlockIo?
      Status = gBS->LocateDevicePath (
                      &gEfiSimpleFileSystemProtocolGuid,
                      &DevicePath,
                      &Handle
                      );
      if (!EFI_ERROR (Status)) {
        //
        // To access as a file system, the file path should only
        // contain file path components.  Follow the file path nodes
        // and find the target file
        //
        for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath
              ; !IsDevicePathEnd (&FilePathNode->Header)
              ; FilePathNode = (FILEPATH_DEVICE_PATH *)NextDevicePathNode (&FilePathNode->Header)
              )
        {
          SHELL_FREE_NON_NULL (AlignedNode);
          AlignedNode = AllocateCopyPool (DevicePathNodeLength (FilePathNode), FilePathNode);
          //
          // For file system access each node should be a file path component
          //
          if ((DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH) ||
              (DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP)
              )
          {
            Status = EFI_UNSUPPORTED;
            break;
          }

          //
          // Open this file path node
          //
          Handle2 = Handle1;
          Handle1 = NULL;

          //
          // if this is the last node in the DevicePath always create (if that was requested).
          //
          if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) {
            Status = Handle2->Open (
                                Handle2,
                                &Handle1,
                                AlignedNode->PathName,
                                OpenMode,
                                Attributes
                                );
          } else {
            //
            //  This is not the last node and we dont want to 'create' existing
            //  directory entries...
            //

            //
            // open without letting it create
            // prevents error on existing files/directories
            //
            Status = Handle2->Open (
                                Handle2,
                                &Handle1,
                                AlignedNode->PathName,
                                OpenMode &~EFI_FILE_MODE_CREATE,
                                Attributes
                                );
            //
            // if above failed now open and create the 'item'
            // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above)
            //
            if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
              Status = Handle2->Open (
                                  Handle2,
                                  &Handle1,
                                  AlignedNode->PathName,
                                  OpenMode,
                                  Attributes
                                  );
            }
          }

          //
          // Close the last node
          //
          ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2);

          //
          // If there's been an error, stop
          //
          if (EFI_ERROR (Status)) {
            break;
          }
        } // for loop
      }
    }
  }

  SHELL_FREE_NON_NULL (AlignedNode);
  if (EFI_ERROR (Status)) {
    if (Handle1 != NULL) {
      ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle1);
    }
  } else {
    *FileHandle = ConvertEfiFileProtocolToShellHandle (Handle1, ShellFileHandleGetPath (ShellHandle));
  }

  return (Status);
}

/**
  Creates a file or directory by name.

  This function creates an empty new file or directory with the specified attributes and
  returns the new file's handle. If the file already exists and is read-only, then
  EFI_INVALID_PARAMETER will be returned.

  If the file already existed, it is truncated and its attributes updated. If the file is
  created successfully, the FileHandle is the file's handle, else, the FileHandle is NULL.

  If the file name begins with >v, then the file handle which is returned refers to the
  shell environment variable with the specified name. If the shell environment variable
  already exists and is non-volatile then EFI_INVALID_PARAMETER is returned.

  @param FileName           Pointer to NULL-terminated file path
  @param FileAttribs        The new file's attributes.  the different attributes are
                            described in EFI_FILE_PROTOCOL.Open().
  @param FileHandle         On return, points to the created file handle or directory's handle

  @retval EFI_SUCCESS       The file was opened.  FileHandle points to the new file's handle.
  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
  @retval EFI_UNSUPPORTED   could not open the file path
  @retval EFI_NOT_FOUND     the specified file could not be found on the device, or could not
                            file the file system on the device.
  @retval EFI_NO_MEDIA      the device has no medium.
  @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
                            longer supported.
  @retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according
                            the DirName.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write
                            when the media is write-protected.
  @retval EFI_ACCESS_DENIED The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
  @retval EFI_VOLUME_FULL   The volume is full.
**/
EFI_STATUS
EFIAPI
EfiShellCreateFile (
  IN CONST CHAR16        *FileName,
  IN UINT64              FileAttribs,
  OUT SHELL_FILE_HANDLE  *FileHandle
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
  BOOLEAN                   Volatile;

  //
  // Is this for an environment variable
  // do we start with >v
  //
  if (StrStr (FileName, L">v") == FileName) {
    Status = IsVolatileEnv (FileName + 2, &Volatile);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (!Volatile) {
      return (EFI_INVALID_PARAMETER);
    }

    *FileHandle = CreateFileInterfaceEnv (FileName+2);
    return (EFI_SUCCESS);
  }

  //
  // We are opening a regular file.
  //
  DevicePath = EfiShellGetDevicePathFromFilePath (FileName);
  if (DevicePath == NULL) {
    return (EFI_NOT_FOUND);
  }

  Status = InternalOpenFileDevicePath (DevicePath, FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, FileAttribs);
  FreePool (DevicePath);

  return (Status);
}

/**
  Register a GUID and a localized human readable name for it.

  If Guid is not assigned a name, then assign GuidName to Guid.  This list of GUID
  names must be used whenever a shell command outputs GUID information.

  This function is only available when the major and minor versions in the
  EfiShellProtocol are greater than or equal to 2 and 1, respectively.

  @param[in] Guid       A pointer to the GUID being registered.
  @param[in] GuidName   A pointer to the localized name for the GUID being registered.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_INVALID_PARAMETER   Guid was NULL.
  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
  @retval EFI_ACCESS_DENIED       Guid already is assigned a name.
**/
EFI_STATUS
EFIAPI
EfiShellRegisterGuidName (
  IN CONST EFI_GUID  *Guid,
  IN CONST CHAR16    *GuidName
  )
{
  return (AddNewGuidNameMapping (Guid, GuidName, NULL));
}

/**
  Opens a file or a directory by file name.

  This function opens the specified file in the specified OpenMode and returns a file
  handle.
  If the file name begins with >v, then the file handle which is returned refers to the
  shell environment variable with the specified name. If the shell environment variable
  exists, is non-volatile and the OpenMode indicates EFI_FILE_MODE_WRITE, then
  EFI_INVALID_PARAMETER is returned.

  If the file name is >i, then the file handle which is returned refers to the standard
  input. If the OpenMode indicates EFI_FILE_MODE_WRITE, then EFI_INVALID_PARAMETER
  is returned.

  If the file name is >o, then the file handle which is returned refers to the standard
  output. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER
  is returned.

  If the file name is >e, then the file handle which is returned refers to the standard
  error. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER
  is returned.

  If the file name is NUL, then the file handle that is returned refers to the standard NUL
  file. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER is
  returned.

  If return EFI_SUCCESS, the FileHandle is the opened file's handle, else, the
  FileHandle is NULL.

  @param FileName               Points to the NULL-terminated UCS-2 encoded file name.
  @param FileHandle             On return, points to the file handle.
  @param OpenMode               File open mode. Either EFI_FILE_MODE_READ or
                                EFI_FILE_MODE_WRITE from section 12.4 of the UEFI
                                Specification.
  @retval EFI_SUCCESS           The file was opened. FileHandle has the opened file's handle.
  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. FileHandle is NULL.
  @retval EFI_UNSUPPORTED       Could not open the file path. FileHandle is NULL.
  @retval EFI_NOT_FOUND         The specified file could not be found on the device or the file
                                system could not be found on the device. FileHandle is NULL.
  @retval EFI_NO_MEDIA          The device has no medium. FileHandle is NULL.
  @retval EFI_MEDIA_CHANGED     The device has a different medium in it or the medium is no
                                longer supported. FileHandle is NULL.
  @retval EFI_DEVICE_ERROR      The device reported an error or can't get the file path according
                                the FileName. FileHandle is NULL.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted. FileHandle is NULL.
  @retval EFI_WRITE_PROTECTED   An attempt was made to create a file, or open a file for write
                                when the media is write-protected. FileHandle is NULL.
  @retval EFI_ACCESS_DENIED     The service denied access to the file. FileHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES  Not enough resources were available to open the file. FileHandle
                                is NULL.
  @retval EFI_VOLUME_FULL       The volume is full. FileHandle is NULL.
**/
EFI_STATUS
EFIAPI
EfiShellOpenFileByName (
  IN CONST CHAR16        *FileName,
  OUT SHELL_FILE_HANDLE  *FileHandle,
  IN UINT64              OpenMode
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
  BOOLEAN                   Volatile;

  *FileHandle = NULL;

  //
  // Is this for StdIn
  //
  if (StrCmp (FileName, L">i") == 0) {
    //
    // make sure not writing to StdIn
    //
    if ((OpenMode & EFI_FILE_MODE_WRITE) != 0) {
      return (EFI_INVALID_PARAMETER);
    }

    *FileHandle = ShellInfoObject.NewShellParametersProtocol->StdIn;
    ASSERT (*FileHandle != NULL);
    return (EFI_SUCCESS);
  }

  //
  // Is this for StdOut
  //
  if (StrCmp (FileName, L">o") == 0) {
    //
    // make sure not writing to StdIn
    //
    if ((OpenMode & EFI_FILE_MODE_READ) != 0) {
      return (EFI_INVALID_PARAMETER);
    }

    *FileHandle = &FileInterfaceStdOut;
    return (EFI_SUCCESS);
  }

  //
  // Is this for NUL / NULL file
  //
  if ((gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)FileName, L"NUL") == 0) ||
      (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)FileName, L"NULL") == 0))
  {
    *FileHandle = &FileInterfaceNulFile;
    return (EFI_SUCCESS);
  }

  //
  // Is this for StdErr
  //
  if (StrCmp (FileName, L">e") == 0) {
    //
    // make sure not writing to StdIn
    //
    if ((OpenMode & EFI_FILE_MODE_READ) != 0) {
      return (EFI_INVALID_PARAMETER);
    }

    *FileHandle = &FileInterfaceStdErr;
    return (EFI_SUCCESS);
  }

  //
  // Is this for an environment variable
  // do we start with >v
  //
  if (StrStr (FileName, L">v") == FileName) {
    Status = IsVolatileEnv (FileName + 2, &Volatile);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (!Volatile &&
        ((OpenMode & EFI_FILE_MODE_WRITE) != 0))
    {
      return (EFI_INVALID_PARAMETER);
    }

    *FileHandle = CreateFileInterfaceEnv (FileName+2);
    return (EFI_SUCCESS);
  }

  //
  // We are opening a regular file.
  //
  DevicePath = EfiShellGetDevicePathFromFilePath (FileName);

  if (DevicePath == NULL) {
    return (EFI_NOT_FOUND);
  }

  //
  // Copy the device path, open the file, then free the memory
  //
  Status = InternalOpenFileDevicePath (DevicePath, FileHandle, OpenMode, 0); // 0 = no specific file attributes
  FreePool (DevicePath);

  return (Status);
}

/**
  Deletes the file specified by the file name.

  This function deletes a file.

  @param FileName                 Points to the NULL-terminated file name.

  @retval EFI_SUCCESS             The file was closed and deleted, and the handle was closed.
  @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
  @sa EfiShellCreateFile
**/
EFI_STATUS
EFIAPI
EfiShellDeleteFileByName (
  IN CONST CHAR16  *FileName
  )
{
  SHELL_FILE_HANDLE  FileHandle;
  EFI_STATUS         Status;

  FileHandle = NULL;

  //
  // get a handle to the file
  //
  Status = EfiShellCreateFile (
             FileName,
             0,
             &FileHandle
             );
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // now delete the file
  //
  ShellFileHandleRemove (FileHandle);
  return (ShellInfoObject.NewEfiShellProtocol->DeleteFile (FileHandle));
}

/**
  Disables the page break output mode.
**/
VOID
EFIAPI
EfiShellDisablePageBreak (
  VOID
  )
{
  ShellInfoObject.PageBreakEnabled = FALSE;
}

/**
  Enables the page break output mode.
**/
VOID
EFIAPI
EfiShellEnablePageBreak (
  VOID
  )
{
  ShellInfoObject.PageBreakEnabled = TRUE;
}

/**
  internal worker function to load and run an image via device path.

  @param ParentImageHandle      A handle of the image that is executing the specified
                                command line.
  @param DevicePath             device path of the file to execute
  @param CommandLine            Points to the NULL-terminated UCS-2 encoded string
                                containing the command line. If NULL then the command-
                                line will be empty.
  @param Environment            Points to a NULL-terminated array of environment
                                variables with the format 'x=y', where x is the
                                environment variable name and y is the value. If this
                                is NULL, then the current shell environment is used.

  @param[out] StartImageStatus  Returned status from gBS->StartImage.

  @retval EFI_SUCCESS       The command executed successfully. The  status code
                            returned by the command is pointed to by StatusCode.
  @retval EFI_INVALID_PARAMETER The parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES Out of resources.
  @retval EFI_UNSUPPORTED   Nested shell invocations are not allowed.
**/
EFI_STATUS
InternalShellExecuteDevicePath (
  IN CONST EFI_HANDLE                *ParentImageHandle,
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN CONST CHAR16                    *CommandLine OPTIONAL,
  IN CONST CHAR16                    **Environment OPTIONAL,
  OUT EFI_STATUS                     *StartImageStatus OPTIONAL
  )
{
  EFI_STATUS                     Status;
  EFI_STATUS                     StartStatus;
  EFI_STATUS                     CleanupStatus;
  EFI_HANDLE                     NewHandle;
  EFI_LOADED_IMAGE_PROTOCOL      *LoadedImage;
  LIST_ENTRY                     OrigEnvs;
  EFI_SHELL_PARAMETERS_PROTOCOL  ShellParamsProtocol;
  CHAR16                         *ImagePath;
  UINTN                          Index;
  CHAR16                         *Walker;
  CHAR16                         *NewCmdLine;

  if (ParentImageHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  InitializeListHead (&OrigEnvs);
  ZeroMem (&ShellParamsProtocol, sizeof (EFI_SHELL_PARAMETERS_PROTOCOL));

  NewHandle = NULL;

  NewCmdLine = AllocateCopyPool (StrSize (CommandLine), CommandLine);
  if (NewCmdLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
    if ((*Walker == L'^') && (*(Walker+1) == L'#')) {
      CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
    }
  }

  //
  // Load the image with:
  // FALSE - not from boot manager and NULL, 0 being not already in memory
  //
  Status = gBS->LoadImage (
                  FALSE,
                  *ParentImageHandle,
                  (EFI_DEVICE_PATH_PROTOCOL *)DevicePath,
                  NULL,
                  0,
                  &NewHandle
                  );

  if (EFI_ERROR (Status)) {
    if (NewHandle != NULL) {
      gBS->UnloadImage (NewHandle);
    }

    FreePool (NewCmdLine);
    return (Status);
  }

  Status = gBS->OpenProtocol (
                  NewHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (!EFI_ERROR (Status)) {
    //
    // If the image is not an app abort it.
    //
    if (LoadedImage->ImageCodeType != EfiLoaderCode) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_SHELL_IMAGE_NOT_APP),
        ShellInfoObject.HiiHandle
        );
      goto UnloadImage;
    }

    ASSERT (LoadedImage->LoadOptionsSize == 0);
    if (NewCmdLine != NULL) {
      LoadedImage->LoadOptionsSize = (UINT32)StrSize (NewCmdLine);
      LoadedImage->LoadOptions     = (VOID *)NewCmdLine;
    }

    //
    // Save our current environment settings for later restoration if necessary
    //
    if (Environment != NULL) {
      Status = GetEnvironmentVariableList (&OrigEnvs);
      if (!EFI_ERROR (Status)) {
        Status = SetEnvironmentVariables (Environment);
      }
    }

    //
    // Initialize and install a shell parameters protocol on the image.
    //
    ShellParamsProtocol.StdIn  = ShellInfoObject.NewShellParametersProtocol->StdIn;
    ShellParamsProtocol.StdOut = ShellInfoObject.NewShellParametersProtocol->StdOut;
    ShellParamsProtocol.StdErr = ShellInfoObject.NewShellParametersProtocol->StdErr;
    Status                     = UpdateArgcArgv (&ShellParamsProtocol, NewCmdLine, Efi_Application, NULL, NULL);
    if (EFI_ERROR (Status)) {
      goto UnloadImage;
    }

    //
    // Replace Argv[0] with the full path of the binary we're executing:
    // If the command line was "foo", the binary might be called "foo.efi".
    // "The first entry in [Argv] is always the full file path of the
    //  executable" - UEFI Shell Spec section 2.3
    //
    ImagePath = EfiShellGetFilePathFromDevicePath (DevicePath);
    // The image we're executing isn't necessarily in a filesystem - it might
    // be memory mapped. In this case EfiShellGetFilePathFromDevicePath will
    // return NULL, and we'll leave Argv[0] as UpdateArgcArgv set it.
    if (ImagePath != NULL) {
      if (ShellParamsProtocol.Argv == NULL) {
        // Command line was empty or null.
        // (UpdateArgcArgv sets Argv to NULL when CommandLine is "" or NULL)
        ShellParamsProtocol.Argv = AllocatePool (sizeof (CHAR16 *));
        if (ShellParamsProtocol.Argv == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto UnloadImage;
        }

        ShellParamsProtocol.Argc = 1;
      } else {
        // Free the string UpdateArgcArgv put in Argv[0];
        FreePool (ShellParamsProtocol.Argv[0]);
      }

      ShellParamsProtocol.Argv[0] = ImagePath;
    }

    Status = gBS->InstallProtocolInterface (&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);
    ASSERT_EFI_ERROR (Status);

    //
    // now start the image and if the caller wanted the return code pass it to them...
    //
    if (!EFI_ERROR (Status)) {
      StartStatus = gBS->StartImage (
                           NewHandle,
                           0,
                           NULL
                           );
      if (StartImageStatus != NULL) {
        *StartImageStatus = StartStatus;
      }

      CleanupStatus = gBS->UninstallProtocolInterface (
                             NewHandle,
                             &gEfiShellParametersProtocolGuid,
                             &ShellParamsProtocol
                             );
      ASSERT_EFI_ERROR (CleanupStatus);

      goto FreeAlloc;
    }

UnloadImage:
    // Unload image - We should only get here if we didn't call StartImage
    gBS->UnloadImage (NewHandle);

FreeAlloc:
    // Free Argv (Allocated in UpdateArgcArgv)
    if (ShellParamsProtocol.Argv != NULL) {
      for (Index = 0; Index < ShellParamsProtocol.Argc; Index++) {
        if (ShellParamsProtocol.Argv[Index] != NULL) {
          FreePool (ShellParamsProtocol.Argv[Index]);
        }
      }

      FreePool (ShellParamsProtocol.Argv);
    }
  }

  // Restore environment variables
  if (!IsListEmpty (&OrigEnvs)) {
    CleanupStatus = SetEnvironmentVariableList (&OrigEnvs);
    ASSERT_EFI_ERROR (CleanupStatus);
  }

  FreePool (NewCmdLine);

  return (Status);
}

/**
  internal worker function to load and run an image in the current shell.

  @param CommandLine            Points to the NULL-terminated UCS-2 encoded string
                                containing the command line. If NULL then the command-
                                line will be empty.
  @param Environment            Points to a NULL-terminated array of environment
                                variables with the format 'x=y', where x is the
                                environment variable name and y is the value. If this
                                is NULL, then the current shell environment is used.

  @param[out] StartImageStatus  Returned status from the command line.

  @retval EFI_SUCCESS       The command executed successfully. The  status code
                            returned by the command is pointed to by StatusCode.
  @retval EFI_INVALID_PARAMETER The parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES Out of resources.
  @retval EFI_UNSUPPORTED   Nested shell invocations are not allowed.
**/
EFI_STATUS
InternalShellExecute (
  IN CONST CHAR16  *CommandLine OPTIONAL,
  IN CONST CHAR16  **Environment OPTIONAL,
  OUT EFI_STATUS   *StartImageStatus OPTIONAL
  )
{
  EFI_STATUS  Status;
  EFI_STATUS  CleanupStatus;
  LIST_ENTRY  OrigEnvs;

  InitializeListHead (&OrigEnvs);

  //
  // Save our current environment settings for later restoration if necessary
  //
  if (Environment != NULL) {
    Status = GetEnvironmentVariableList (&OrigEnvs);
    if (!EFI_ERROR (Status)) {
      Status = SetEnvironmentVariables (Environment);
    } else {
      return Status;
    }
  }

  Status = RunShellCommand (CommandLine, StartImageStatus);

  // Restore environment variables
  if (!IsListEmpty (&OrigEnvs)) {
    CleanupStatus = SetEnvironmentVariableList (&OrigEnvs);
    ASSERT_EFI_ERROR (CleanupStatus);
  }

  return (Status);
}

/**
  Determine if the UEFI Shell is currently running with nesting enabled or disabled.

  @retval FALSE   nesting is required
  @retval other   nesting is enabled
**/
STATIC
BOOLEAN
NestingEnabled (
  VOID
  )
{
  EFI_STATUS  Status;
  CHAR16      *Temp;
  CHAR16      *Temp2;
  UINTN       TempSize;
  BOOLEAN     RetVal;

  RetVal = TRUE;
  Temp   = NULL;
  Temp2  = NULL;

  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
    TempSize = 0;
    Temp     = NULL;
    Status   = SHELL_GET_ENVIRONMENT_VARIABLE (mNoNestingEnvVarName, &TempSize, Temp);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Temp = AllocateZeroPool (TempSize + sizeof (CHAR16));
      if (Temp != NULL) {
        Status = SHELL_GET_ENVIRONMENT_VARIABLE (mNoNestingEnvVarName, &TempSize, Temp);
      }
    }

    Temp2 = StrnCatGrow (&Temp2, NULL, mNoNestingTrue, 0);
    if ((Temp != NULL) && (Temp2 != NULL) && (StringNoCaseCompare (&Temp, &Temp2) == 0)) {
      //
      // Use the no nesting method.
      //
      RetVal = FALSE;
    }
  }

  SHELL_FREE_NON_NULL (Temp);
  SHELL_FREE_NON_NULL (Temp2);
  return (RetVal);
}

/**
  Execute the command line.

  This function creates a nested instance of the shell and executes the specified
  command (CommandLine) with the specified environment (Environment). Upon return,
  the status code returned by the specified command is placed in StatusCode.

  If Environment is NULL, then the current environment is used and all changes made
  by the commands executed will be reflected in the current environment. If the
  Environment is non-NULL, then the changes made will be discarded.

  The CommandLine is executed from the current working directory on the current
  device.

  @param ParentImageHandle  A handle of the image that is executing the specified
                            command line.
  @param CommandLine        Points to the NULL-terminated UCS-2 encoded string
                            containing the command line. If NULL then the command-
                            line will be empty.
  @param Environment        Points to a NULL-terminated array of environment
                            variables with the format 'x=y', where x is the
                            environment variable name and y is the value. If this
                            is NULL, then the current shell environment is used.
  @param StatusCode         Points to the status code returned by the CommandLine.

  @retval EFI_SUCCESS       The command executed successfully. The  status code
                            returned by the command is pointed to by StatusCode.
  @retval EFI_INVALID_PARAMETER The parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES Out of resources.
  @retval EFI_UNSUPPORTED   Nested shell invocations are not allowed.
  @retval EFI_UNSUPPORTED   The support level required for this function is not present.

  @sa InternalShellExecuteDevicePath
**/
EFI_STATUS
EFIAPI
EfiShellExecute (
  IN EFI_HANDLE   *ParentImageHandle,
  IN CHAR16       *CommandLine OPTIONAL,
  IN CHAR16       **Environment OPTIONAL,
  OUT EFI_STATUS  *StatusCode OPTIONAL
  )
{
  EFI_STATUS                Status;
  CHAR16                    *Temp;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  UINTN                     Size;

  if ((PcdGet8 (PcdShellSupportLevel) < 1)) {
    return (EFI_UNSUPPORTED);
  }

  Temp = NULL;
  if (NestingEnabled ()) {
    DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
    if (DevPath == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DEBUG_CODE_BEGIN ();
    Temp = ConvertDevicePathToText (ShellInfoObject.FileDevPath, TRUE, TRUE);
    if (Temp != NULL) {
      FreePool (Temp);
    }

    Temp = ConvertDevicePathToText (ShellInfoObject.ImageDevPath, TRUE, TRUE);
    if (Temp != NULL) {
      FreePool (Temp);
    }

    if (DevPath != NULL) {
      Temp = ConvertDevicePathToText (DevPath, TRUE, TRUE);
    }

    if (Temp != NULL) {
      FreePool (Temp);
    }

    DEBUG_CODE_END ();

    Temp = NULL;
    Size = 0;
    ASSERT ((Temp == NULL && Size == 0) || (Temp != NULL));
    StrnCatGrow (&Temp, &Size, L"Shell.efi -exit ", 0);
    StrnCatGrow (&Temp, &Size, CommandLine, 0);

    Status = InternalShellExecuteDevicePath (
               ParentImageHandle,
               DevPath,
               Temp,
               (CONST CHAR16 **)Environment,
               StatusCode
               );

    //
    // de-allocate and return
    //
    FreePool (DevPath);
    FreePool (Temp);
  } else {
    Status = InternalShellExecute (
               (CONST CHAR16 *)CommandLine,
               (CONST CHAR16 **)Environment,
               StatusCode
               );
  }

  return (Status);
}

/**
  Utility cleanup function for EFI_SHELL_FILE_INFO objects.

  1) frees all pointers (non-NULL)
  2) Closes the SHELL_FILE_HANDLE

  @param FileListNode     pointer to the list node to free
**/
VOID
InternalFreeShellFileInfoNode (
  IN EFI_SHELL_FILE_INFO  *FileListNode
  )
{
  if (FileListNode->Info != NULL) {
    FreePool ((VOID *)FileListNode->Info);
  }

  if (FileListNode->FileName != NULL) {
    FreePool ((VOID *)FileListNode->FileName);
  }

  if (FileListNode->FullName != NULL) {
    FreePool ((VOID *)FileListNode->FullName);
  }

  if (FileListNode->Handle != NULL) {
    ShellInfoObject.NewEfiShellProtocol->CloseFile (FileListNode->Handle);
  }

  FreePool (FileListNode);
}

/**
  Frees the file list.

  This function cleans up the file list and any related data structures. It has no
  impact on the files themselves.

  @param FileList               The file list to free. Type EFI_SHELL_FILE_INFO is
                                defined in OpenFileList()

  @retval EFI_SUCCESS           Free the file list successfully.
  @retval EFI_INVALID_PARAMETER FileList was NULL or *FileList was NULL;
**/
EFI_STATUS
EFIAPI
EfiShellFreeFileList (
  IN EFI_SHELL_FILE_INFO  **FileList
  )
{
  EFI_SHELL_FILE_INFO  *ShellFileListItem;

  if ((FileList == NULL) || (*FileList == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
        ; !IsListEmpty (&(*FileList)->Link)
        ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
        )
  {
    RemoveEntryList (&ShellFileListItem->Link);
    InternalFreeShellFileInfoNode (ShellFileListItem);
  }

  InternalFreeShellFileInfoNode (*FileList);
  *FileList = NULL;
  return (EFI_SUCCESS);
}

/**
  Deletes the duplicate file names files in the given file list.

  This function deletes the reduplicate files in the given file list.

  @param FileList               A pointer to the first entry in the file list.

  @retval EFI_SUCCESS           Always success.
  @retval EFI_INVALID_PARAMETER FileList was NULL or *FileList was NULL;
**/
EFI_STATUS
EFIAPI
EfiShellRemoveDupInFileList (
  IN EFI_SHELL_FILE_INFO  **FileList
  )
{
  EFI_STATUS           Status;
  EFI_SHELL_FILE_INFO  *Duplicates;
  EFI_SHELL_FILE_INFO  *ShellFileListItem;
  EFI_SHELL_FILE_INFO  *ShellFileListItem2;
  EFI_SHELL_FILE_INFO  *TempNode;

  if ((FileList == NULL) || (*FileList == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = ShellSortFileList (
             FileList,
             &Duplicates,
             ShellSortFileListByFullName
             );
  if (!EFI_ERROR (Status)) {
    EfiShellFreeFileList (&Duplicates);
    return EFI_SUCCESS;
  }

  //
  // Fall back to the slow method that needs no extra memory, and so cannot
  // fail.
  //
  for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
        ; !IsNull (&(*FileList)->Link, &ShellFileListItem->Link)
        ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
        )
  {
    for ( ShellFileListItem2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
          ; !IsNull (&(*FileList)->Link, &ShellFileListItem2->Link)
          ; ShellFileListItem2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem2->Link)
          )
    {
      if (gUnicodeCollation->StriColl (
                               gUnicodeCollation,
                               (CHAR16 *)ShellFileListItem->FullName,
                               (CHAR16 *)ShellFileListItem2->FullName
                               ) == 0
          )
      {
        TempNode = (EFI_SHELL_FILE_INFO *)GetPreviousNode (
                                            &(*FileList)->Link,
                                            &ShellFileListItem2->Link
                                            );
        RemoveEntryList (&ShellFileListItem2->Link);
        InternalFreeShellFileInfoNode (ShellFileListItem2);
        // Set ShellFileListItem2 to PreviousNode so we don't access Freed
        // memory in GetNextNode in the loop expression above.
        ShellFileListItem2 = TempNode;
      }
    }
  }

  return (EFI_SUCCESS);
}

//
// This is the same structure as the external version, but it has no CONST qualifiers.
//
typedef struct {
  LIST_ENTRY           Link;      ///< Linked list members.
  EFI_STATUS           Status;    ///< Status of opening the file.  Valid only if Handle != NULL.
  CHAR16               *FullName; ///< Fully qualified filename.
  CHAR16               *FileName; ///< name of this file.
  SHELL_FILE_HANDLE    Handle;    ///< Handle for interacting with the opened file or NULL if closed.
  EFI_FILE_INFO        *Info;     ///< Pointer to the FileInfo struct for this file or NULL.
} EFI_SHELL_FILE_INFO_NO_CONST;

/**
  Allocates and duplicates a EFI_SHELL_FILE_INFO node.

  @param[in] Node     The node to copy from.
  @param[in] Save     TRUE to set Node->Handle to NULL, FALSE otherwise.

  @retval NULL        a memory allocation error occurred
  @return != NULL     a pointer to the new node
**/
EFI_SHELL_FILE_INFO *
InternalDuplicateShellFileInfo (
  IN       EFI_SHELL_FILE_INFO  *Node,
  IN BOOLEAN                    Save
  )
{
  EFI_SHELL_FILE_INFO_NO_CONST  *NewNode;

  //
  // try to confirm that the objects are in sync
  //
  ASSERT (sizeof (EFI_SHELL_FILE_INFO_NO_CONST) == sizeof (EFI_SHELL_FILE_INFO));

  NewNode = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
  if (NewNode == NULL) {
    return (NULL);
  }

  NewNode->FullName = AllocateCopyPool (StrSize (Node->FullName), Node->FullName);
  NewNode->FileName = AllocateCopyPool (StrSize (Node->FileName), Node->FileName);
  NewNode->Info     = AllocateCopyPool ((UINTN)Node->Info->Size, Node->Info);
  if (  (NewNode->FullName == NULL)
     || (NewNode->FileName == NULL)
     || (NewNode->Info == NULL)
        )
  {
    SHELL_FREE_NON_NULL (NewNode->FullName);
    SHELL_FREE_NON_NULL (NewNode->FileName);
    SHELL_FREE_NON_NULL (NewNode->Info);
    SHELL_FREE_NON_NULL (NewNode);
    return (NULL);
  }

  NewNode->Status = Node->Status;
  NewNode->Handle = Node->Handle;
  if (!Save) {
    Node->Handle = NULL;
  }

  return ((EFI_SHELL_FILE_INFO *)NewNode);
}

/**
  Allocates and populates a EFI_SHELL_FILE_INFO structure.  if any memory operation
  failed it will return NULL.

  @param[in] BasePath         the Path to prepend onto filename for FullPath
  @param[in] Status           Status member initial value.
  @param[in] FileName         FileName member initial value.
  @param[in] Handle           Handle member initial value.
  @param[in] Info             Info struct to copy.

  @retval NULL                An error occurred.
  @return                     a pointer to the newly allocated structure.
**/
EFI_SHELL_FILE_INFO *
CreateAndPopulateShellFileInfo (
  IN CONST CHAR16             *BasePath,
  IN CONST EFI_STATUS         Status,
  IN CONST CHAR16             *FileName,
  IN CONST SHELL_FILE_HANDLE  Handle,
  IN CONST EFI_FILE_INFO      *Info
  )
{
  EFI_SHELL_FILE_INFO  *ShellFileListItem;
  CHAR16               *TempString;
  UINTN                Size;

  TempString = NULL;
  Size       = 0;

  ShellFileListItem = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
  if (ShellFileListItem == NULL) {
    return (NULL);
  }

  if ((Info != NULL) && (Info->Size != 0)) {
    ShellFileListItem->Info = AllocateZeroPool ((UINTN)Info->Size);
    if (ShellFileListItem->Info == NULL) {
      FreePool (ShellFileListItem);
      return (NULL);
    }

    CopyMem (ShellFileListItem->Info, Info, (UINTN)Info->Size);
  } else {
    ShellFileListItem->Info = NULL;
  }

  if (FileName != NULL) {
    ASSERT (TempString == NULL);
    ShellFileListItem->FileName = StrnCatGrow (&TempString, 0, FileName, 0);
    if (ShellFileListItem->FileName == NULL) {
      FreePool (ShellFileListItem->Info);
      FreePool (ShellFileListItem);
      return (NULL);
    }
  } else {
    ShellFileListItem->FileName = NULL;
  }

  Size       = 0;
  TempString = NULL;
  if (BasePath != NULL) {
    ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
    TempString = StrnCatGrow (&TempString, &Size, BasePath, 0);
    if (TempString == NULL) {
      FreePool ((VOID *)ShellFileListItem->FileName);
      SHELL_FREE_NON_NULL (ShellFileListItem->Info);
      FreePool (ShellFileListItem);
      return (NULL);
    }
  }

  if (ShellFileListItem->FileName != NULL) {
    ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
    TempString = StrnCatGrow (&TempString, &Size, ShellFileListItem->FileName, 0);
    if (TempString == NULL) {
      FreePool ((VOID *)ShellFileListItem->FileName);
      FreePool (ShellFileListItem->Info);
      FreePool (ShellFileListItem);
      return (NULL);
    }
  }

  TempString = PathCleanUpDirectories (TempString);

  ShellFileListItem->FullName = TempString;
  ShellFileListItem->Status   = Status;
  ShellFileListItem->Handle   = Handle;

  return (ShellFileListItem);
}

/**
  Find all files in a specified directory.

  @param FileDirHandle          Handle of the directory to search.
  @param FileList               On return, points to the list of files in the directory
                                or NULL if there are no files in the directory.

  @retval EFI_SUCCESS           File information was returned successfully.
  @retval EFI_VOLUME_CORRUPTED  The file system structures have been corrupted.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_NO_MEDIA          The device media is not present.
  @retval EFI_INVALID_PARAMETER The FileDirHandle was not a directory.
  @return                       An error from FileHandleGetFileName().
**/
EFI_STATUS
EFIAPI
EfiShellFindFilesInDir (
  IN SHELL_FILE_HANDLE     FileDirHandle,
  OUT EFI_SHELL_FILE_INFO  **FileList
  )
{
  EFI_SHELL_FILE_INFO  *ShellFileList;
  EFI_SHELL_FILE_INFO  *ShellFileListItem;
  EFI_FILE_INFO        *FileInfo;
  EFI_STATUS           Status;
  BOOLEAN              NoFile;
  CHAR16               *TempString;
  CHAR16               *BasePath;
  UINTN                Size;
  CHAR16               *TempSpot;

  BasePath = NULL;
  Status   = FileHandleGetFileName (FileDirHandle, &BasePath);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  if (ShellFileHandleGetPath (FileDirHandle) != NULL) {
    TempString = NULL;
    Size       = 0;
    TempString = StrnCatGrow (&TempString, &Size, ShellFileHandleGetPath (FileDirHandle), 0);
    if (TempString == NULL) {
      SHELL_FREE_NON_NULL (BasePath);
      return (EFI_OUT_OF_RESOURCES);
    }

    TempSpot = StrStr (TempString, L";");

    if (TempSpot != NULL) {
      *TempSpot = CHAR_NULL;
    }

    TempString = StrnCatGrow (&TempString, &Size, BasePath, 0);
    if (TempString == NULL) {
      SHELL_FREE_NON_NULL (BasePath);
      return (EFI_OUT_OF_RESOURCES);
    }

    SHELL_FREE_NON_NULL (BasePath);
    BasePath = TempString;
  }

  NoFile            = FALSE;
  ShellFileList     = NULL;
  ShellFileListItem = NULL;
  FileInfo          = NULL;
  Status            = EFI_SUCCESS;

  for ( Status = FileHandleFindFirstFile (FileDirHandle, &FileInfo)
        ; !EFI_ERROR (Status) && !NoFile
        ; Status = FileHandleFindNextFile (FileDirHandle, FileInfo, &NoFile)
        )
  {
    if (ShellFileList == NULL) {
      ShellFileList = (EFI_SHELL_FILE_INFO *)AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
      if (ShellFileList == NULL) {
        SHELL_FREE_NON_NULL (BasePath);
        return EFI_OUT_OF_RESOURCES;
      }

      InitializeListHead (&ShellFileList->Link);
    }

    //
    // allocate a new EFI_SHELL_FILE_INFO and populate it...
    //
    ShellFileListItem = CreateAndPopulateShellFileInfo (
                          BasePath,
                          EFI_SUCCESS, // success since we didn't fail to open it...
                          FileInfo->FileName,
                          NULL, // no handle since not open
                          FileInfo
                          );
    if (ShellFileListItem == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      //
      // Free resources outside the loop.
      //
      break;
    }

    InsertTailList (&ShellFileList->Link, &ShellFileListItem->Link);
  }

  if (EFI_ERROR (Status)) {
    EfiShellFreeFileList (&ShellFileList);
    *FileList = NULL;
  } else {
    *FileList = ShellFileList;
  }

  SHELL_FREE_NON_NULL (BasePath);
  return (Status);
}

/**
  Get the GUID value from a human readable name.

  If GuidName is a known GUID name, then update Guid to have the correct value for
  that GUID.

  This function is only available when the major and minor versions in the
  EfiShellProtocol are greater than or equal to 2 and 1, respectively.

  @param[in]  GuidName   A pointer to the localized name for the GUID being queried.
  @param[out] Guid       A pointer to the GUID structure to be filled in.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_INVALID_PARAMETER   Guid was NULL.
  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
  @retval EFI_NOT_FOUND           GuidName is not a known GUID Name.
**/
EFI_STATUS
EFIAPI
EfiShellGetGuidFromName (
  IN  CONST CHAR16    *GuidName,
  OUT       EFI_GUID  *Guid
  )
{
  EFI_GUID    *NewGuid;
  EFI_STATUS  Status;

  if ((Guid == NULL) || (GuidName == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = GetGuidFromStringName (GuidName, NULL, &NewGuid);

  if (!EFI_ERROR (Status)) {
    CopyGuid (Guid, NewGuid);
  }

  return (Status);
}

/**
  Get the human readable name for a GUID from the value.

  If Guid is assigned a name, then update *GuidName to point to the name. The callee
  should not modify the value.

  This function is only available when the major and minor versions in the
  EfiShellProtocol are greater than or equal to 2 and 1, respectively.

  @param[in]  Guid       A pointer to the GUID being queried.
  @param[out] GuidName   A pointer to a pointer the localized to name for the GUID being requested

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_INVALID_PARAMETER   Guid was NULL.
  @retval EFI_INVALID_PARAMETER   GuidName was NULL.
  @retval EFI_NOT_FOUND           Guid is not assigned a name.
**/
EFI_STATUS
EFIAPI
EfiShellGetGuidName (
  IN  CONST EFI_GUID  *Guid,
  OUT CONST CHAR16    **GuidName
  )
{
  CHAR16  *Name;

  if ((Guid == NULL) || (GuidName == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  Name = GetStringNameFromGuid (Guid, NULL);
  if ((Name == NULL) || (StrLen (Name) == 0)) {
    SHELL_FREE_NON_NULL (Name);
    return (EFI_NOT_FOUND);
  }

  *GuidName = AddBufferToFreeList (Name);

  return (EFI_SUCCESS);
}

/**
  If FileHandle is a directory then the function reads from FileHandle and reads in
  each of the FileInfo structures.  If one of them matches the Pattern's first
  "level" then it opens that handle and calls itself on that handle.

  If FileHandle is a file and matches all of the remaining Pattern (which would be
  on its last node), then add a EFI_SHELL_FILE_INFO object for this file to fileList.

  Upon a EFI_SUCCESS return fromt he function any the caller is responsible to call
  FreeFileList with FileList.

  @param[in] FilePattern         The FilePattern to check against.
  @param[in] UnicodeCollation    The pointer to EFI_UNICODE_COLLATION_PROTOCOL structure
  @param[in] FileHandle          The FileHandle to start with
  @param[in, out] FileList       pointer to pointer to list of found files.
  @param[in] ParentNode          The node for the parent. Same file as identified by HANDLE.
  @param[in] MapName             The file system name this file is on.

  @retval EFI_SUCCESS           all files were found and the FileList contains a list.
  @retval EFI_NOT_FOUND         no files were found
  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed
**/
EFI_STATUS
ShellSearchHandle (
  IN     CONST CHAR16                          *FilePattern,
  IN           EFI_UNICODE_COLLATION_PROTOCOL  *UnicodeCollation,
  IN           SHELL_FILE_HANDLE               FileHandle,
  IN OUT       EFI_SHELL_FILE_INFO             **FileList,
  IN     CONST EFI_SHELL_FILE_INFO             *ParentNode OPTIONAL,
  IN     CONST CHAR16                          *MapName
  )
{
  EFI_STATUS           Status;
  CONST CHAR16         *NextFilePatternStart;
  CHAR16               *CurrentFilePattern;
  EFI_SHELL_FILE_INFO  *ShellInfo;
  EFI_SHELL_FILE_INFO  *ShellInfoNode;
  EFI_SHELL_FILE_INFO  *NewShellNode;
  EFI_FILE_INFO        *FileInfo;
  BOOLEAN              Directory;
  CHAR16               *NewFullName;
  UINTN                Size;

  NewShellNode = NULL;
  FileInfo     = NULL;
  if (  (FilePattern      == NULL)
     || (UnicodeCollation == NULL)
     || (FileList         == NULL)
        )
  {
    return (EFI_INVALID_PARAMETER);
  }

  ShellInfo          = NULL;
  CurrentFilePattern = NULL;

  if (*FilePattern == L'\\') {
    FilePattern++;
  }

  for ( NextFilePatternStart = FilePattern
        ; *NextFilePatternStart != CHAR_NULL && *NextFilePatternStart != L'\\'
        ; NextFilePatternStart++)
  {
  }

  CurrentFilePattern = AllocateZeroPool ((NextFilePatternStart-FilePattern+1)*sizeof (CHAR16));
  if (CurrentFilePattern == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StrnCpyS (CurrentFilePattern, NextFilePatternStart-FilePattern+1, FilePattern, NextFilePatternStart-FilePattern);

  if (  (CurrentFilePattern[0]   == CHAR_NULL)
     && (NextFilePatternStart[0] == CHAR_NULL)
        )
  {
    //
    // we want the parent or root node (if no parent)
    //
    if (ParentNode == NULL) {
      //
      // We want the root node.  create the node.
      //
      FileInfo = FileHandleGetInfo (FileHandle);
      if (FileInfo != NULL) {
        NewShellNode = CreateAndPopulateShellFileInfo (
                         MapName,
                         EFI_SUCCESS,
                         L"\\",
                         FileHandle,
                         FileInfo
                         );
      }

      SHELL_FREE_NON_NULL (FileInfo);
    } else {
      //
      // Add the current parameter FileHandle to the list, then end...
      //
      NewShellNode = InternalDuplicateShellFileInfo ((EFI_SHELL_FILE_INFO *)ParentNode, TRUE);
    }

    if (NewShellNode == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      NewShellNode->Handle = NULL;
      if (*FileList == NULL) {
        *FileList = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
        InitializeListHead (&((*FileList)->Link));
      }

      //
      // Add to the returning to use list
      //
      InsertTailList (&(*FileList)->Link, &NewShellNode->Link);

      Status = EFI_SUCCESS;
    }
  } else {
    Status = EfiShellFindFilesInDir (FileHandle, &ShellInfo);

    if (!EFI_ERROR (Status)) {
      if (StrStr (NextFilePatternStart, L"\\") != NULL) {
        Directory = TRUE;
      } else {
        Directory = FALSE;
      }

      for ( ShellInfoNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ShellInfo->Link)
            ; !IsNull (&ShellInfo->Link, &ShellInfoNode->Link)
            ; ShellInfoNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ShellInfo->Link, &ShellInfoNode->Link)
            )
      {
        if (UnicodeCollation->MetaiMatch (UnicodeCollation, (CHAR16 *)ShellInfoNode->FileName, CurrentFilePattern)) {
          if ((ShellInfoNode->FullName != NULL) && (StrStr (ShellInfoNode->FullName, L":") == NULL)) {
            Size        = StrSize (ShellInfoNode->FullName) + StrSize (MapName);
            NewFullName = AllocateZeroPool (Size);
            if (NewFullName == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              StrCpyS (NewFullName, Size / sizeof (CHAR16), MapName);
              StrCatS (NewFullName, Size / sizeof (CHAR16), ShellInfoNode->FullName);
              FreePool ((VOID *)ShellInfoNode->FullName);
              ShellInfoNode->FullName = NewFullName;
            }
          }

          if (Directory && !EFI_ERROR (Status) && (ShellInfoNode->FullName != NULL) && (ShellInfoNode->FileName != NULL)) {
            //
            // should be a directory
            //

            //
            // don't open the . and .. directories
            //
            if (!IsDotOrDotDot (ShellInfoNode->FileName)) {
              //
              //
              //
              if (EFI_ERROR (Status)) {
                break;
              }

              //
              // Open the directory since we need that handle in the next recursion.
              //
              ShellInfoNode->Status = EfiShellOpenFileByName (ShellInfoNode->FullName, &ShellInfoNode->Handle, EFI_FILE_MODE_READ);

              //
              // recurse with the next part of the pattern
              //
              Status = ShellSearchHandle (NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode, MapName);
              EfiShellClose (ShellInfoNode->Handle);
              ShellInfoNode->Handle = NULL;
            }
          } else if (!EFI_ERROR (Status)) {
            //
            // should be a file
            //

            //
            // copy the information we need into a new Node
            //
            NewShellNode = InternalDuplicateShellFileInfo (ShellInfoNode, FALSE);
            if (NewShellNode == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            }

            if (*FileList == NULL) {
              *FileList = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
              InitializeListHead (&((*FileList)->Link));
            }

            //
            // Add to the returning to use list
            //
            InsertTailList (&(*FileList)->Link, &NewShellNode->Link);
          }
        }

        if (EFI_ERROR (Status)) {
          break;
        }
      }

      if (EFI_ERROR (Status)) {
        EfiShellFreeFileList (&ShellInfo);
      } else {
        Status = EfiShellFreeFileList (&ShellInfo);
      }
    }
  }

  if ((*FileList == NULL) || ((*FileList != NULL) && IsListEmpty (&(*FileList)->Link))) {
    Status = EFI_NOT_FOUND;
  }

  FreePool (CurrentFilePattern);
  return (Status);
}

/**
  Find files that match a specified pattern.

  This function searches for all files and directories that match the specified
  FilePattern. The FilePattern can contain wild-card characters. The resulting file
  information is placed in the file list FileList.

  Wildcards are processed
  according to the rules specified in UEFI Shell 2.0 spec section 3.7.1.

  The files in the file list are not opened. The OpenMode field is set to 0 and the FileInfo
  field is set to NULL.

  if *FileList is not NULL then it must be a pre-existing and properly initialized list.

  @param FilePattern      Points to a NULL-terminated shell file path, including wildcards.
  @param FileList         On return, points to the start of a file list containing the names
                          of all matching files or else points to NULL if no matching files
                          were found.  only on a EFI_SUCCESS return will; this be non-NULL.

  @retval EFI_SUCCESS           Files found.  FileList is a valid list.
  @retval EFI_NOT_FOUND         No files found.
  @retval EFI_NO_MEDIA          The device has no media
  @retval EFI_DEVICE_ERROR      The device reported an error
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted
**/
EFI_STATUS
EFIAPI
EfiShellFindFiles (
  IN CONST CHAR16          *FilePattern,
  OUT EFI_SHELL_FILE_INFO  **FileList
  )
{
  EFI_STATUS                Status;
  CHAR16                    *PatternCopy;
  CHAR16                    *PatternCurrentLocation;
  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath;
  SHELL_FILE_HANDLE         RootFileHandle;
  CHAR16                    *MapName;
  UINTN                     Count;

  if (  (FilePattern      == NULL)
     || (FileList         == NULL)
     || (StrStr (FilePattern, L":") == NULL)
        )
  {
    return (EFI_INVALID_PARAMETER);
  }

  Status         = EFI_SUCCESS;
  RootDevicePath = NULL;
  RootFileHandle = NULL;
  MapName        = NULL;
  PatternCopy    = AllocateCopyPool (StrSize (FilePattern), FilePattern);
  if (PatternCopy == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  PatternCopy = PathCleanUpDirectories (PatternCopy);
  if (PatternCopy == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  Count = StrStr (PatternCopy, L":") - PatternCopy + 1;
  ASSERT (Count <= StrLen (PatternCopy));

  ASSERT (MapName == NULL);
  MapName = StrnCatGrow (&MapName, NULL, PatternCopy, Count);
  if (MapName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  } else {
    RootDevicePath = EfiShellGetDevicePathFromFilePath (PatternCopy);
    if (RootDevicePath == NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      Status = EfiShellOpenRoot (RootDevicePath, &RootFileHandle);
      if (!EFI_ERROR (Status)) {
        for ( PatternCurrentLocation = PatternCopy
              ; *PatternCurrentLocation != ':'
              ; PatternCurrentLocation++)
        {
        }

        PatternCurrentLocation++;
        Status = ShellSearchHandle (PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL, MapName);
        EfiShellClose (RootFileHandle);
      }

      FreePool (RootDevicePath);
    }
  }

  SHELL_FREE_NON_NULL (PatternCopy);
  SHELL_FREE_NON_NULL (MapName);

  return (Status);
}

/**
  Opens the files that match the path specified.

  This function opens all of the files specified by Path. Wildcards are processed
  according to the rules specified in UEFI Shell 2.0 spec section 3.7.1. Each
  matching file has an EFI_SHELL_FILE_INFO structure created in a linked list.

  @param Path                   A pointer to the path string.
  @param OpenMode               Specifies the mode used to open each file, EFI_FILE_MODE_READ or
                                EFI_FILE_MODE_WRITE.
  @param FileList               Points to the start of a list of files opened.

  @retval EFI_SUCCESS           Create the file list successfully.
  @return Others                Can't create the file list.
**/
EFI_STATUS
EFIAPI
EfiShellOpenFileList (
  IN CHAR16                   *Path,
  IN UINT64                   OpenMode,
  IN OUT EFI_SHELL_FILE_INFO  **FileList
  )
{
  EFI_STATUS           Status;
  EFI_SHELL_FILE_INFO  *ShellFileListItem;
  CHAR16               *Path2;
  UINTN                Path2Size;
  CONST CHAR16         *CurDir;
  BOOLEAN              Found;

  PathCleanUpDirectories (Path);

  Path2Size = 0;
  Path2     = NULL;

  if ((FileList == NULL) || (*FileList == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  if ((*Path == L'.') && (*(Path+1) == L'\\')) {
    Path += 2;
  }

  //
  // convert a local path to an absolute path
  //
  if (StrStr (Path, L":") == NULL) {
    CurDir = EfiShellGetCurDir (NULL);
    if (CurDir == NULL) {
      return EFI_NOT_FOUND;
    }

    ASSERT ((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
    StrnCatGrow (&Path2, &Path2Size, CurDir, 0);
    StrnCatGrow (&Path2, &Path2Size, L"\\", 0);
    if (*Path == L'\\') {
      Path++;
      while (PathRemoveLastItem (Path2)) {
      }
    }

    ASSERT ((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
    StrnCatGrow (&Path2, &Path2Size, Path, 0);
  } else {
    ASSERT (Path2 == NULL);
    StrnCatGrow (&Path2, NULL, Path, 0);
  }

  PathCleanUpDirectories (Path2);

  //
  // do the search
  //
  Status = EfiShellFindFiles (Path2, FileList);

  FreePool (Path2);

  if (EFI_ERROR (Status)) {
    return (Status);
  }

  Found = FALSE;
  //
  // We had no errors so open all the files (that are not already opened...)
  //
  for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
        ; !IsNull (&(*FileList)->Link, &ShellFileListItem->Link)
        ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
        )
  {
    if ((ShellFileListItem->Status == 0) && (ShellFileListItem->Handle == NULL)) {
      ShellFileListItem->Status = EfiShellOpenFileByName (ShellFileListItem->FullName, &ShellFileListItem->Handle, OpenMode);
      Found                     = TRUE;
    }
  }

  if (!Found) {
    return (EFI_NOT_FOUND);
  }

  return (EFI_SUCCESS);
}

/**
  Gets the environment variable and Attributes, or list of environment variables.  Can be
  used instead of GetEnv().

  This function returns the current value of the specified environment variable and
  the Attributes. If no variable name was specified, then all of the known
  variables will be returned.

  @param[in] Name               A pointer to the environment variable name. If Name is NULL,
                                then the function will return all of the defined shell
                                environment variables. In the case where multiple environment
                                variables are being returned, each variable will be terminated
                                by a NULL, and the list will be terminated by a double NULL.
  @param[out] Attributes        If not NULL, a pointer to the returned attributes bitmask for
                                the environment variable. In the case where Name is NULL, and
                                multiple environment variables are being returned, Attributes
                                is undefined.

  @retval NULL                  The environment variable doesn't exist.
  @return                       A non-NULL value points to the variable's value. The returned
                                pointer does not need to be freed by the caller.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetEnvEx (
  IN  CONST CHAR16  *Name,
  OUT       UINT32  *Attributes OPTIONAL
  )
{
  EFI_STATUS    Status;
  VOID          *Buffer;
  UINTN         Size;
  ENV_VAR_LIST  *Node;
  CHAR16        *CurrentWriteLocation;

  Size   = 0;
  Buffer = NULL;

  if (Name == NULL) {
    //
    // Build the semi-colon delimited list. (2 passes)
    //
    for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
          ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
          ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
          )
    {
      if (Node->Key == NULL) {
        ASSERT (FALSE);
        continue;
      }

      Size += StrSize (Node->Key);
    }

    Size += 2*sizeof (CHAR16);

    Buffer = AllocateZeroPool (Size);
    if (Buffer == NULL) {
      return (NULL);
    }

    CurrentWriteLocation = (CHAR16 *)Buffer;

    for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
          ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
          ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
          )
    {
      ASSERT (Node->Key != NULL);
      StrCpyS (
        CurrentWriteLocation,
        (Size)/sizeof (CHAR16) - (CurrentWriteLocation - ((CHAR16 *)Buffer)),
        Node->Key
        );
      CurrentWriteLocation += StrLen (CurrentWriteLocation) + 1;
    }
  } else {
    //
    // We are doing a specific environment variable
    //
    Status = ShellFindEnvVarInList (Name, (CHAR16 **)&Buffer, &Size, Attributes);

    if (EFI_ERROR (Status)) {
      //
      // get the size we need for this EnvVariable
      //
      Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (Name, Attributes, &Size, Buffer);
      if (Status == EFI_BUFFER_TOO_SMALL) {
        //
        // Allocate the space and recall the get function
        //
        Buffer = AllocateZeroPool (Size);
        if (Buffer == NULL) {
          return NULL;
        }

        Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (Name, Attributes, &Size, Buffer);
      }

      //
      // we didn't get it (might not exist)
      // free the memory if we allocated any and return NULL
      //
      if (EFI_ERROR (Status)) {
        if (Buffer != NULL) {
          FreePool (Buffer);
        }

        return (NULL);
      } else {
        //
        // If we did not find the environment variable in the gShellEnvVarList
        // but get it from UEFI variable storage successfully then we need update
        // the gShellEnvVarList.
        //
        ShellFreeEnvVarList ();
        Status = ShellInitEnvVarList ();
        ASSERT (Status == EFI_SUCCESS);
      }
    }
  }

  //
  // return the buffer
  //
  return (AddBufferToFreeList (Buffer));
}

/**
  Gets either a single or list of environment variables.

  If name is not NULL then this function returns the current value of the specified
  environment variable.

  If Name is NULL, then a list of all environment variable names is returned.  Each is a
  NULL terminated string with a double NULL terminating the list.

  @param Name                   A pointer to the environment variable name.  If
                                Name is NULL, then the function will return all
                                of the defined shell environment variables.  In
                                the case where multiple environment variables are
                                being returned, each variable will be terminated by
                                a NULL, and the list will be terminated by a double
                                NULL.

  @retval !=NULL                A pointer to the returned string.
                                The returned pointer does not need to be freed by the caller.

  @retval NULL                  The environment variable doesn't exist or there are
                                no environment variables.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetEnv (
  IN CONST CHAR16  *Name
  )
{
  return (EfiShellGetEnvEx (Name, NULL));
}

/**
  Internal variable setting function.  Allows for setting of the read only variables.

  @param Name                   Points to the NULL-terminated environment variable name.
  @param Value                  Points to the NULL-terminated environment variable value. If the value is an
                                empty string then the environment variable is deleted.
  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).

  @retval EFI_SUCCESS           The environment variable was successfully updated.
**/
EFI_STATUS
InternalEfiShellSetEnv (
  IN CONST CHAR16  *Name,
  IN CONST CHAR16  *Value,
  IN BOOLEAN       Volatile
  )
{
  EFI_STATUS  Status;

  if ((Value == NULL) || (StrLen (Value) == 0)) {
    Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Name);
    if (!EFI_ERROR (Status)) {
      ShellRemvoeEnvVarFromList (Name);
    }
  } else {
    SHELL_DELETE_ENVIRONMENT_VARIABLE (Name);
    Status = ShellAddEnvVarToList (
               Name,
               Value,
               StrSize (Value),
               EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE)
               );
    if (!EFI_ERROR (Status)) {
      Status = Volatile
             ? SHELL_SET_ENVIRONMENT_VARIABLE_V (Name, StrSize (Value) - sizeof (CHAR16), Value)
             : SHELL_SET_ENVIRONMENT_VARIABLE_NV (Name, StrSize (Value) - sizeof (CHAR16), Value);
      if (EFI_ERROR (Status)) {
        ShellRemvoeEnvVarFromList (Name);
      }
    }
  }

  return Status;
}

/**
  Sets the environment variable.

  This function changes the current value of the specified environment variable. If the
  environment variable exists and the Value is an empty string, then the environment
  variable is deleted. If the environment variable exists and the Value is not an empty
  string, then the value of the environment variable is changed. If the environment
  variable does not exist and the Value is an empty string, there is no action. If the
  environment variable does not exist and the Value is a non-empty string, then the
  environment variable is created and assigned the specified value.

  For a description of volatile and non-volatile environment variables, see UEFI Shell
  2.0 specification section 3.6.1.

  @param Name                   Points to the NULL-terminated environment variable name.
  @param Value                  Points to the NULL-terminated environment variable value. If the value is an
                                empty string then the environment variable is deleted.
  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).

  @retval EFI_SUCCESS           The environment variable was successfully updated.
**/
EFI_STATUS
EFIAPI
EfiShellSetEnv (
  IN CONST CHAR16  *Name,
  IN CONST CHAR16  *Value,
  IN BOOLEAN       Volatile
  )
{
  if ((Name == NULL) || (*Name == CHAR_NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Make sure we dont 'set' a predefined read only variable
  //
  if ((StrCmp (Name, L"cwd") == 0) ||
      (StrCmp (Name, L"lasterror") == 0) ||
      (StrCmp (Name, L"profiles") == 0) ||
      (StrCmp (Name, L"uefishellsupport") == 0) ||
      (StrCmp (Name, L"uefishellversion") == 0) ||
      (StrCmp (Name, L"uefiversion") == 0) ||
      (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest &&
       (StrCmp (Name, mNoNestingEnvVarName) == 0))
      )
  {
    return (EFI_INVALID_PARAMETER);
  }

  return (InternalEfiShellSetEnv (Name, Value, Volatile));
}

/**
  Returns the current directory on the specified device.

  If FileSystemMapping is NULL, it returns the current working directory. If the
  FileSystemMapping is not NULL, it returns the current directory associated with the
  FileSystemMapping. In both cases, the returned name includes the file system
  mapping (i.e. fs0:\current-dir).

  Note that the current directory string should exclude the tailing backslash character.

  @param FileSystemMapping      A pointer to the file system mapping. If NULL,
                                then the current working directory is returned.

  @retval !=NULL                The current directory.
  @retval NULL                  Current directory does not exist.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetCurDir (
  IN CONST CHAR16  *FileSystemMapping OPTIONAL
  )
{
  CHAR16          *PathToReturn;
  UINTN           Size;
  SHELL_MAP_LIST  *MapListItem;

  if (!IsListEmpty (&gShellMapList.Link)) {
    //
    // if parameter is NULL, use current
    //
    if (FileSystemMapping == NULL) {
      return (EfiShellGetEnv (L"cwd"));
    } else {
      Size         = 0;
      PathToReturn = NULL;
      MapListItem  = ShellCommandFindMapItem (FileSystemMapping);
      if (MapListItem != NULL) {
        ASSERT ((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
        PathToReturn = StrnCatGrow (&PathToReturn, &Size, MapListItem->MapName, 0);
        PathToReturn = StrnCatGrow (&PathToReturn, &Size, MapListItem->CurrentDirectoryPath, 0);
      }
    }

    return (AddBufferToFreeList (PathToReturn));
  } else {
    return (NULL);
  }
}

/**
  Changes the current directory on the specified device.

  If the FileSystem is NULL, and the directory Dir does not contain a file system's
  mapped name, this function changes the current working directory.

  If the FileSystem is NULL and the directory Dir contains a mapped name, then the
  current file system and the current directory on that file system are changed.

  If FileSystem is NULL, and Dir is not NULL, then this changes the current working file
  system.

  If FileSystem is not NULL and Dir is not NULL, then this function changes the current
  directory on the specified file system.

  If the current working directory or the current working file system is changed then the
  %cwd% environment variable will be updated

  Note that the current directory string should exclude the tailing backslash character.

  @param FileSystem             A pointer to the file system's mapped name. If NULL, then the current working
                                directory is changed.
  @param Dir                    Points to the NULL-terminated directory on the device specified by FileSystem.

  @retval EFI_SUCCESS           The operation was successful
  @retval EFI_NOT_FOUND         The file system could not be found
**/
EFI_STATUS
EFIAPI
EfiShellSetCurDir (
  IN CONST CHAR16  *FileSystem OPTIONAL,
  IN CONST CHAR16  *Dir
  )
{
  CHAR16          *MapName;
  SHELL_MAP_LIST  *MapListItem;
  UINTN           Size;
  EFI_STATUS      Status;
  CHAR16          *TempString;
  CHAR16          *DirectoryName;
  UINTN           TempLen;

  Size          = 0;
  MapName       = NULL;
  MapListItem   = NULL;
  TempString    = NULL;
  DirectoryName = NULL;

  if (((FileSystem == NULL) && (Dir == NULL)) || (Dir == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  if (IsListEmpty (&gShellMapList.Link)) {
    return (EFI_NOT_FOUND);
  }

  DirectoryName = StrnCatGrow (&DirectoryName, NULL, Dir, 0);
  if (DirectoryName == NULL) {
    ASSERT (DirectoryName != NULL);
    return (EFI_OUT_OF_RESOURCES);
  }

  PathCleanUpDirectories (DirectoryName);

  if (FileSystem == NULL) {
    //
    // determine the file system mapping to use
    //
    if (StrStr (DirectoryName, L":") != NULL) {
      ASSERT (MapName == NULL);
      MapName = StrnCatGrow (&MapName, NULL, DirectoryName, (StrStr (DirectoryName, L":")-DirectoryName+1));
    }

    //
    // find the file system mapping's entry in the list
    // or use current
    //
    if (MapName != NULL) {
      MapListItem = ShellCommandFindMapItem (MapName);

      //
      // make that the current file system mapping
      //
      if (MapListItem != NULL) {
        gShellCurMapping = MapListItem;
      }
    } else {
      MapListItem = gShellCurMapping;
    }

    if (MapListItem == NULL) {
      FreePool (DirectoryName);
      SHELL_FREE_NON_NULL (MapName);
      return (EFI_NOT_FOUND);
    }

    //
    // now update the MapListItem's current directory
    //
    if ((MapListItem->CurrentDirectoryPath != NULL) && (DirectoryName[StrLen (DirectoryName) - 1] != L':')) {
      FreePool (MapListItem->CurrentDirectoryPath);
      MapListItem->CurrentDirectoryPath = NULL;
    }

    if (MapName != NULL) {
      TempLen = StrLen (MapName);
      if (TempLen != StrLen (DirectoryName)) {
        ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
        MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName+StrLen (MapName), 0);
      }

      FreePool (MapName);
    } else {
      ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
      MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
    }

    if (((MapListItem->CurrentDirectoryPath != NULL) && (MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] == L'\\')) || (MapListItem->CurrentDirectoryPath == NULL)) {
      ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
      if (MapListItem->CurrentDirectoryPath != NULL) {
        MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
      }
    }
  } else {
    //
    // cant have a mapping in the directory...
    //
    if (StrStr (DirectoryName, L":") != NULL) {
      FreePool (DirectoryName);
      return (EFI_INVALID_PARAMETER);
    }

    //
    // FileSystem != NULL
    //
    MapListItem = ShellCommandFindMapItem (FileSystem);
    if (MapListItem == NULL) {
      FreePool (DirectoryName);
      return (EFI_INVALID_PARAMETER);
    }

    //    gShellCurMapping = MapListItem;
    if (DirectoryName != NULL) {
      //
      // change current dir on that file system
      //

      if (MapListItem->CurrentDirectoryPath != NULL) {
        FreePool (MapListItem->CurrentDirectoryPath);
        DEBUG_CODE (
          MapListItem->CurrentDirectoryPath = NULL;
          );
      }

      //      ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
      //      MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, FileSystem, 0);
      ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
      MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
      ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
      MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
      if ((MapListItem->CurrentDirectoryPath != NULL) && (MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] == L'\\')) {
        ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
        MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
      }
    }
  }

  FreePool (DirectoryName);
  //
  // if updated the current directory then update the environment variable
  //
  if (MapListItem == gShellCurMapping) {
    Size = 0;
    ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
    StrnCatGrow (&TempString, &Size, MapListItem->MapName, 0);
    ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
    StrnCatGrow (&TempString, &Size, MapListItem->CurrentDirectoryPath, 0);
    Status =  InternalEfiShellSetEnv (L"cwd", TempString, TRUE);
    FreePool (TempString);
    return (Status);
  }

  return (EFI_SUCCESS);
}

/**
  Return help information about a specific command.

  This function returns the help information for the specified command. The help text
  can be internal to the shell or can be from a UEFI Shell manual page.

  If Sections is specified, then each section name listed will be compared in a casesensitive
  manner, to the section names described in Appendix B. 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 Command                Points to the NULL-terminated UEFI Shell command name.
  @param Sections               Points to the NULL-terminated comma-delimited
                                section names to return. If NULL, then all
                                sections will be returned.
  @param HelpText               On return, points to a callee-allocated buffer
                                containing all specified help text.

  @retval EFI_SUCCESS           The help text was returned.
  @retval EFI_OUT_OF_RESOURCES  The necessary buffer could not be allocated to hold the
                                returned help text.
  @retval EFI_INVALID_PARAMETER HelpText is NULL
  @retval EFI_NOT_FOUND         There is no help text available for Command.
**/
EFI_STATUS
EFIAPI
EfiShellGetHelpText (
  IN CONST CHAR16  *Command,
  IN CONST CHAR16  *Sections OPTIONAL,
  OUT CHAR16       **HelpText
  )
{
  CONST CHAR16  *ManFileName;
  CHAR16        *FixCommand;
  EFI_STATUS    Status;

  ASSERT (HelpText != NULL);
  FixCommand = NULL;

  ManFileName = ShellCommandGetManFileNameHandler (Command);

  if (ManFileName != NULL) {
    return (ProcessManFile (ManFileName, Command, Sections, NULL, HelpText));
  } else {
    if (  (StrLen (Command) > 4)
       && ((Command[StrLen (Command)-1] == L'i') || (Command[StrLen (Command)-1] == L'I'))
       && ((Command[StrLen (Command)-2] == L'f') || (Command[StrLen (Command)-2] == L'F'))
       && ((Command[StrLen (Command)-3] == L'e') || (Command[StrLen (Command)-3] == L'E'))
       && (Command[StrLen (Command)-4] == L'.')
          )
    {
      FixCommand = AllocateZeroPool (StrSize (Command) - 4 * sizeof (CHAR16));
      if (FixCommand == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      StrnCpyS (
        FixCommand,
        (StrSize (Command) - 4 * sizeof (CHAR16))/sizeof (CHAR16),
        Command,
        StrLen (Command)-4
        );
      Status = ProcessManFile (FixCommand, FixCommand, Sections, NULL, HelpText);
      FreePool (FixCommand);
      return Status;
    } else {
      return (ProcessManFile (Command, Command, Sections, NULL, HelpText));
    }
  }
}

/**
  Gets the enable status of the page break output mode.

  User can use this function to determine current page break mode.

  @retval TRUE                  The page break output mode is enabled.
  @retval FALSE                 The page break output mode is disabled.
**/
BOOLEAN
EFIAPI
EfiShellGetPageBreak (
  VOID
  )
{
  return (ShellInfoObject.PageBreakEnabled);
}

/**
  Judges whether the active shell is the root shell.

  This function makes the user to know that whether the active Shell is the root shell.

  @retval TRUE                  The active Shell is the root Shell.
  @retval FALSE                 The active Shell is NOT the root Shell.
**/
BOOLEAN
EFIAPI
EfiShellIsRootShell (
  VOID
  )
{
  return (ShellInfoObject.RootShellInstance);
}

/**
  function to return a semi-colon delimited list of all alias' in the current shell

  up to caller to free the memory.

  @retval NULL    No alias' were found
  @retval NULL    An error occurred getting alias'
  @return !NULL   a list of all alias'
**/
CHAR16 *
InternalEfiShellGetListAlias (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_GUID    Guid;
  CHAR16      *VariableName;
  UINTN       NameSize;
  UINTN       NameBufferSize;
  CHAR16      *RetVal;
  UINTN       RetSize;

  NameBufferSize = INIT_NAME_BUFFER_SIZE;
  VariableName   = AllocateZeroPool (NameBufferSize);
  RetSize        = 0;
  RetVal         = NULL;

  if (VariableName == NULL) {
    return (NULL);
  }

  VariableName[0] = CHAR_NULL;

  while (TRUE) {
    NameSize = NameBufferSize;
    Status   = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
    if (Status == EFI_NOT_FOUND) {
      break;
    } else if (Status == EFI_BUFFER_TOO_SMALL) {
      NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
      SHELL_FREE_NON_NULL (VariableName);
      VariableName = AllocateZeroPool (NameBufferSize);
      if (VariableName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        SHELL_FREE_NON_NULL (RetVal);
        RetVal = NULL;
        break;
      }

      NameSize = NameBufferSize;
      Status   = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
    }

    if (EFI_ERROR (Status)) {
      SHELL_FREE_NON_NULL (RetVal);
      RetVal = NULL;
      break;
    }

    if (CompareGuid (&Guid, &gShellAliasGuid)) {
      ASSERT ((RetVal == NULL && RetSize == 0) || (RetVal != NULL));
      RetVal = StrnCatGrow (&RetVal, &RetSize, VariableName, 0);
      RetVal = StrnCatGrow (&RetVal, &RetSize, L";", 0);
    } // compare guid
  } // while

  SHELL_FREE_NON_NULL (VariableName);

  return (RetVal);
}

/**
  Convert a null-terminated unicode string, in-place, to all lowercase.
  Then return it.

  @param  Str    The null-terminated string to be converted to all lowercase.

  @return        The null-terminated string converted into all lowercase.
**/
CHAR16 *
ToLower (
  CHAR16  *Str
  )
{
  UINTN  Index;

  for (Index = 0; Str[Index] != L'\0'; Index++) {
    if ((Str[Index] >= L'A') && (Str[Index] <= L'Z')) {
      Str[Index] -= (CHAR16)(L'A' - L'a');
    }
  }

  return Str;
}

/**
  This function returns the command associated with a alias or a list of all
  alias'.

  @param[in] Alias              Points to the NULL-terminated shell alias.
                                If this parameter is NULL, then all
                                aliases will be returned in ReturnedData.
  @param[out] Volatile          upon return of a single command if TRUE indicates
                                this is stored in a volatile fashion.  FALSE otherwise.

  @return                        If Alias is not NULL, it will return a pointer to
                                the NULL-terminated command for that alias.
                                If Alias is NULL, ReturnedData points to a ';'
                                delimited list of alias (e.g.
                                ReturnedData = "dir;del;copy;mfp") that is NULL-terminated.
  @retval NULL                  an error occurred
  @retval NULL                  Alias was not a valid Alias
**/
CONST CHAR16 *
EFIAPI
EfiShellGetAlias (
  IN  CONST CHAR16  *Alias,
  OUT BOOLEAN       *Volatile OPTIONAL
  )
{
  CHAR16      *RetVal;
  UINTN       RetSize;
  UINT32      Attribs;
  EFI_STATUS  Status;
  CHAR16      *AliasLower;
  CHAR16      *AliasVal;

  // Convert to lowercase to make aliases case-insensitive
  if (Alias != NULL) {
    AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
    if (AliasLower == NULL) {
      return NULL;
    }

    ToLower (AliasLower);

    if (Volatile == NULL) {
      GetVariable2 (AliasLower, &gShellAliasGuid, (VOID **)&AliasVal, NULL);
      FreePool (AliasLower);
      return (AddBufferToFreeList (AliasVal));
    }

    RetSize = 0;
    RetVal  = NULL;
    Status  = gRT->GetVariable (AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      RetVal = AllocateZeroPool (RetSize);
      if (RetVal == NULL) {
        FreePool (AliasLower);
        return NULL;
      }

      Status = gRT->GetVariable (AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
    }

    if (EFI_ERROR (Status)) {
      if (RetVal != NULL) {
        FreePool (RetVal);
      }

      FreePool (AliasLower);
      return (NULL);
    }

    if ((EFI_VARIABLE_NON_VOLATILE & Attribs) == EFI_VARIABLE_NON_VOLATILE) {
      *Volatile = FALSE;
    } else {
      *Volatile = TRUE;
    }

    FreePool (AliasLower);
    return (AddBufferToFreeList (RetVal));
  }

  return (AddBufferToFreeList (InternalEfiShellGetListAlias ()));
}

/**
  Changes a shell command alias.

  This function creates an alias for a shell command or if Alias is NULL it will delete an existing alias.

  this function does not check for built in alias'.

  @param[in] Command            Points to the NULL-terminated shell command or existing alias.
  @param[in] Alias              Points to the NULL-terminated alias for the shell command. If this is NULL, and
                                Command refers to an alias, that alias will be deleted.
  @param[in] Volatile           if TRUE the Alias being set will be stored in a volatile fashion.  if FALSE the
                                Alias being set will be stored in a non-volatile fashion.

  @retval EFI_SUCCESS           Alias created or deleted successfully.
  @retval EFI_NOT_FOUND         the Alias intended to be deleted was not found
**/
EFI_STATUS
InternalSetAlias (
  IN CONST CHAR16  *Command,
  IN CONST CHAR16  *Alias,
  IN BOOLEAN       Volatile
  )
{
  EFI_STATUS  Status;
  CHAR16      *AliasLower;
  BOOLEAN     DeleteAlias;

  DeleteAlias = FALSE;
  if (Alias == NULL) {
    //
    // We must be trying to remove one if Alias is NULL
    // remove an alias (but passed in COMMAND parameter)
    //
    Alias       = Command;
    DeleteAlias = TRUE;
  }

  ASSERT (Alias != NULL);

  //
  // Convert to lowercase to make aliases case-insensitive
  //
  AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
  if (AliasLower == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  ToLower (AliasLower);

  if (DeleteAlias) {
    Status = gRT->SetVariable (AliasLower, &gShellAliasGuid, 0, 0, NULL);
  } else {
    Status = gRT->SetVariable (
                    AliasLower,
                    &gShellAliasGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE),
                    StrSize (Command),
                    (VOID *)Command
                    );
  }

  FreePool (AliasLower);

  return Status;
}

/**
  Changes a shell command alias.

  This function creates an alias for a shell command or if Alias is NULL it will delete an existing alias.


  @param[in] Command            Points to the NULL-terminated shell command or existing alias.
  @param[in] Alias              Points to the NULL-terminated alias for the shell command. If this is NULL, and
                                Command refers to an alias, that alias will be deleted.
  @param[in] Replace            If TRUE and the alias already exists, then the existing alias will be replaced. If
                                FALSE and the alias already exists, then the existing alias is unchanged and
                                EFI_ACCESS_DENIED is returned.
  @param[in] Volatile           if TRUE the Alias being set will be stored in a volatile fashion.  if FALSE the
                                Alias being set will be stored in a non-volatile fashion.

  @retval EFI_SUCCESS           Alias created or deleted successfully.
  @retval EFI_NOT_FOUND         the Alias intended to be deleted was not found
  @retval EFI_ACCESS_DENIED     The alias is a built-in alias or already existed and Replace was set to
                                FALSE.
  @retval EFI_INVALID_PARAMETER Command is null or the empty string.
**/
EFI_STATUS
EFIAPI
EfiShellSetAlias (
  IN CONST CHAR16  *Command,
  IN CONST CHAR16  *Alias,
  IN BOOLEAN       Replace,
  IN BOOLEAN       Volatile
  )
{
  if (ShellCommandIsOnAliasList ((Alias == NULL) ? Command : Alias)) {
    //
    // cant set over a built in alias
    //
    return (EFI_ACCESS_DENIED);
  } else if ((Command == NULL) || (*Command == CHAR_NULL) || (StrLen (Command) == 0)) {
    //
    // Command is null or empty
    //
    return (EFI_INVALID_PARAMETER);
  } else if ((EfiShellGetAlias (Command, NULL) != NULL) && !Replace) {
    //
    // Alias already exists, Replace not set
    //
    return (EFI_ACCESS_DENIED);
  } else {
    return (InternalSetAlias (Command, Alias, Volatile));
  }
}

// Pure FILE_HANDLE operations are passed to FileHandleLib
// these functions are indicated by the *
EFI_SHELL_PROTOCOL  mShellProtocol = {
  EfiShellExecute,
  EfiShellGetEnv,
  EfiShellSetEnv,
  EfiShellGetAlias,
  EfiShellSetAlias,
  EfiShellGetHelpText,
  EfiShellGetDevicePathFromMap,
  EfiShellGetMapFromDevicePath,
  EfiShellGetDevicePathFromFilePath,
  EfiShellGetFilePathFromDevicePath,
  EfiShellSetMap,
  EfiShellGetCurDir,
  EfiShellSetCurDir,
  EfiShellOpenFileList,
  EfiShellFreeFileList,
  EfiShellRemoveDupInFileList,
  EfiShellBatchIsActive,
  EfiShellIsRootShell,
  EfiShellEnablePageBreak,
  EfiShellDisablePageBreak,
  EfiShellGetPageBreak,
  EfiShellGetDeviceName,
  (EFI_SHELL_GET_FILE_INFO)FileHandleGetInfo,         // *
  (EFI_SHELL_SET_FILE_INFO)FileHandleSetInfo,         // *
  EfiShellOpenFileByName,
  EfiShellClose,
  EfiShellCreateFile,
  (EFI_SHELL_READ_FILE)FileHandleRead,                // *
  (EFI_SHELL_WRITE_FILE)FileHandleWrite,              // *
  (EFI_SHELL_DELETE_FILE)FileHandleDelete,            // *
  EfiShellDeleteFileByName,
  (EFI_SHELL_GET_FILE_POSITION)FileHandleGetPosition, // *
  (EFI_SHELL_SET_FILE_POSITION)FileHandleSetPosition, // *
  (EFI_SHELL_FLUSH_FILE)FileHandleFlush,              // *
  EfiShellFindFiles,
  EfiShellFindFilesInDir,
  (EFI_SHELL_GET_FILE_SIZE)FileHandleGetSize,         // *
  EfiShellOpenRoot,
  EfiShellOpenRootByHandle,
  NULL,
  SHELL_MAJOR_VERSION,
  SHELL_MINOR_VERSION,

  // New for UEFI Shell 2.1
  EfiShellRegisterGuidName,
  EfiShellGetGuidName,
  EfiShellGetGuidFromName,
  EfiShellGetEnvEx
};

/**
  Function to create and install on the current handle.

  Will overwrite any existing ShellProtocols in the system to be sure that
  the current shell is in control.

  This must be removed via calling CleanUpShellProtocol().

  @param[in, out] NewShell   The pointer to the pointer to the structure
  to install.

  @retval EFI_SUCCESS     The operation was successful.
  @return                 An error from LocateHandle, CreateEvent, or other core function.
**/
EFI_STATUS
CreatePopulateInstallShellProtocol (
  IN OUT EFI_SHELL_PROTOCOL  **NewShell
  )
{
  EFI_STATUS                  Status;
  UINTN                       BufferSize;
  EFI_HANDLE                  *Buffer;
  UINTN                       HandleCounter;
  SHELL_PROTOCOL_HANDLE_LIST  *OldProtocolNode;
  EFI_SHELL_PROTOCOL          *OldShell;

  if (NewShell == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  BufferSize      = 0;
  Buffer          = NULL;
  OldProtocolNode = NULL;
  InitializeListHead (&ShellInfoObject.OldShellList.Link);

  //
  // Initialize EfiShellProtocol object...
  //
  Status = gBS->CreateEvent (
                  0,
                  0,
                  NULL,
                  NULL,
                  &mShellProtocol.ExecutionBreak
                  );
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // Get the size of the buffer we need.
  //
  Status = gBS->LocateHandle (
                  ByProtocol,
                  &gEfiShellProtocolGuid,
                  NULL,
                  &BufferSize,
                  Buffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate and recall with buffer of correct size
    //
    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiShellProtocolGuid,
                    NULL,
                    &BufferSize,
                    Buffer
                    );
    if (EFI_ERROR (Status)) {
      FreePool (Buffer);
      return (Status);
    }

    //
    // now overwrite each of them, but save the info to restore when we end.
    //
    for (HandleCounter = 0; HandleCounter < (BufferSize/sizeof (EFI_HANDLE)); HandleCounter++) {
      Status = gBS->OpenProtocol (
                      Buffer[HandleCounter],
                      &gEfiShellProtocolGuid,
                      (VOID **)&OldShell,
                      gImageHandle,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (!EFI_ERROR (Status)) {
        OldProtocolNode = AllocateZeroPool (sizeof (SHELL_PROTOCOL_HANDLE_LIST));
        if (OldProtocolNode == NULL) {
          if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {
            CleanUpShellProtocol (&mShellProtocol);
          }

          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        //
        // reinstall over the old one...
        //
        OldProtocolNode->Handle    = Buffer[HandleCounter];
        OldProtocolNode->Interface = OldShell;
        Status                     = gBS->ReinstallProtocolInterface (
                                            OldProtocolNode->Handle,
                                            &gEfiShellProtocolGuid,
                                            OldProtocolNode->Interface,
                                            (VOID *)(&mShellProtocol)
                                            );
        if (!EFI_ERROR (Status)) {
          //
          // we reinstalled successfully.  log this so we can reverse it later.
          //

          //
          // add to the list for subsequent...
          //
          InsertTailList (&ShellInfoObject.OldShellList.Link, &OldProtocolNode->Link);
        }
      }
    }

    FreePool (Buffer);
  } else if (Status == EFI_NOT_FOUND) {
    ASSERT (IsListEmpty (&ShellInfoObject.OldShellList.Link));
    //
    // no one else published yet.  just publish it ourselves.
    //
    Status = gBS->InstallProtocolInterface (
                    &gImageHandle,
                    &gEfiShellProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    (VOID *)(&mShellProtocol)
                    );
  }

  if (!EFI_ERROR (Status)) {
    *NewShell = &mShellProtocol;
  }

  return (Status);
}

/**
  Opposite of CreatePopulateInstallShellProtocol.

  Free all memory and restore the system to the state it was in before calling
  CreatePopulateInstallShellProtocol.

  @param[in, out] NewShell   The pointer to the new shell protocol structure.

  @retval EFI_SUCCESS       The operation was successful.
**/
EFI_STATUS
CleanUpShellProtocol (
  IN OUT EFI_SHELL_PROTOCOL  *NewShell
  )
{
  SHELL_PROTOCOL_HANDLE_LIST  *Node2;

  //
  // if we need to restore old protocols...
  //
  if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {
    for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode (&ShellInfoObject.OldShellList.Link)
         ; !IsListEmpty (&ShellInfoObject.OldShellList.Link)
         ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode (&ShellInfoObject.OldShellList.Link)
         )
    {
      RemoveEntryList (&Node2->Link);
      gBS->ReinstallProtocolInterface (Node2->Handle, &gEfiShellProtocolGuid, NewShell, Node2->Interface);
      FreePool (Node2);
    }
  } else {
    //
    // no need to restore
    //
    gBS->UninstallProtocolInterface (gImageHandle, &gEfiShellProtocolGuid, NewShell);
  }

  return EFI_SUCCESS;
}

/**
  Cleanup the shell environment.

  @param[in, out] NewShell   The pointer to the new shell protocol structure.

  @retval EFI_SUCCESS       The operation was successful.
**/
EFI_STATUS
CleanUpShellEnvironment (
  IN OUT EFI_SHELL_PROTOCOL  *NewShell
  )
{
  EFI_STATUS                         Status;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *SimpleEx;

  CleanUpShellProtocol (NewShell);

  Status                   = gBS->CloseEvent (NewShell->ExecutionBreak);
  NewShell->ExecutionBreak = NULL;

  Status = gBS->OpenProtocol (
                  gST->ConsoleInHandle,
                  &gEfiSimpleTextInputExProtocolGuid,
                  (VOID **)&SimpleEx,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle1);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle2);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle3);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle4);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle1);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle2);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle3);
    Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle4);
  }

  return (Status);
}

/**
  Notification function for keystrokes.

  @param[in] KeyData    The key that was pressed.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
EFIAPI
NotificationFunction (
  IN EFI_KEY_DATA  *KeyData
  )
{
  if (((KeyData->Key.UnicodeChar == L'c') &&
       ((KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED)) || (KeyData->KeyState.KeyShiftState  == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED)))) ||
      (KeyData->Key.UnicodeChar == 3)
      )
  {
    if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {
      return (EFI_UNSUPPORTED);
    }

    return (gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak));
  } else if ((KeyData->Key.UnicodeChar == L's') &&
             ((KeyData->KeyState.KeyShiftState  == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED)) || (KeyData->KeyState.KeyShiftState  == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED)))
             )
  {
    ShellInfoObject.HaltOutput = TRUE;
  }

  return (EFI_SUCCESS);
}

/**
  Function to start monitoring for CTRL-C using SimpleTextInputEx.  This
  feature's enabled state was not known when the shell initially launched.

  @retval EFI_SUCCESS           The feature is enabled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available.
**/
EFI_STATUS
InernalEfiShellStartMonitor (
  VOID
  )
{
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *SimpleEx;
  EFI_KEY_DATA                       KeyData;
  EFI_STATUS                         Status;

  Status = gBS->OpenProtocol (
                  gST->ConsoleInHandle,
                  &gEfiSimpleTextInputExProtocolGuid,
                  (VOID **)&SimpleEx,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_SHELL_NO_IN_EX),
      ShellInfoObject.HiiHandle
      );
    return (EFI_SUCCESS);
  }

  if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {
    return (EFI_UNSUPPORTED);
  }

  KeyData.KeyState.KeyToggleState = 0;
  KeyData.Key.ScanCode            = 0;
  KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
  KeyData.Key.UnicodeChar         = L'c';

  Status = SimpleEx->RegisterKeyNotify (
                       SimpleEx,
                       &KeyData,
                       NotificationFunction,
                       &ShellInfoObject.CtrlCNotifyHandle1
                       );

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlCNotifyHandle2
                         );
  }

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
  KeyData.Key.UnicodeChar        = 3;
  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlCNotifyHandle3
                         );
  }

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlCNotifyHandle4
                         );
  }

  return (Status);
}
