/** @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>
  Copyright (c) 2009 - 2014, 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"

/**
  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
EFIAPI
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
EFIAPI
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
EFIAPI
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);
            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)
         ){
        //
        // all the rest should be file path nodes
        //
        if ((DevicePathType(&FilePath->Header) != MEDIA_DEVICE_PATH) ||
            (DevicePathSubType(&FilePath->Header) != MEDIA_FILEPATH_DP)) {
          FreePool(PathForReturn);
          PathForReturn = NULL;
          ASSERT(FALSE);
        } else {
          //
          // append the path part onto the filepath.
          //
          ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));

          AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath);
          ASSERT (AlignedNode != 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) - sizeof(CHAR16);
    NewPath = AllocateZeroPool(Size);
    if (NewPath == NULL) {
      return (NULL);
    }
    StrnCpy(NewPath, Cwd, Size/sizeof(CHAR16)-1);
    if (*Path == L'\\') {
      Path++;
      while (PathRemoveLastItem(NewPath)) ;
    }
    StrnCat(NewPath, Path, Size/sizeof(CHAR16) - 1 - StrLen(NewPath));
    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
EFIAPI
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;

  //
  // Is this for an environment variable
  // do we start with >v
  //
  if (StrStr(FileName, L">v") == FileName) {
    if (!IsVolatileEnv(FileName+2)) {
      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;

  *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 file
  //
  if (StrCmp(FileName, L"NUL") == 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) {
    if (!IsVolatileEnv(FileName+2) &&
        ((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
  //
  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
EFIAPI
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);

  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);
    }
    return (Status);
  }
  Status = gBS->OpenProtocol(
    NewHandle,
    &gEfiLoadedImageProtocolGuid,
    (VOID**)&LoadedImage,
    gImageHandle,
    NULL,
    EFI_OPEN_PROTOCOL_GET_PROTOCOL);

  if (!EFI_ERROR(Status)) {
    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, 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);
}
/**
  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 command.

  @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);
  }

  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);
  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
EFIAPI
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*
EFIAPI
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 *
EFIAPI
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)
     ){
    //
    // 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 (ShellFileList == NULL) {
      ShellFileList = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
      ASSERT(ShellFileList != NULL);
      InitializeListHead(&ShellFileList->Link);
    }
    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(NewGuid, Guid);
  }

  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
EFIAPI
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
EFIAPI
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));
  ASSERT(CurrentFilePattern != NULL);
  StrnCpy(CurrentFilePattern, 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);
            Size += StrSize(MapName) + sizeof(CHAR16);
            NewFullName = AllocateZeroPool(Size);
            if (NewFullName == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              StrnCpy(NewFullName, MapName, Size/sizeof(CHAR16)-1);
              StrnCat(NewFullName, ShellInfoNode->FullName+1, (Size/sizeof(CHAR16))-StrLen(NewFullName)-1);
              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);
            }
          } else if (!EFI_ERROR(Status)) {
            //
            // should be a file
            //

            //
            // copy the information we need into a new Node
            //
            NewShellNode = InternalDuplicateShellFileInfo(ShellInfoNode, FALSE);
            ASSERT(NewShellNode != NULL);
            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);
      }
    }
  }

  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;
  Count += 2;

  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);
      }
      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);
    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;
  LIST_ENTRY  List;
  ENV_VAR_LIST *Node;
  CHAR16      *CurrentWriteLocation;

  Size = 0;
  Buffer = NULL;

  if (Name == NULL) {
    //
    // Get all our environment variables
    //
    InitializeListHead(&List);
    Status = GetEnvironmentVariableList(&List);
    if (EFI_ERROR(Status)){
      return (NULL);
    }

    //
    // Build the semi-colon delimited list. (2 passes)
    //
    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
      ; !IsNull(&List, &Node->Link)
      ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     ){
      ASSERT(Node->Key != NULL);
      Size += StrSize(Node->Key);
    }

    Size += 2*sizeof(CHAR16);

    Buffer = AllocateZeroPool(Size);
    if (Buffer == NULL) {
      if (!IsListEmpty (&List)) {
        FreeEnvironmentVariableList(&List);
      }
      return (NULL);
    }
    CurrentWriteLocation = (CHAR16*)Buffer;

    for ( Node = (ENV_VAR_LIST*)GetFirstNode(&List)
      ; !IsNull(&List, &Node->Link)
      ; Node = (ENV_VAR_LIST*)GetNextNode(&List, &Node->Link)
     ){
      ASSERT(Node->Key != NULL);
      StrnCpy(CurrentWriteLocation, Node->Key,  (Size)/sizeof(CHAR16) - (CurrentWriteLocation - ((CHAR16*)Buffer)) - 1);
      CurrentWriteLocation += StrLen(CurrentWriteLocation) + 1;
    }

    //
    // Free the list...
    //
    if (!IsListEmpty (&List)) {
      FreeEnvironmentVariableList(&List);
    }
  } else {
    //
    // We are doing a specific environment variable
    //

    //
    // 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);
    }
  }

  //
  // 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
EFIAPI
InternalEfiShellSetEnv(
  IN CONST CHAR16 *Name,
  IN CONST CHAR16 *Value,
  IN BOOLEAN Volatile
  )
{
  if (Value == NULL || StrLen(Value) == 0) {
    return (SHELL_DELETE_ENVIRONMENT_VARIABLE(Name));
  } else {
    SHELL_DELETE_ENVIRONMENT_VARIABLE(Name);
    if (Volatile) {
      return (SHELL_SET_ENVIRONMENT_VARIABLE_V(Name, StrSize(Value), Value));
    } else {
      return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(Name, StrSize(Value), Value));
    }
  }
}

/**
  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
       ){
    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).

  @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

  @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) {
      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);
      }
    } 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));
      MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
    }
  } else {
    //
    // cant have a mapping in the directory...
    //
    if (StrStr(DirectoryName, L":") != NULL) {
      return (EFI_INVALID_PARAMETER);
    }
    //
    // FileSystem != NULL
    //
    MapListItem = ShellCommandFindMapItem(FileSystem);
    if (MapListItem == NULL) {
      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 = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
      }
    }
  }
  //
  // 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));
      ASSERT(FixCommand != NULL);

      StrnCpy(FixCommand, 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 *
EFIAPI
InternalEfiShellGetListAlias(
  )
{
  UINT64            MaxStorSize;
  UINT64            RemStorSize;
  UINT64            MaxVarSize;
  EFI_STATUS        Status;
  EFI_GUID          Guid;
  CHAR16            *VariableName;
  UINTN             NameSize;
  CHAR16            *RetVal;
  UINTN             RetSize;

  Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);
  ASSERT_EFI_ERROR(Status);

  VariableName  = AllocateZeroPool((UINTN)MaxVarSize);
  RetSize       = 0;
  RetVal        = NULL;

  if (VariableName == NULL) {
    return (NULL);
  }

  VariableName[0] = CHAR_NULL;

  while (TRUE) {
    NameSize = (UINTN)MaxVarSize;
    Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
    if (Status == EFI_NOT_FOUND){
      break;
    }
    ASSERT_EFI_ERROR(Status);
    if (EFI_ERROR(Status)) {
      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
  FreePool(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;

  // Convert to lowercase to make aliases case-insensitive
  if (Alias != NULL) {
    AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
    ASSERT (AliasLower != NULL);
    ToLower (AliasLower);

    if (Volatile == NULL) {
      return (AddBufferToFreeList(GetVariable(AliasLower, &gShellAliasGuid)));
    }
    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);
      }
      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
EFIAPI
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);
    ASSERT (AliasLower != NULL);
    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
EFIAPI
CreatePopulateInstallShellProtocol (
  IN OUT EFI_SHELL_PROTOCOL  **NewShell
  )
{
  EFI_STATUS                  Status;
  UINTN                       BufferSize;
  EFI_HANDLE                  *Buffer;
  UINTN                       HandleCounter;
  SHELL_PROTOCOL_HANDLE_LIST  *OldProtocolNode;

  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++) {
      OldProtocolNode = AllocateZeroPool(sizeof(SHELL_PROTOCOL_HANDLE_LIST));
      ASSERT(OldProtocolNode != NULL);
      Status = gBS->OpenProtocol(Buffer[HandleCounter],
                                &gEfiShellProtocolGuid,
                                (VOID **) &(OldProtocolNode->Interface),
                                gImageHandle,
                                NULL,
                                EFI_OPEN_PROTOCOL_GET_PROTOCOL
                               );
      if (!EFI_ERROR(Status)) {
        //
        // reinstall over the old one...
        //
        OldProtocolNode->Handle = Buffer[HandleCounter];
        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
EFIAPI
CleanUpShellProtocol (
  IN OUT EFI_SHELL_PROTOCOL  *NewShell
  )
{
  EFI_STATUS                        Status;
  SHELL_PROTOCOL_HANDLE_LIST        *Node2;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;

  //
  // 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);
      Status = gBS->ReinstallProtocolInterface(Node2->Handle,
                                               &gEfiShellProtocolGuid,
                                               NewShell,
                                               Node2->Interface);
      FreePool(Node2);
    }
  } else {
    //
    // no need to restore
    //
    Status = gBS->UninstallProtocolInterface(gImageHandle,
                                             &gEfiShellProtocolGuid,
                                             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
EFIAPI
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);
}

