/** @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 - 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)+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
**/
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);
  *FileHandle = ConvertEfiFileProtocolToShellHandle(RealFileHandle, EfiShellGetMapFromDevicePath(&DevPath));
  return (Status);
}

/**
  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(
)
{
  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) {
        gShellCurDir = MapListItem;
      }
    } else {
      MapListItem = gShellCurDir;
    }

    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);
    }
//    gShellCurDir = 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 == gShellCurDir) {
    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(
  )
{
  
  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;

  // Convert to lowercase to make aliases case-insensitive
  if (Alias != NULL) {
    AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
    if (AliasLower == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    ToLower (AliasLower);
  } else {
    AliasLower = NULL;
  }

  //
  // We must be trying to remove one if Alias is NULL
  //
  if (Alias == NULL) {
    //
    // remove an alias (but passed in COMMAND parameter)
    //
    Status = (gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL));
  } else {
    //
    // Add and replace are the same
    //

    // We dont check the error return on purpose since the variable may not exist.
    gRT->SetVariable((CHAR16*)Command, &gShellAliasGuid, 0, 0, NULL);

    Status = (gRT->SetVariable((CHAR16*)Alias, &gShellAliasGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS|(Volatile?0:EFI_VARIABLE_NON_VOLATILE), StrSize(Command), (VOID*)Command));
  }

  if (Alias != NULL) {
    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);
}

