/** @file
  Provides interface to EFI_FILE_HANDLE functionality.

  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>

#include <Protocol/SimpleFileSystem.h>
#include <Protocol/UnicodeCollation.h>

#include <Guid/FileInfo.h>

#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FileHandleLib.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>

CONST UINT16  gUnicodeFileTag = EFI_UNICODE_BYTE_ORDER_MARK;

#define MAX_FILE_NAME_LEN            522// (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)
#define FIND_XXXXX_FILE_BUFFER_SIZE  (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)

/**
  This function will retrieve the information about the file for the handle
  specified and store it in allocated pool memory.

  This function allocates a buffer to store the file's information. It is the
  caller's responsibility to free the buffer

  @param  FileHandle  The file handle of the file for which information is
  being requested.

  @retval NULL information could not be retrieved.

  @return the information about the file
**/
EFI_FILE_INFO *
EFIAPI
FileHandleGetInfo (
  IN EFI_FILE_HANDLE  FileHandle
  )
{
  EFI_FILE_INFO  *FileInfo;
  UINTN          FileInfoSize;
  EFI_STATUS     Status;

  if (FileHandle == NULL) {
    return (NULL);
  }

  //
  // Get the required size to allocate
  //
  FileInfoSize = 0;
  FileInfo     = NULL;
  Status       = FileHandle->GetInfo (
                               FileHandle,
                               &gEfiFileInfoGuid,
                               &FileInfoSize,
                               NULL
                               );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // error is expected.  getting size to allocate
    //
    FileInfo = AllocateZeroPool (FileInfoSize);
    if (FileInfo != NULL) {
      //
      // now get the information
      //
      Status = FileHandle->GetInfo (
                             FileHandle,
                             &gEfiFileInfoGuid,
                             &FileInfoSize,
                             FileInfo
                             );
      //
      // if we got an error free the memory and return NULL
      //
      if (EFI_ERROR (Status)) {
        FreePool (FileInfo);
        FileInfo = NULL;
      }
    }
  }

  return (FileInfo);
}

/**
  This function sets the information about the file for the opened handle
  specified.

  @param[in]  FileHandle        The file handle of the file for which information
                                is being set.

  @param[in]  FileInfo          The information to set.

  @retval EFI_SUCCESS           The information was set.
  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.
  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened read only.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
EFI_STATUS
EFIAPI
FileHandleSetInfo (
  IN EFI_FILE_HANDLE      FileHandle,
  IN CONST EFI_FILE_INFO  *FileInfo
  )
{
  if ((FileHandle == NULL) || (FileInfo == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Set the info
  //
  return (FileHandle->SetInfo (
                        FileHandle,
                        &gEfiFileInfoGuid,
                        (UINTN)FileInfo->Size,
                        (EFI_FILE_INFO *)FileInfo
                        ));
}

/**
  This function reads information from an opened file.

  If FileHandle is not a directory, the function reads the requested number of
  bytes from the file at the file's current position and returns them in Buffer.
  If the read goes beyond the end of the file, the read length is truncated to the
  end of the file. The file's current position is increased by the number of bytes
  returned.  If FileHandle is a directory, the function reads the directory entry
  at the file's current position and returns the entry in Buffer. If the Buffer
  is not large enough to hold the current directory entry, then
  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.
  BufferSize is set to be the size of the buffer needed to read the entry. On
  success, the current position is updated to the next directory entry. If there
  are no more directory entries, the read returns a zero-length buffer.
  EFI_FILE_INFO is the structure returned as the directory entry.

  @param FileHandle             the opened file handle
  @param BufferSize             on input the size of buffer in bytes.  on return
                                the number of bytes written.
  @param Buffer                 the buffer to put read data into.

  @retval EFI_SUCCESS           Data was read.
  @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.
  @retval EFI_BUFFER_TO_SMALL   Buffer is too small. ReadSize contains required
                                size.

**/
EFI_STATUS
EFIAPI
FileHandleRead (
  IN EFI_FILE_HANDLE  FileHandle,
  IN OUT UINTN        *BufferSize,
  OUT VOID            *Buffer
  )
{
  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the read based on EFI_FILE_PROTOCOL
  //
  return (FileHandle->Read (FileHandle, BufferSize, Buffer));
}

