/** @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) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        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 (  (StrCmp (ShellInfoNode->FileName, L".") != 0)
               && (StrCmp (ShellInfoNode->FileName, L"..") != 0)
                  )
            {
              //
              //
              //
              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)) {
    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      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);
}
