/** @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);
    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);
}