/**
  Write data to a file.

  This function writes the specified number of bytes to the file at the current
  file position. The current file position is advanced the actual number of bytes
  written, which is returned in BufferSize. Partial writes only occur when there
  has been a data error during the write attempt (such as "volume space full").
  The file is automatically grown to hold the data if required. Direct writes to
  opened directories are not supported.

  @param FileHandle           The opened file for writing
  @param BufferSize           on input the number of bytes in Buffer.  On output
                              the number of bytes written.
  @param Buffer               the buffer containing data to write is stored.

 @retval EFI_SUCCESS          Data was written.
 @retval EFI_UNSUPPORTED      Writes to an open directory are not supported.
 @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.
 @retval EFI_WRITE_PROTECTED  The device is write-protected.
 @retval EFI_ACCESS_DENIED    The file was open for read only.
 @retval EFI_VOLUME_FULL      The volume is full.
**/
EFI_STATUS
EFIAPI
FileHandleWrite (
  IN EFI_FILE_HANDLE  FileHandle,
  IN OUT UINTN        *BufferSize,
  IN VOID             *Buffer
  )
{
  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the write based on EFI_FILE_PROTOCOL
  //
  return (FileHandle->Write (FileHandle, BufferSize, Buffer));
}

/**
  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 FileHandle               the file handle to close.

@retval EFI_SUCCESS             the file handle was closed successfully.
**/
EFI_STATUS
EFIAPI
FileHandleClose (
  IN EFI_FILE_HANDLE  FileHandle
  )
{
  EFI_STATUS  Status;

  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the Close based on EFI_FILE_PROTOCOL
  //
  Status = FileHandle->Close (FileHandle);
  return Status;
}

/**
  Delete a file and close the handle

  This function closes and deletes a file. In all cases the file handle is closed.
  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is
  returned, but the handle is still closed.

  @param FileHandle             the file handle to delete

  @retval EFI_SUCCESS           the file was closed successfully
  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not
                                deleted
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
**/
EFI_STATUS
EFIAPI
FileHandleDelete (
  IN EFI_FILE_HANDLE  FileHandle
  )
{
  EFI_STATUS  Status;

  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the Delete based on EFI_FILE_PROTOCOL
  //
  Status = FileHandle->Delete (FileHandle);
  return Status;
}

/**
  Set the current position in a file.

  This function sets the current file position for the handle to the position
  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only
  absolute positioning is supported, and seeking past the end of the file is
  allowed (a subsequent write would grow the file). Seeking to position
  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.
  If FileHandle is a directory, the only position that may be set is zero. This
  has the effect of starting the read process of the directory entries over.

  @param FileHandle             The file handle on which the position is being set
  @param Position               Byte position from beginning of file

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on
                                directories.
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
**/
EFI_STATUS
EFIAPI
FileHandleSetPosition (
  IN EFI_FILE_HANDLE  FileHandle,
  IN UINT64           Position
  )
{
  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the SetPosition based on EFI_FILE_PROTOCOL
  //
  return (FileHandle->SetPosition (FileHandle, Position));
}

