/** @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);
    }
    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)) {
          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) {
          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);
      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.
    //
    if (DeviceNameToReturn == NULL){
      PARSE_HANDLE_DATABASE_PARENTS(DeviceHandle, &ParentControllerCount, &ParentControllerBuffer);
      for (LoopVar = 0 ; LoopVar < ParentControllerCount ; LoopVar++) {
        PARSE_HANDLE_DATABASE_UEFI_DRIVERS(ParentControllerBuffer[LoopVar], &ParentDriverCount, &ParentDriverBuffer);
        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);
          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);

    ///@todo initialize and install ShellInterface protocol on the new image for compatibility if - PcdGetBool(PcdShellSupportOldProtocols)

    //
    // 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);
  }

  if (NestingEnabled()) {
    DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);

    DEBUG_CODE_BEGIN();
    Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);
    FreePool(Temp);
    Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);
    FreePool(Temp);
    Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
    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;

  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);
      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);

  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);
    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)
     ){
      ASSERT(Node->Key != NULL);
      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);
        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);
  ASSERT(DirectoryName != NULL);

  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);
      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 (PcdGetBool(PcdShellSupportOldProtocols)){
    ///@todo support ShellEnvironment2
    ///@todo do we need to support ShellEnvironment (not ShellEnvironment2) also?
  }

  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);
}

