/** @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 - 2017, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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);
}

/**
  Internal worker debug helper function to print out maps as they are added.

  @param[in] Mapping        string mapping that has been added
  @param[in] DevicePath     pointer to device path that has been mapped.

  @retval EFI_SUCCESS   the operation was successful.
  @return other         an error ocurred

  @sa LocateHandle
  @sa OpenProtocol
**/
EFI_STATUS
InternalShellProtocolDebugPrintMessage (
  IN CONST CHAR16                   *Mapping,
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
  )
{
  EFI_STATUS                        Status;
  CHAR16                            *Temp;

  Status = EFI_SUCCESS;
  DEBUG_CODE_BEGIN();

  if (Mapping != NULL) {
    DEBUG((EFI_D_INFO, "Added new map item:\"%S\"\r\n", Mapping));
  }
  Temp = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
  DEBUG((EFI_D_INFO, "DevicePath: %S\r\n", Temp));
  FreePool(Temp);

  DEBUG_CODE_END();
  return (Status);
}

/**
  This function creates a mapping for a device path.

  If both DeviecPath 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 didnt 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 seperated 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 cotained non-path elements
  @retval other                   an error ocurred.
**/
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 begining 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 attrbiutes.  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 devide, 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);
//  DEBUG_CODE(InternalShellProtocolDebugPrintMessage (NULL, DevicePath););
  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);
    ASSERT_EFI_ERROR(Status);
    //
    // 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_SHELL_FILE_INFO *ShellFileListItem;
  EFI_SHELL_FILE_INFO *ShellFileListItem2;
  EFI_SHELL_FILE_INFO *TempNode;

  if (FileList == NULL || *FileList == NULL) {
    return (EFI_INVALID_PARAMETER);
  }
  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 ocurred
  @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 ocurred.
  @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 didnt 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);
}

/**
  Updates a file name to be preceeded by the mapped drive name

  @param[in] BasePath      the Mapped drive name to prepend
  @param[in, out] Path     pointer to pointer to the file name to update.

  @retval EFI_SUCCESS
  @retval EFI_OUT_OF_RESOURCES
**/
EFI_STATUS
UpdateFileName(
  IN CONST CHAR16 *BasePath,
  IN OUT CHAR16   **Path
  )
{
  CHAR16              *Path2;
  UINTN               Path2Size;

  Path2Size = 0;
  Path2 = NULL;

  ASSERT(Path      != NULL);
  ASSERT(*Path     != NULL);
  ASSERT(BasePath  != NULL);

  //
  // convert a local path to an absolute path
  //
  if (StrStr(*Path, L":") == NULL) {
    ASSERT((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
    StrnCatGrow(&Path2, &Path2Size, BasePath, 0);
    if (Path2 == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }
    ASSERT((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
    StrnCatGrow(&Path2, &Path2Size, (*Path)[0] == L'\\'?(*Path) + 1 :*Path, 0);
    if (Path2 == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }
  }

  FreePool(*Path);
  (*Path) = Path2;

  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 didnt 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 (gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"cwd") == 0
    ||gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"Lasterror") == 0
    ||gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"profiles") == 0
    ||gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"uefishellsupport") == 0
    ||gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"uefishellversion") == 0
    ||gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        L"uefiversion") == 0
    ||(!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest &&
      gUnicodeCollation->StriColl(
        gUnicodeCollation,
        (CHAR16*)Name,
        (CHAR16*)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 sucessful
  @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 delimeted 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 ocurred 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 ocurred
  @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 sucessfully.  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 mnemory 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);
}