/**
  Gets a file's current position

  This function retrieves the current file position for the file handle. For
  directories, the current file position has no meaning outside of the file
  system driver and as such the operation is not supported. An error is returned
  if FileHandle is a directory.

  @param FileHandle             The open file handle on which to get the position.
  @param Position               Byte position from beginning of file.

  @retval EFI_SUCCESS           the operation completed successfully.
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
  @retval EFI_UNSUPPORTED       the request is not valid on directories.
**/
EFI_STATUS
EFIAPI
FileHandleGetPosition (
  IN EFI_FILE_HANDLE  FileHandle,
  OUT UINT64          *Position
  )
{
  if ((Position == NULL) || (FileHandle == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the GetPosition based on EFI_FILE_PROTOCOL
  //
  return (FileHandle->GetPosition (FileHandle, Position));
}

/**
  Flushes data on a file

  This function flushes all modified data associated with a file to a device.

  @param FileHandle             The file handle on which to flush data

  @retval EFI_SUCCESS           The data was flushed.
  @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.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened for read only.
**/
EFI_STATUS
EFIAPI
FileHandleFlush (
  IN EFI_FILE_HANDLE  FileHandle
  )
{
  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Perform the Flush based on EFI_FILE_PROTOCOL
  //
  return (FileHandle->Flush (FileHandle));
}

/**
  Function to determine if a given handle is a directory handle.

  Open the file information on the DirHandle and verify that the Attribute
  includes EFI_FILE_DIRECTORY bit set.

  @param[in] DirHandle          Handle to open file.

  @retval EFI_SUCCESS           DirHandle is a directory.
  @retval EFI_INVALID_PARAMETER DirHandle is NULL.
                                The file information returns from FileHandleGetInfo is NULL.
  @retval EFI_NOT_FOUND         DirHandle is not a directory.
**/
EFI_STATUS
EFIAPI
FileHandleIsDirectory (
  IN EFI_FILE_HANDLE  DirHandle
  )
{
  EFI_FILE_INFO  *DirInfo;

  if (DirHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // get the file information for DirHandle
  //
  DirInfo = FileHandleGetInfo (DirHandle);

  //
  // Parse DirInfo
  //
  if (DirInfo == NULL) {
    //
    // We got nothing...
    //
    return (EFI_INVALID_PARAMETER);
  }

  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
    //
    // Attributes say this is not a directory
    //
    FreePool (DirInfo);
    return (EFI_NOT_FOUND);
  }

  //
  // all good...
  //
  FreePool (DirInfo);
  return (EFI_SUCCESS);
}

/** Retrieve first entry from a directory.

  This function takes an open directory handle and gets information from the
  first entry in the directory.  A buffer is allocated to contain
  the information and a pointer to the buffer is returned in *Buffer.  The
  caller can use FileHandleFindNextFile() to get subsequent directory entries.

  The buffer will be freed by FileHandleFindNextFile() when the last directory
  entry is read.  Otherwise, the caller must free the buffer, using FreePool,
  when finished with it.

  @param[in]  DirHandle         The file handle of the directory to search.
  @param[out] Buffer            The pointer to pointer to buffer for file's information.

  @retval EFI_SUCCESS           Found the first file.
  @retval EFI_NOT_FOUND         Cannot find the directory.
  @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.
  @return Others                status of FileHandleGetInfo, FileHandleSetPosition,
                                or FileHandleRead
**/
EFI_STATUS
EFIAPI
FileHandleFindFirstFile (
  IN EFI_FILE_HANDLE  DirHandle,
  OUT EFI_FILE_INFO   **Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;

  if ((Buffer == NULL) || (DirHandle == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // verify that DirHandle is a directory
  //
  Status = FileHandleIsDirectory (DirHandle);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // Allocate a buffer sized to struct size + enough for the string at the end
  //
  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
  *Buffer    = AllocateZeroPool (BufferSize);
  if (*Buffer == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // reset to the beginning of the directory
  //
  Status = FileHandleSetPosition (DirHandle, 0);
  if (EFI_ERROR (Status)) {
    FreePool (*Buffer);
    *Buffer = NULL;
    return (Status);
  }

  //
  // read in the info about the first file
  //
  Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);
  ASSERT (Status != EFI_BUFFER_TOO_SMALL);
  if (EFI_ERROR (Status) || (BufferSize == 0)) {
    FreePool (*Buffer);
    *Buffer = NULL;
    if (BufferSize == 0) {
      return (EFI_NOT_FOUND);
    }

    return (Status);
  }

  return (EFI_SUCCESS);
}

/** Retrieve next entries from a directory.

  To use this function, the caller must first call the FileHandleFindFirstFile()
  function to get the first directory entry.  Subsequent directory entries are
  retrieved by using the FileHandleFindNextFile() function.  This function can
  be called several times to get each entry from the directory.  If the call of
  FileHandleFindNextFile() retrieved the last directory entry, the next call of
  this function will set *NoFile to TRUE and free the buffer.

  @param[in]  DirHandle         The file handle of the directory.
  @param[out] Buffer            The pointer to buffer for file's information.
  @param[out] NoFile            The pointer to boolean when last file is found.

  @retval EFI_SUCCESS           Found the next file, or reached last file
  @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
FileHandleFindNextFile (
  IN EFI_FILE_HANDLE  DirHandle,
  OUT EFI_FILE_INFO   *Buffer,
  OUT BOOLEAN         *NoFile
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;

  if ((DirHandle == NULL) || (Buffer == NULL) || (NoFile == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile
  //
  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;

  //
  // read in the info about the next file
  //
  Status = FileHandleRead (DirHandle, &BufferSize, Buffer);
  ASSERT (Status != EFI_BUFFER_TOO_SMALL);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // If we read 0 bytes (but did not have erros) we already read in the last file.
  //
  if (BufferSize == 0) {
    FreePool (Buffer);
    *NoFile = TRUE;
  }

  return (EFI_SUCCESS);
}

/**
  Retrieve the size of a file.

  This function extracts the file size info from the FileHandle's EFI_FILE_INFO
  data.

  @param[in] FileHandle         The file handle from which size is retrieved.
  @param[out] Size              The pointer to size.

  @retval EFI_SUCCESS           Operation was completed successfully.
  @retval EFI_DEVICE_ERROR      Cannot access the file.
  @retval EFI_INVALID_PARAMETER FileHandle is NULL.
                                Size is NULL.
**/
EFI_STATUS
EFIAPI
FileHandleGetSize (
  IN EFI_FILE_HANDLE  FileHandle,
  OUT UINT64          *Size
  )
{
  EFI_FILE_INFO  *FileInfo;

  if ((FileHandle == NULL) || (Size == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // get the FileInfo structure
  //
  FileInfo = FileHandleGetInfo (FileHandle);
  if (FileInfo == NULL) {
    return (EFI_DEVICE_ERROR);
  }

  //
  // Assign the Size pointer to the correct value
  //
  *Size = FileInfo->FileSize;

  //
  // free the FileInfo memory
  //
  FreePool (FileInfo);

  return (EFI_SUCCESS);
}

/**
  Set the size of a file.

  This function changes the file size info from the FileHandle's EFI_FILE_INFO
  data.

  @param[in] FileHandle         The file handle whose size is to be changed.
  @param[in] Size               The new size.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_DEVICE_ERROR      Cannot access the file.
  @retval EFI_INVALID_PARAMETER FileHandle is NULL.
**/
EFI_STATUS
EFIAPI
FileHandleSetSize (
  IN EFI_FILE_HANDLE  FileHandle,
  IN UINT64           Size
  )
{
  EFI_FILE_INFO  *FileInfo;
  EFI_STATUS     Status;

  if (FileHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // get the FileInfo structure
  //
  FileInfo = FileHandleGetInfo (FileHandle);
  if (FileInfo == NULL) {
    return (EFI_DEVICE_ERROR);
  }

  //
  // Assign the FileSize pointer to the new value
  //
  FileInfo->FileSize = Size;

  Status = FileHandleSetInfo (FileHandle, FileInfo);
  //
  // free the FileInfo memory
  //
  FreePool (FileInfo);

  return (Status);
}

/**
  Safely append (on the left) with automatic string resizing given length of Destination and
  desired length of copy from Source.

  append the first D characters of Source to the end of Destination, where D is
  the lesser of Count and the StrLen() of Source. If appending those D characters
  will fit within Destination (whose Size is given as CurrentSize) and
  still leave room for a NULL terminator, then those characters are appended,
  starting at the original terminating NULL of Destination, and a new terminating
  NULL is appended.

  If appending D characters onto Destination will result in a overflow of the size
  given in CurrentSize the string will be grown such that the copy can be performed
  and CurrentSize will be updated to the new size.

  If Source is NULL, there is nothing to append, just return the current buffer in
  Destination.

  if Destination is NULL, then return error
  if Destination's current length (including NULL terminator) is already more then
  CurrentSize, then ASSERT()

  @param[in, out] Destination   The String to append onto
  @param[in, out] CurrentSize   on call the number of bytes in Destination.  On
                                return possibly the new size (still in bytes).  if NULL
                                then allocate whatever is needed.
  @param[in]      Source        The String to append from
  @param[in]      Count         Maximum number of characters to append.  if 0 then
                                all are appended.

  @return Destination           return the resultant string.
**/
CHAR16 *
EFIAPI
StrnCatGrowLeft (
  IN OUT CHAR16        **Destination,
  IN OUT UINTN         *CurrentSize,
  IN     CONST CHAR16  *Source,
  IN     UINTN         Count
  )
{
  UINTN  DestinationStartSize;
  UINTN  NewSize;
  UINTN  CopySize;

  if (Destination == NULL) {
    return (NULL);
  }

  //
  // If there's nothing to do then just return Destination
  //
  if (Source == NULL) {
    return (*Destination);
  }

  //
  // allow for NULL pointers address as Destination
  //
  if (*Destination != NULL) {
    ASSERT (CurrentSize != 0);
    DestinationStartSize = StrSize (*Destination);
    ASSERT (DestinationStartSize <= *CurrentSize);
  } else {
    DestinationStartSize = 0;
    //    ASSERT(*CurrentSize == 0);
  }

  //
  // Append all of Source?
  //
  if (Count == 0) {
    Count = StrSize (Source);
  }

  //
  // Test and grow if required
  //
  if (CurrentSize != NULL) {
    NewSize = *CurrentSize;
    while (NewSize < (DestinationStartSize + Count)) {
      NewSize += 2 * Count;
    }

    *Destination = ReallocatePool (*CurrentSize, NewSize, *Destination);
    *CurrentSize = NewSize;
  } else {
    *Destination = AllocateZeroPool (Count+sizeof (CHAR16));
  }

  if (*Destination == NULL) {
    return NULL;
  }

  CopySize = StrSize (*Destination);
  CopyMem ((*Destination)+((Count-2)/sizeof (CHAR16)), *Destination, CopySize);
  CopyMem (*Destination, Source, Count-2);
  return (*Destination);
}

/**
  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the
  directory 'stack'. If the file is a directory, then append the '\' char at the
  end of name string. If it's not a directory, then the last '\' should not be
  added.

  if Handle is NULL, return EFI_INVALID_PARAMETER

  @param[in] Handle             Handle to the Directory or File to create path to.
  @param[out] FullFileName      pointer to pointer to generated full file name.  It
                                is the responsibility of the caller to free this memory
                                with a call to FreePool().
  @retval EFI_SUCCESS           the operation was sucessful and the FullFileName is valid.
  @retval EFI_INVALID_PARAMETER Handle was NULL.
  @retval EFI_INVALID_PARAMETER FullFileName was NULL.
  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
**/
EFI_STATUS
EFIAPI
FileHandleGetFileName (
  IN CONST EFI_FILE_HANDLE  Handle,
  OUT CHAR16                **FullFileName
  )
{
  EFI_STATUS       Status;
  UINTN            Size;
  EFI_FILE_HANDLE  CurrentHandle;
  EFI_FILE_HANDLE  NextHigherHandle;
  EFI_FILE_INFO    *FileInfo;

  Size = 0;

  //
  // Check our parameters
  //
  if ((FullFileName == NULL) || (Handle == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  *FullFileName = NULL;
  CurrentHandle = NULL;

  Status = Handle->Open (Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0);
  if (!EFI_ERROR (Status)) {
    //
    // Reverse out the current directory on the device
    //
    for ( ; ;) {
      FileInfo = FileHandleGetInfo (CurrentHandle);
      if (FileInfo == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      } else {
        //
        // Prepare to move to the parent directory.
        // Also determine whether CurrentHandle refers to the Root directory.
        //
        Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);
        //
        // We got info... do we have a name? if yes precede the current path with it...
        //
        if ((StrLen (FileInfo->FileName) == 0) || EFI_ERROR (Status)) {
          //
          // Both FileInfo->FileName being '\0' and EFI_ERROR() suggest that
          // CurrentHandle refers to the Root directory.  As this loop ensures
          // FullFileName is starting with '\\' at all times, signal success
          // and exit the loop.
          // While FileInfo->FileName could theoretically be a value other than
          // '\0' or '\\', '\\' is guaranteed to be supported by the
          // specification and hence its value can safely be ignored.
          //
          Status = EFI_SUCCESS;
          if (*FullFileName == NULL) {
            ASSERT ((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
            *FullFileName = StrnCatGrowLeft (FullFileName, &Size, L"\\", 0);
          }

          FreePool (FileInfo);
          break;
        } else {
          if (*FullFileName == NULL) {
            ASSERT ((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
            *FullFileName = StrnCatGrowLeft (FullFileName, &Size, L"\\", 0);
          }

          ASSERT ((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
          *FullFileName = StrnCatGrowLeft (FullFileName, &Size, FileInfo->FileName, 0);
          *FullFileName = StrnCatGrowLeft (FullFileName, &Size, L"\\", 0);
          FreePool (FileInfo);
        }
      }

      FileHandleClose (CurrentHandle);
      //
      // Move to the parent directory
      //
      CurrentHandle = NextHigherHandle;
    }
  } else if (Status == EFI_NOT_FOUND) {
    Status = EFI_SUCCESS;
    ASSERT ((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
    *FullFileName = StrnCatGrowLeft (FullFileName, &Size, L"\\", 0);
  }

  if ((*FullFileName != NULL) &&
      ((*FullFileName)[StrLen (*FullFileName) - 1] == L'\\') &&
      (StrLen (*FullFileName) > 1) &&
      (FileHandleIsDirectory (Handle) == EFI_NOT_FOUND)
      )
  {
    (*FullFileName)[StrLen (*FullFileName) - 1] = CHAR_NULL;
  }

  if (CurrentHandle != NULL) {
    CurrentHandle->Close (CurrentHandle);
  }

  if (EFI_ERROR (Status) && (*FullFileName != NULL)) {
    FreePool (*FullFileName);
  }

  return (Status);
}

/**
  Function to read a single line from a file. The \n is not included in the returned
  buffer.  The returned buffer must be callee freed.

  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
  maintained and not changed for all operations with the same file.

  @param[in]       Handle        FileHandle to read from.
  @param[in, out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);

  @return                       The line of text from the file.

  @sa FileHandleReadLine
**/
CHAR16 *
EFIAPI
FileHandleReturnLine (
  IN EFI_FILE_HANDLE  Handle,
  IN OUT BOOLEAN      *Ascii
  )
{
  CHAR16      *RetVal;
  UINTN       Size;
  EFI_STATUS  Status;

  Size   = 0;
  RetVal = NULL;

  Status = FileHandleReadLine (Handle, RetVal, &Size, FALSE, Ascii);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    RetVal = AllocateZeroPool (Size);

    if (RetVal == NULL) {
      return NULL;
    }

    Status = FileHandleReadLine (Handle, RetVal, &Size, FALSE, Ascii);
  }

  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status) && (RetVal != NULL)) {
    FreePool (RetVal);
    RetVal = NULL;
  }

  return (RetVal);
}

/**
  Function to read a single line (up to but not including the \n) from a file.

  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
  maintained and not changed for all operations with the same file.
  The function will not return the \r and \n character in buffer. When an empty line is
  read a CHAR_NULL character will be returned in buffer.

  @param[in]       Handle        FileHandle to read from.
  @param[in, out]  Buffer        The pointer to buffer to read into.
  @param[in, out]  Size          The pointer to number of bytes in Buffer.
  @param[in]       Truncate      If the buffer is large enough, this has no effect.
                                 If the buffer is is too small and Truncate is TRUE,
                                 the line will be truncated.
                                 If the buffer is is too small and Truncate is FALSE,
                                 then no read will occur.

  @param[in, out]  Ascii         Boolean value for indicating whether the file is
                                 Ascii (TRUE) or UCS2 (FALSE).

  @retval EFI_SUCCESS           The operation was successful.  The line is stored in
                                Buffer.
  @retval EFI_INVALID_PARAMETER Handle was NULL.
  @retval EFI_INVALID_PARAMETER Size was NULL.
  @retval EFI_BUFFER_TOO_SMALL  Size was not large enough to store the line.
                                Size was updated to the minimum space required.
  @sa FileHandleRead
**/
EFI_STATUS
EFIAPI
FileHandleReadLine (
  IN EFI_FILE_HANDLE  Handle,
  IN OUT CHAR16       *Buffer,
  IN OUT UINTN        *Size,
  IN BOOLEAN          Truncate,
  IN OUT BOOLEAN      *Ascii
  )
{
  EFI_STATUS  Status;
  CHAR16      CharBuffer;
  UINT64      FileSize;
  UINTN       CharSize;
  UINTN       CountSoFar;
  UINTN       CrCount;
  UINTN       OldSize;
  UINT64      OriginalFilePosition;

  if (  (Handle == NULL)
     || (Size   == NULL)
     || ((Buffer == NULL) && (*Size != 0))
        )
  {
    return (EFI_INVALID_PARAMETER);
  }

  if ((Buffer != NULL) && (*Size != 0)) {
    *Buffer = CHAR_NULL;
  }

  Status = FileHandleGetSize (Handle, &FileSize);
  if (EFI_ERROR (Status)) {
    return Status;
  } else if (FileSize == 0) {
    *Ascii = TRUE;
    return EFI_SUCCESS;
  }

  FileHandleGetPosition (Handle, &OriginalFilePosition);
  if (OriginalFilePosition == 0) {
    CharSize = sizeof (CHAR16);
    Status   = FileHandleRead (Handle, &CharSize, &CharBuffer);
    ASSERT_EFI_ERROR (Status);
    if (CharBuffer == gUnicodeFileTag) {
      *Ascii = FALSE;
    } else {
      *Ascii = TRUE;
      FileHandleSetPosition (Handle, OriginalFilePosition);
    }
  }

  CrCount = 0;
  for (CountSoFar = 0; ; CountSoFar++) {
    CharBuffer = 0;
    if (*Ascii) {
      CharSize = sizeof (CHAR8);
    } else {
      CharSize = sizeof (CHAR16);
    }

    Status = FileHandleRead (Handle, &CharSize, &CharBuffer);
    if (  EFI_ERROR (Status)
       || (CharSize == 0)
       || ((CharBuffer == L'\n') && !(*Ascii))
       || ((CharBuffer ==  '\n') && *Ascii)
          )
    {
      break;
    } else if (
               ((CharBuffer == L'\r') && !(*Ascii)) ||
               ((CharBuffer ==  '\r') && *Ascii)
               )
    {
      CrCount++;
      continue;
    }

    //
    // if we have space save it...
    //
    if ((CountSoFar+1-CrCount)*sizeof (CHAR16) < *Size) {
      ASSERT (Buffer != NULL);
      ((CHAR16 *)Buffer)[CountSoFar-CrCount]   = CharBuffer;
      ((CHAR16 *)Buffer)[CountSoFar+1-CrCount] = CHAR_NULL;
    }
  }

  //
  // if we ran out of space tell when...
  //
  if ((CountSoFar+1-CrCount)*sizeof (CHAR16) > *Size) {
    OldSize = *Size;
    *Size   = (CountSoFar+1-CrCount)*sizeof (CHAR16);
    if (!Truncate) {
      if ((Buffer != NULL) && (OldSize != 0)) {
        ZeroMem (Buffer, OldSize);
      }

      FileHandleSetPosition (Handle, OriginalFilePosition);
      return (EFI_BUFFER_TOO_SMALL);
    } else {
      DEBUG ((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));
      return (EFI_SUCCESS);
    }
  }

  return (Status);
}

/**
  Function to write a line of text to a file.

  If the file is a Unicode file (with UNICODE file tag) then write the unicode
  text.
  If the file is an ASCII file then write the ASCII text.
  If the size of file is zero (without file tag at the beginning) then write
  ASCII text as default.

  @param[in]     Handle         FileHandle to write to.
  @param[in]     Buffer         Buffer to write, if NULL the function will
                                take no action and return EFI_SUCCESS.

  @retval  EFI_SUCCESS            The data was written.
                                  Buffer is NULL.
  @retval  EFI_INVALID_PARAMETER  Handle is NULL.
  @retval  EFI_OUT_OF_RESOURCES   Unable to allocate temporary space for ASCII
                                  string due to out of resources.

  @sa FileHandleWrite
**/
EFI_STATUS
EFIAPI
FileHandleWriteLine (
  IN EFI_FILE_HANDLE  Handle,
  IN CHAR16           *Buffer
  )
{
  EFI_STATUS  Status;
  CHAR16      CharBuffer;
  UINTN       Size;
  UINTN       Index;
  UINTN       CharSize;
  UINT64      FileSize;
  UINT64      OriginalFilePosition;
  BOOLEAN     Ascii;
  CHAR8       *AsciiBuffer;

  if (Buffer == NULL) {
    return (EFI_SUCCESS);
  }

  if (Handle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Ascii       = FALSE;
  AsciiBuffer = NULL;

  Status = FileHandleGetPosition (Handle, &OriginalFilePosition);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = FileHandleSetPosition (Handle, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = FileHandleGetSize (Handle, &FileSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (FileSize == 0) {
    Ascii = TRUE;
  } else {
    CharSize = sizeof (CHAR16);
    Status   = FileHandleRead (Handle, &CharSize, &CharBuffer);
    ASSERT_EFI_ERROR (Status);
    if (CharBuffer == gUnicodeFileTag) {
      Ascii = FALSE;
    } else {
      Ascii = TRUE;
    }
  }

  Status = FileHandleSetPosition (Handle, OriginalFilePosition);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Ascii) {
    Size        = (StrSize (Buffer) / sizeof (CHAR16)) * sizeof (CHAR8);
    AsciiBuffer = (CHAR8 *)AllocateZeroPool (Size);
    if (AsciiBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size);
    for (Index = 0; Index < Size; Index++) {
      if ((AsciiBuffer[Index] & BIT7) != 0) {
        FreePool (AsciiBuffer);
        return EFI_INVALID_PARAMETER;
      }
    }

    Size   = AsciiStrSize (AsciiBuffer) - sizeof (CHAR8);
    Status = FileHandleWrite (Handle, &Size, AsciiBuffer);
    if (EFI_ERROR (Status)) {
      FreePool (AsciiBuffer);
      return (Status);
    }

    Size   = AsciiStrSize ("\r\n") - sizeof (CHAR8);
    Status = FileHandleWrite (Handle, &Size, "\r\n");
  } else {
    if (OriginalFilePosition == 0) {
      Status = FileHandleSetPosition (Handle, sizeof (CHAR16));
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    Size   = StrSize (Buffer) - sizeof (CHAR16);
    Status = FileHandleWrite (Handle, &Size, Buffer);
    if (EFI_ERROR (Status)) {
      return (Status);
    }

    Size   = StrSize (L"\r\n") - sizeof (CHAR16);
    Status = FileHandleWrite (Handle, &Size, L"\r\n");
  }

  if (AsciiBuffer != NULL) {
    FreePool (AsciiBuffer);
  }

  return Status;
}

/**
  function to take a formatted argument and print it to a file.

  @param[in] Handle   the file handle for the file to write to
  @param[in] Format   the format argument (see printlib for format specifier)
  @param[in] ...      the variable arguments for the format

  @retval EFI_SUCCESS the operation was successful
  @return other       a return value from FileHandleWriteLine

  @sa FileHandleWriteLine
**/
EFI_STATUS
EFIAPI
FileHandlePrintLine (
  IN EFI_FILE_HANDLE  Handle,
  IN CONST CHAR16     *Format,
  ...
  )
{
  VA_LIST     Marker;
  CHAR16      *Buffer;
  EFI_STATUS  Status;

  //
  // Get a buffer to print into
  //
  Buffer = AllocateZeroPool (PcdGet16 (PcdUefiFileHandleLibPrintBufferSize));
  if (Buffer == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // Print into our buffer
  //
  VA_START (Marker, Format);
  UnicodeVSPrint (Buffer, PcdGet16 (PcdUefiFileHandleLibPrintBufferSize), Format, Marker);
  VA_END (Marker);

  //
  // Print buffer into file
  //
  Status = FileHandleWriteLine (Handle, Buffer);

  //
  // Cleanup and return
  //
  FreePool (Buffer);
  return (Status);
}

/**
  Function to determine if a FILE_HANDLE is at the end of the file.

  This will NOT work on directories.

  If Handle is NULL, then return False.

  @param[in] Handle     the file handle

  @retval TRUE          the position is at the end of the file
  @retval FALSE         the position is not at the end of the file
**/
BOOLEAN
EFIAPI
FileHandleEof (
  IN EFI_FILE_HANDLE  Handle
  )
{
  EFI_FILE_INFO  *Info;
  UINT64         Pos;
  BOOLEAN        RetVal;

  if (Handle == NULL) {
    return (FALSE);
  }

  FileHandleGetPosition (Handle, &Pos);
  Info = FileHandleGetInfo (Handle);

  if (Info == NULL) {
    return (FALSE);
  }

  FileHandleSetPosition (Handle, Pos);

  if (Pos == Info->FileSize) {
    RetVal = TRUE;
  } else {
    RetVal = FALSE;
  }

  FreePool (Info);

  return (RetVal);
}
