/*++ @file
 POSIX Pthreads to emulate APs and implement threads

Copyright (c) 2011, Apple Inc. All rights reserved.
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Host.h"


#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 's')

typedef struct {
  UINTN                           Signature;
  EMU_IO_THUNK_PROTOCOL           *Thunk;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;
  CHAR8                           *FilePath;
  CHAR16                          *VolumeLabel;
  BOOLEAN                         FileHandlesOpen;
} EMU_SIMPLE_FILE_SYSTEM_PRIVATE;

#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
  CR (a, \
      EMU_SIMPLE_FILE_SYSTEM_PRIVATE, \
      SimpleFileSystem, \
      EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
      )


#define EMU_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 'i')

typedef struct {
  UINTN                           Signature;
  EMU_IO_THUNK_PROTOCOL           *Thunk;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
  EFI_FILE_PROTOCOL               EfiFile;
  int                             fd;
  DIR                             *Dir;
  BOOLEAN                         IsRootDirectory;
  BOOLEAN                         IsDirectoryPath;
  BOOLEAN                         IsOpenedByRead;
  char                            *FileName;
  struct dirent                   *Dirent;
} EMU_EFI_FILE_PRIVATE;

#define EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
  CR (a, \
      EMU_EFI_FILE_PRIVATE, \
      EfiFile, \
      EMU_EFI_FILE_PRIVATE_SIGNATURE \
      )

EFI_STATUS
PosixFileGetInfo (
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN OUT UINTN                *BufferSize,
  OUT VOID                    *Buffer
  );

EFI_STATUS
PosixFileSetInfo (
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN UINTN                    BufferSize,
  IN VOID                     *Buffer
  );


EFI_FILE_PROTOCOL gPosixFileProtocol = {
  EFI_FILE_REVISION,
  GasketPosixFileOpen,
  GasketPosixFileCLose,
  GasketPosixFileDelete,
  GasketPosixFileRead,
  GasketPosixFileWrite,
  GasketPosixFileGetPossition,
  GasketPosixFileSetPossition,
  GasketPosixFileGetInfo,
  GasketPosixFileSetInfo,
  GasketPosixFileFlush
};

EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gPosixFileSystemProtocol = {
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
  GasketPosixOpenVolume,
};


/**
  Open the root directory on a volume.

  @param  This Protocol instance pointer.
  @param  Root Returns an Open file handle for the root directory

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_UNSUPPORTED      This volume does not support the file system.
  @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_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.

**/
EFI_STATUS
PosixOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *This,
  OUT EFI_FILE_PROTOCOL                 **Root
  )
{
  EFI_STATUS                        Status;
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *Private;
  EMU_EFI_FILE_PRIVATE              *PrivateFile;

  Private     = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);

  Status = EFI_OUT_OF_RESOURCES;
  PrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE));
  if (PrivateFile == NULL) {
    goto Done;
  }

  PrivateFile->FileName = malloc (AsciiStrSize (Private->FilePath));
  if (PrivateFile->FileName == NULL) {
    goto Done;
  }
  AsciiStrCpyS (
    PrivateFile->FileName,
    AsciiStrSize (Private->FilePath),
    Private->FilePath
    );

  PrivateFile->Signature            = EMU_EFI_FILE_PRIVATE_SIGNATURE;
  PrivateFile->Thunk                = Private->Thunk;
  PrivateFile->SimpleFileSystem     = This;
  PrivateFile->IsRootDirectory      = TRUE;
  PrivateFile->IsDirectoryPath      = TRUE;
  PrivateFile->IsOpenedByRead       = TRUE;

  CopyMem (&PrivateFile->EfiFile, &gPosixFileProtocol, sizeof (EFI_FILE_PROTOCOL));

  PrivateFile->fd                   = -1;
  PrivateFile->Dir                  = NULL;
  PrivateFile->Dirent               = NULL;

  *Root = &PrivateFile->EfiFile;

  PrivateFile->Dir = opendir (PrivateFile->FileName);
  if (PrivateFile->Dir == NULL) {
    Status = EFI_ACCESS_DENIED;
  } else {
    Status = EFI_SUCCESS;
  }

Done:
  if (EFI_ERROR (Status)) {
    if (PrivateFile != NULL) {
      if (PrivateFile->FileName != NULL) {
        free (PrivateFile->FileName);
      }

      free (PrivateFile);
    }

    *Root = NULL;
  }

  return Status;
}


EFI_STATUS
ErrnoToEfiStatus ()
{
  switch (errno) {
  case EACCES:
    return EFI_ACCESS_DENIED;

  case EDQUOT:
  case ENOSPC:
    return EFI_VOLUME_FULL;

  default:
    return EFI_DEVICE_ERROR;
  }
}

VOID
CutPrefix (
  IN  CHAR8  *Str,
  IN  UINTN   Count
  )
{
  CHAR8  *Pointer;

  if (AsciiStrLen (Str) < Count) {
    ASSERT (0);
  }

  for (Pointer = Str; *(Pointer + Count); Pointer++) {
    *Pointer = *(Pointer + Count);
  }

  *Pointer = *(Pointer + Count);
}


VOID
PosixSystemTimeToEfiTime (
  IN  time_t                SystemTime,
  OUT EFI_TIME              *Time
  )
{
  struct tm *tm;

  tm           = gmtime (&SystemTime);
  Time->Year   = tm->tm_year;
  Time->Month  = tm->tm_mon + 1;
  Time->Day    = tm->tm_mday;
  Time->Hour   = tm->tm_hour;
  Time->Minute = tm->tm_min;
  Time->Second = tm->tm_sec;
  Time->Nanosecond = 0;

  Time->TimeZone = timezone / 60;
  Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
}


EFI_STATUS
UnixSimpleFileSystemFileInfo (
  EMU_EFI_FILE_PRIVATE            *PrivateFile,
  IN     CHAR8                    *FileName,
  IN OUT UINTN                    *BufferSize,
  OUT    VOID                     *Buffer
  )
{
  EFI_STATUS                  Status;
  UINTN                       Size;
  UINTN                       NameSize;
  UINTN                       ResultSize;
  EFI_FILE_INFO               *Info;
  CHAR8                       *RealFileName;
  CHAR8                       *TempPointer;
  CHAR16                      *BufferFileName;
  struct stat                 buf;

  if (FileName != NULL) {
    RealFileName = FileName;
  } else if (PrivateFile->IsRootDirectory) {
    RealFileName = "";
  } else {
    RealFileName  = PrivateFile->FileName;
  }

  TempPointer = RealFileName;
  while (*TempPointer) {
    if (*TempPointer == '/') {
      RealFileName = TempPointer + 1;
    }

    TempPointer++;
  }

  Size        = SIZE_OF_EFI_FILE_INFO;
  NameSize    = AsciiStrSize (RealFileName) * 2;
  ResultSize  = Size + NameSize;

  if (*BufferSize < ResultSize) {
    *BufferSize = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }
  if (stat (FileName == NULL ? PrivateFile->FileName : FileName, &buf) < 0) {
    return EFI_DEVICE_ERROR;
  }

  Status  = EFI_SUCCESS;

  Info    = Buffer;
  ZeroMem (Info, ResultSize);

  Info->Size          = ResultSize;
  Info->FileSize      = buf.st_size;
  Info->PhysicalSize  = MultU64x32 (buf.st_blocks, buf.st_blksize);

  PosixSystemTimeToEfiTime (buf.st_ctime, &Info->CreateTime);
  PosixSystemTimeToEfiTime (buf.st_atime, &Info->LastAccessTime);
  PosixSystemTimeToEfiTime (buf.st_mtime, &Info->ModificationTime);

  if (!(buf.st_mode & S_IWUSR)) {
    Info->Attribute |= EFI_FILE_READ_ONLY;
  }

  if (S_ISDIR(buf.st_mode)) {
    Info->Attribute |= EFI_FILE_DIRECTORY;
  }


  BufferFileName = (CHAR16 *)((CHAR8 *) Buffer + Size);
  while (*RealFileName) {
    *BufferFileName++ = *RealFileName++;
  }
  *BufferFileName = 0;

  *BufferSize = ResultSize;
  return Status;
}

BOOLEAN
IsZero (
  IN VOID   *Buffer,
  IN UINTN  Length
  )
{
  if (Buffer == NULL || Length == 0) {
    return FALSE;
  }

  if (*(UINT8 *) Buffer != 0) {
    return FALSE;
  }

  if (Length > 1) {
    if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {
      return FALSE;
    }
  }

  return TRUE;
}



/**
  Opens a new file relative to the source file's location.

  @param  This       The protocol instance pointer.
  @param  NewHandle  Returns File Handle for FileName.
  @param  FileName   Null terminated string. "\", ".", and ".." are supported.
  @param  OpenMode   Open mode for file.
  @param  Attributes Only used for EFI_FILE_MODE_CREATE.

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_MEDIA_CHANGED    The media has changed.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
EFI_STATUS
PosixFileOpen (
  IN EFI_FILE_PROTOCOL        *This,
  OUT EFI_FILE_PROTOCOL       **NewHandle,
  IN CHAR16                   *FileName,
  IN UINT64                   OpenMode,
  IN UINT64                   Attributes
  )
{
  EFI_FILE_PROTOCOL                 *Root;
  EMU_EFI_FILE_PRIVATE              *PrivateFile;
  EMU_EFI_FILE_PRIVATE              *NewPrivateFile;
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *PrivateRoot;
  EFI_STATUS                        Status;
  CHAR16                            *Src;
  char                              *Dst;
  CHAR8                             *RealFileName;
  char                              *ParseFileName;
  char                              *GuardPointer;
  CHAR8                             TempChar;
  UINTN                             Count;
  BOOLEAN                           TrailingDash;
  BOOLEAN                           LoopFinish;
  UINTN                             InfoSize;
  EFI_FILE_INFO                     *Info;
  struct stat                       finfo;
  int                               res;
  UINTN                             Size;

  PrivateFile     = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
  PrivateRoot     = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
  NewPrivateFile  = NULL;
  Status          = EFI_OUT_OF_RESOURCES;

  //
  // BUGBUG: assume an open of root
  // if current location, return current data
  //
  TrailingDash = FALSE;
  if ((StrCmp (FileName, L"\\") == 0) ||
      (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {
OpenRoot:
    Status          = PosixOpenVolume (PrivateFile->SimpleFileSystem, &Root);
    NewPrivateFile  = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);
    goto Done;
  }

  if (FileName[StrLen (FileName) - 1] == L'\\') {
    TrailingDash = TRUE;
    FileName[StrLen (FileName) - 1]  = 0;
  }

  //
  // Attempt to open the file
  //
  NewPrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE));
  if (NewPrivateFile == NULL) {
    goto Done;
  }

  CopyMem (NewPrivateFile, PrivateFile, sizeof (EMU_EFI_FILE_PRIVATE));

  Size = AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1;
  NewPrivateFile->FileName = malloc (Size);
  if (NewPrivateFile->FileName == NULL) {
    goto Done;
  }

  if (*FileName == L'\\') {
    AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateRoot->FilePath);
    // Skip first '\'.
    Src = FileName + 1;
  } else {
    AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateFile->FileName);
    Src = FileName;
  }
  Dst = NewPrivateFile->FileName + AsciiStrLen (NewPrivateFile->FileName);
  GuardPointer = NewPrivateFile->FileName + AsciiStrLen (PrivateRoot->FilePath);
  *Dst++ = '/';
  // Convert unicode to ascii and '\' to '/'
  while (*Src) {
    if (*Src == '\\') {
      *Dst++ = '/';
    } else {
      *Dst++ = *Src;
    }
    Src++;
  }
  *Dst = 0;


  //
  // Get rid of . and .., except leading . or ..
  //

  //
  // GuardPointer protect simplefilesystem root path not be destroyed
  //

  LoopFinish    = FALSE;
  while (!LoopFinish) {
    LoopFinish = TRUE;

    for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {
      if (*ParseFileName == '.' &&
          (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == '/') &&
          *(ParseFileName - 1) == '/'
          ) {

        //
        // cut /.
        //
        CutPrefix (ParseFileName - 1, 2);
        LoopFinish = FALSE;
        break;
      }

      if (*ParseFileName == '.' &&
          *(ParseFileName + 1) == '.' &&
          (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == '/') &&
          *(ParseFileName - 1) == '/'
          ) {

        ParseFileName--;
        Count = 3;

        while (ParseFileName != GuardPointer) {
          ParseFileName--;
          Count++;
          if (*ParseFileName == '/') {
            break;
          }
        }

        //
        // cut /.. and its left directory
        //
        CutPrefix (ParseFileName, Count);
        LoopFinish = FALSE;
        break;
      }
    }
  }

  if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {
    NewPrivateFile->IsRootDirectory = TRUE;
    free (NewPrivateFile->FileName);
    free (NewPrivateFile);
    goto OpenRoot;
  }

  RealFileName = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName) - 1;
  while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/') {
    RealFileName--;
  }

  TempChar            = *(RealFileName - 1);
  *(RealFileName - 1) = 0;
  *(RealFileName - 1) = TempChar;


  //
  // Test whether file or directory
  //
  NewPrivateFile->IsRootDirectory = FALSE;
  NewPrivateFile->fd = -1;
  NewPrivateFile->Dir = NULL;
  if (OpenMode & EFI_FILE_MODE_CREATE) {
    if (Attributes & EFI_FILE_DIRECTORY) {
      NewPrivateFile->IsDirectoryPath = TRUE;
    } else {
      NewPrivateFile->IsDirectoryPath = FALSE;
    }
  } else {
    res = stat (NewPrivateFile->FileName, &finfo);
    if (res == 0 && S_ISDIR(finfo.st_mode)) {
      NewPrivateFile->IsDirectoryPath = TRUE;
    } else {
      NewPrivateFile->IsDirectoryPath = FALSE;
    }
  }

  if (OpenMode & EFI_FILE_MODE_WRITE) {
    NewPrivateFile->IsOpenedByRead = FALSE;
  } else {
    NewPrivateFile->IsOpenedByRead = TRUE;
  }

  Status = EFI_SUCCESS;

  //
  // deal with directory
  //
  if (NewPrivateFile->IsDirectoryPath) {
    if ((OpenMode & EFI_FILE_MODE_CREATE)) {
      //
      // Create a directory
      //
      if (mkdir (NewPrivateFile->FileName, 0777) != 0) {
        if (errno != EEXIST) {
          //free (TempFileName);
          Status = EFI_ACCESS_DENIED;
          goto Done;
        }
      }
    }

    NewPrivateFile->Dir = opendir (NewPrivateFile->FileName);
    if (NewPrivateFile->Dir == NULL) {
      if (errno == EACCES) {
        Status = EFI_ACCESS_DENIED;
      } else {
        Status = EFI_NOT_FOUND;
      }

      goto Done;
    }

  } else {
    //
    // deal with file
    //
    NewPrivateFile->fd = open (
                          NewPrivateFile->FileName,
                          ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0) | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR),
                          0666
                          );
    if (NewPrivateFile->fd < 0) {
      if (errno == ENOENT) {
        Status = EFI_NOT_FOUND;
      } else {
        Status = EFI_ACCESS_DENIED;
      }
    }
  }

  if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {
    //
    // Set the attribute
    //
    InfoSize  = 0;
    Info      = NULL;
    Status    = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
    if (Status != EFI_BUFFER_TOO_SMALL) {
      Status = EFI_DEVICE_ERROR;
      goto Done;
    }

    Info = malloc (InfoSize);
    if (Info == NULL) {
      goto Done;
    }

    Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    Info->Attribute = Attributes;
    PosixFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);

    free (Info);
  }

Done: ;
  if (TrailingDash) {
    FileName[StrLen (FileName) + 1]  = 0;
    FileName[StrLen (FileName)]      = L'\\';
  }

  if (EFI_ERROR (Status)) {
    if (NewPrivateFile) {
      if (NewPrivateFile->FileName) {
        free (NewPrivateFile->FileName);
      }

      free (NewPrivateFile);
    }
  } else {
    *NewHandle = &NewPrivateFile->EfiFile;
  }

  return Status;
}



/**
  Close the file handle

  @param  This          Protocol instance pointer.

  @retval EFI_SUCCESS   The device was opened.

**/
EFI_STATUS
PosixFileCLose (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  EMU_EFI_FILE_PRIVATE *PrivateFile;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->fd >= 0) {
    close (PrivateFile->fd);
  }
  if (PrivateFile->Dir != NULL) {
    closedir (PrivateFile->Dir);
  }

  PrivateFile->fd = -1;
  PrivateFile->Dir = NULL;

  if (PrivateFile->FileName) {
    free (PrivateFile->FileName);
  }

  free (PrivateFile);

  return EFI_SUCCESS;
}


/**
  Close and delete the file handle.

  @param  This                     Protocol instance pointer.

  @retval EFI_SUCCESS              The device was opened.
  @retval EFI_WARN_DELETE_FAILURE  The handle was closed but the file was not deleted.

**/
EFI_STATUS
PosixFileDelete (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  EFI_STATUS              Status;
  EMU_EFI_FILE_PRIVATE   *PrivateFile;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
  Status      = EFI_WARN_DELETE_FAILURE;

  if (PrivateFile->IsDirectoryPath) {
    if (PrivateFile->Dir != NULL) {
      closedir (PrivateFile->Dir);
      PrivateFile->Dir = NULL;
    }

    if (rmdir (PrivateFile->FileName) == 0) {
      Status = EFI_SUCCESS;
    }
  } else {
    close (PrivateFile->fd);
    PrivateFile->fd = -1;

    if (!PrivateFile->IsOpenedByRead) {
      if (!unlink (PrivateFile->FileName)) {
        Status = EFI_SUCCESS;
      }
    }
  }

  free (PrivateFile->FileName);
  free (PrivateFile);

  return Status;
}


/**
  Read data from the file.

  @param  This       Protocol instance pointer.
  @param  BufferSize On input size of buffer, on output amount of data in buffer.
  @param  Buffer     The buffer in which data is read.

  @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  BufferSize is too small. BufferSize contains required size.

**/
EFI_STATUS
PosixFileRead (
  IN EFI_FILE_PROTOCOL        *This,
  IN OUT UINTN                *BufferSize,
  OUT VOID                    *Buffer
  )
{
  EMU_EFI_FILE_PRIVATE    *PrivateFile;
  EFI_STATUS              Status;
  int                     Res;
  UINTN                   Size;
  UINTN                   NameSize;
  UINTN                   ResultSize;
  CHAR8                   *FullFileName;
  UINTN                   FullFileNameSize;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (!PrivateFile->IsDirectoryPath) {
    if (PrivateFile->fd < 0) {
      Status = EFI_DEVICE_ERROR;
      goto Done;
    }

    Res = read (PrivateFile->fd, Buffer, *BufferSize);
    if (Res < 0) {
      Status = EFI_DEVICE_ERROR;
      goto Done;
    }
    *BufferSize = Res;
    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // Read on a directory.
  //
  if (PrivateFile->Dir == NULL) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  if (PrivateFile->Dirent == NULL) {
    PrivateFile->Dirent = readdir (PrivateFile->Dir);
    if (PrivateFile->Dirent == NULL) {
      *BufferSize = 0;
      Status = EFI_SUCCESS;
      goto Done;
    }
  }

  Size        = SIZE_OF_EFI_FILE_INFO;
  NameSize    = AsciiStrLen (PrivateFile->Dirent->d_name) + 1;
  ResultSize  = Size + 2 * NameSize;

  if (*BufferSize < ResultSize) {
    *BufferSize = ResultSize;
    Status = EFI_BUFFER_TOO_SMALL;
    goto Done;
  }
  Status  = EFI_SUCCESS;

  *BufferSize = ResultSize;

  FullFileNameSize = AsciiStrLen(PrivateFile->FileName) + 1 + NameSize;
  FullFileName = malloc (FullFileNameSize);
  if (FullFileName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  AsciiStrCpyS (FullFileName, FullFileNameSize, PrivateFile->FileName);
  AsciiStrCatS (FullFileName, FullFileNameSize, "/");
  AsciiStrCatS (FullFileName, FullFileNameSize, PrivateFile->Dirent->d_name);
  Status = UnixSimpleFileSystemFileInfo (
            PrivateFile,
            FullFileName,
            BufferSize,
            Buffer
            );
  free (FullFileName);

  PrivateFile->Dirent = NULL;

Done:
  return Status;
}



/**
  Write data to a file.

  @param  This       Protocol instance pointer.
  @param  BufferSize On input size of buffer, on output amount of data in buffer.
  @param  Buffer     The buffer in which data to write.

  @retval EFI_SUCCESS          Data was written.
  @retval EFI_UNSUPPORTED      Writes to 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_DEVICE_ERROR     An attempt was made to write to a deleted file.
  @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
PosixFileWrite (
  IN EFI_FILE_PROTOCOL        *This,
  IN OUT UINTN                *BufferSize,
  IN VOID                     *Buffer
  )
{
  EMU_EFI_FILE_PRIVATE  *PrivateFile;
  int                   Res;


  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->fd < 0) {
    return EFI_DEVICE_ERROR;
  }

  if (PrivateFile->IsDirectoryPath) {
    return EFI_UNSUPPORTED;
  }

  if (PrivateFile->IsOpenedByRead) {
    return EFI_ACCESS_DENIED;
  }

  Res = write (PrivateFile->fd, Buffer, *BufferSize);
  if (Res == (UINTN)-1) {
    return ErrnoToEfiStatus ();
  }

  *BufferSize = Res;
  return EFI_SUCCESS;
}



/**
  Set a files current position

  @param  This            Protocol instance pointer.
  @param  Position        Byte position from the start of the file.

  @retval EFI_SUCCESS     Data was written.
  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.

**/
EFI_STATUS
PosixFileSetPossition (
  IN EFI_FILE_PROTOCOL        *This,
  IN UINT64                   Position
  )
{
  EMU_EFI_FILE_PRIVATE    *PrivateFile;
  off_t                   Pos;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->IsDirectoryPath) {
    if (Position != 0) {
      return EFI_UNSUPPORTED;
    }

    if (PrivateFile->Dir == NULL) {
      return EFI_DEVICE_ERROR;
    }
    rewinddir (PrivateFile->Dir);
    return EFI_SUCCESS;
  } else {
    if (Position == (UINT64) -1) {
      Pos = lseek (PrivateFile->fd, 0, SEEK_END);
    } else {
      Pos = lseek (PrivateFile->fd, Position, SEEK_SET);
    }
    if (Pos == (off_t)-1) {
      return ErrnoToEfiStatus ();
    }
    return EFI_SUCCESS;
  }
}



/**
  Get a file's current position

  @param  This            Protocol instance pointer.
  @param  Position        Byte position from the start of the file.

  @retval EFI_SUCCESS     Data was written.
  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..

**/
EFI_STATUS
PosixFileGetPossition (
  IN EFI_FILE_PROTOCOL        *This,
  OUT UINT64                  *Position
  )
{
  EFI_STATUS            Status;
  EMU_EFI_FILE_PRIVATE  *PrivateFile;

  PrivateFile   = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->IsDirectoryPath) {
    Status = EFI_UNSUPPORTED;
  } else {
    *Position = (UINT64)lseek (PrivateFile->fd, 0, SEEK_CUR);
    Status = (*Position == (UINT64) -1) ? ErrnoToEfiStatus () : EFI_SUCCESS;
  }

  return Status;
}


/**
  Get information about a file.

  @param  This            Protocol instance pointer.
  @param  InformationType Type of information to return in Buffer.
  @param  BufferSize      On input size of buffer, on output amount of data in buffer.
  @param  Buffer          The buffer to return data.

  @retval EFI_SUCCESS          Data was returned.
  @retval EFI_UNSUPPORTED      InformationType is 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_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.

**/
EFI_STATUS
PosixFileGetInfo (
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN OUT UINTN                *BufferSize,
  OUT VOID                    *Buffer
  )
{
  EFI_STATUS                        Status;
  EMU_EFI_FILE_PRIVATE              *PrivateFile;
  EFI_FILE_SYSTEM_INFO              *FileSystemInfoBuffer;
  int                               UnixStatus;
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *PrivateRoot;
  struct statfs                     buf;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
  PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);

  Status = EFI_SUCCESS;
  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer);
  } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {
      *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
      return EFI_BUFFER_TOO_SMALL;
    }

    UnixStatus = statfs (PrivateFile->FileName, &buf);
    if (UnixStatus < 0) {
      return EFI_DEVICE_ERROR;
    }

    FileSystemInfoBuffer            = (EFI_FILE_SYSTEM_INFO *) Buffer;
    FileSystemInfoBuffer->Size      = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
    FileSystemInfoBuffer->ReadOnly  = FALSE;

    //
    // Succeeded
    //
    FileSystemInfoBuffer->VolumeSize  = MultU64x32 (buf.f_blocks, buf.f_bsize);
    FileSystemInfoBuffer->FreeSpace   = MultU64x32 (buf.f_bavail, buf.f_bsize);
    FileSystemInfoBuffer->BlockSize   = buf.f_bsize;


    StrCpyS (
      (CHAR16 *) FileSystemInfoBuffer->VolumeLabel,
      (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),
      PrivateRoot->VolumeLabel
      );
    *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);

  } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
      *BufferSize = StrSize (PrivateRoot->VolumeLabel);
      return EFI_BUFFER_TOO_SMALL;
    }

    StrCpyS (
      (CHAR16 *) Buffer,
      *BufferSize / sizeof (CHAR16),
      PrivateRoot->VolumeLabel
      );
    *BufferSize = StrSize (PrivateRoot->VolumeLabel);

  }

  return Status;
}


/**
  Set information about a file

  @param  File            Protocol instance pointer.
  @param  InformationType Type of information in Buffer.
  @param  BufferSize      Size of buffer.
  @param  Buffer          The data to write.

  @retval EFI_SUCCESS          Data was returned.
  @retval EFI_UNSUPPORTED      InformationType is 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.

**/
EFI_STATUS
PosixFileSetInfo (
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN UINTN                    BufferSize,
  IN VOID                     *Buffer
  )
{
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *PrivateRoot;
  EMU_EFI_FILE_PRIVATE              *PrivateFile;
  EFI_FILE_INFO                     *OldFileInfo;
  EFI_FILE_INFO                     *NewFileInfo;
  EFI_STATUS                        Status;
  UINTN                             OldInfoSize;
  mode_t                            NewAttr;
  struct stat                       OldAttr;
  CHAR8                             *OldFileName;
  CHAR8                             *NewFileName;
  CHAR8                             *CharPointer;
  BOOLEAN                           AttrChangeFlag;
  BOOLEAN                           NameChangeFlag;
  BOOLEAN                           SizeChangeFlag;
  BOOLEAN                           TimeChangeFlag;
  struct tm                         NewLastAccessSystemTime;
  struct tm                         NewLastWriteSystemTime;
  EFI_FILE_SYSTEM_INFO              *NewFileSystemInfo;
  CHAR8                             *AsciiFilePtr;
  CHAR16                            *UnicodeFilePtr;
  int                               UnixStatus;
  struct utimbuf                    Utime;
  UINTN                             Size;

  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
  PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
  errno       = 0;
  Status      = EFI_UNSUPPORTED;
  OldFileInfo = NewFileInfo = NULL;
  OldFileName = NewFileName = NULL;
  AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;

  //
  // Set file system information.
  //
  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    if (BufferSize < (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel))) {
      Status = EFI_BAD_BUFFER_SIZE;
      goto Done;
    }

    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;

    free (PrivateRoot->VolumeLabel);

    PrivateRoot->VolumeLabel = malloc (StrSize (NewFileSystemInfo->VolumeLabel));
    if (PrivateRoot->VolumeLabel == NULL) {
      goto Done;
    }

    StrCpyS (
      PrivateRoot->VolumeLabel,
      StrSize (NewFileSystemInfo->VolumeLabel) / sizeof (CHAR16),
      NewFileSystemInfo->VolumeLabel
      );

    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // Set volume label information.
  //
  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
      Status = EFI_BAD_BUFFER_SIZE;
      goto Done;
    }

    StrCpyS (
      PrivateRoot->VolumeLabel,
      StrSize (PrivateRoot->VolumeLabel) / sizeof (CHAR16),
      (CHAR16 *) Buffer
      );

    Status = EFI_SUCCESS;
    goto Done;
  }

  if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  if (BufferSize < SIZE_OF_EFI_FILE_INFO) {
    Status = EFI_BAD_BUFFER_SIZE;
    goto Done;
  }

  //
  // Set file/directory information.
  //

  //
  // Check for invalid set file information parameters.
  //
  NewFileInfo = (EFI_FILE_INFO *) Buffer;
  if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||
      (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||
      (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)
      ) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  //
  // Get current file information so we can determine what kind
  // of change request this is.
  //
  OldInfoSize = 0;
  Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  OldFileInfo = malloc (OldInfoSize);
  if (OldFileInfo == NULL) {
    goto Done;
  }

  Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  OldFileName = malloc (AsciiStrSize (PrivateFile->FileName));
  if (OldFileInfo == NULL) {
    goto Done;
  }

  AsciiStrCpyS (
    OldFileName,
    AsciiStrSize (PrivateFile->FileName),
    PrivateFile->FileName
    );

  //
  // Make full pathname from new filename and rootpath.
  //
  if (NewFileInfo->FileName[0] == '\\') {
    Size = AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1;
    NewFileName = malloc (Size);
    if (NewFileName == NULL) {
      goto Done;
    }

    AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath);
    AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);
    UnicodeFilePtr = NewFileInfo->FileName + 1;
    *AsciiFilePtr++ ='/';
  } else {
    Size = AsciiStrLen (PrivateFile->FileName) + 2 + StrLen (NewFileInfo->FileName) + 1;
    NewFileName = malloc (Size);
    if (NewFileName == NULL) {
      goto Done;
    }

    AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath);
    AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);
    if ((AsciiFilePtr[-1] != '/') && (NewFileInfo->FileName[0] != '/')) {
      // make sure there is a / between Root FilePath and NewFileInfo Filename
      AsciiFilePtr[0] = '/';
      AsciiFilePtr[1] = '\0';
      AsciiFilePtr++;
    }
    UnicodeFilePtr = NewFileInfo->FileName;
  }
  // Convert to ascii.
  while (*UnicodeFilePtr) {
    *AsciiFilePtr++ = *UnicodeFilePtr++;
  }
  *AsciiFilePtr = 0;

  //
  // Is there an attribute change request?
  //
  if (NewFileInfo->Attribute != OldFileInfo->Attribute) {
    if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    AttrChangeFlag = TRUE;
  }

  //
  // Is there a name change request?
  // bugbug: - Should really use EFI_UNICODE_COLLATION_PROTOCOL
  //
  if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {
    NameChangeFlag = TRUE;
  }

  //
  // Is there a size change request?
  //
  if (NewFileInfo->FileSize != OldFileInfo->FileSize) {
    SizeChangeFlag = TRUE;
  }

  //
  // Is there a time stamp change request?
  //
  if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&
      CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))
      ) {
    TimeChangeFlag = TRUE;
  } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&
             CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))
             ) {
    TimeChangeFlag = TRUE;
  } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&
             CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))
             ) {
    TimeChangeFlag = TRUE;
  }

  //
  // All done if there are no change requests being made.
  //
  if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {
    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // Set file or directory information.
  //
  if (stat (OldFileName, &OldAttr) != 0) {
    Status = ErrnoToEfiStatus ();
    goto Done;
  }

  //
  // Name change.
  //
  if (NameChangeFlag) {
    //
    // Close the handles first
    //
    if (PrivateFile->IsOpenedByRead) {
      Status = EFI_ACCESS_DENIED;
      goto Done;
    }

    for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {
    }

    if (*CharPointer != 0) {
      Status = EFI_ACCESS_DENIED;
      goto Done;
    }

    UnixStatus = rename (OldFileName, NewFileName);
    if (UnixStatus == 0) {
      //
      // modify file name
      //
      free (PrivateFile->FileName);

      PrivateFile->FileName = malloc (AsciiStrSize (NewFileName));
      if (PrivateFile->FileName == NULL) {
        goto Done;
      }

      AsciiStrCpyS (
        PrivateFile->FileName,
        AsciiStrSize (NewFileName),
        NewFileName
        );
    } else {
      Status    = EFI_DEVICE_ERROR;
      goto Done;
    }
  }

  //
  //  Size change
  //
  if (SizeChangeFlag) {
    if (PrivateFile->IsDirectoryPath) {
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {
      Status = EFI_ACCESS_DENIED;
      goto Done;
    }

    if (ftruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) {
      Status = ErrnoToEfiStatus ();
      goto Done;
    }

  }

  //
  // Time change
  //
  if (TimeChangeFlag) {
    NewLastAccessSystemTime.tm_year    = NewFileInfo->LastAccessTime.Year;
    NewLastAccessSystemTime.tm_mon     = NewFileInfo->LastAccessTime.Month;
    NewLastAccessSystemTime.tm_mday    = NewFileInfo->LastAccessTime.Day;
    NewLastAccessSystemTime.tm_hour    = NewFileInfo->LastAccessTime.Hour;
    NewLastAccessSystemTime.tm_min     = NewFileInfo->LastAccessTime.Minute;
    NewLastAccessSystemTime.tm_sec     = NewFileInfo->LastAccessTime.Second;
    NewLastAccessSystemTime.tm_isdst   = 0;

    Utime.actime = mktime (&NewLastAccessSystemTime);

    NewLastWriteSystemTime.tm_year    = NewFileInfo->ModificationTime.Year;
    NewLastWriteSystemTime.tm_mon     = NewFileInfo->ModificationTime.Month;
    NewLastWriteSystemTime.tm_mday    = NewFileInfo->ModificationTime.Day;
    NewLastWriteSystemTime.tm_hour    = NewFileInfo->ModificationTime.Hour;
    NewLastWriteSystemTime.tm_min     = NewFileInfo->ModificationTime.Minute;
    NewLastWriteSystemTime.tm_sec     = NewFileInfo->ModificationTime.Second;
    NewLastWriteSystemTime.tm_isdst   = 0;

    Utime.modtime = mktime (&NewLastWriteSystemTime);

    if (Utime.actime == (time_t)-1 || Utime.modtime == (time_t)-1) {
      goto Done;
    }

    if (utime (PrivateFile->FileName, &Utime) == -1) {
      Status = ErrnoToEfiStatus ();
      goto Done;
    }
  }

  //
  // No matter about AttrChangeFlag, Attribute must be set.
  // Because operation before may cause attribute change.
  //
  NewAttr = OldAttr.st_mode;

  if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {
    NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH);
  } else {
    NewAttr |= S_IRUSR;
  }

  if (chmod (NewFileName, NewAttr) != 0) {
    Status = ErrnoToEfiStatus ();
  }

Done:
  if (OldFileInfo != NULL) {
    free (OldFileInfo);
  }

  if (OldFileName != NULL) {
    free (OldFileName);
  }

  if (NewFileName != NULL) {
    free (NewFileName);
  }

  return Status;
}


/**
  Flush data back for the file handle.

  @param  This Protocol instance pointer.

  @retval EFI_SUCCESS          Data was written.
  @retval EFI_UNSUPPORTED      Writes to 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
PosixFileFlush (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  EMU_EFI_FILE_PRIVATE     *PrivateFile;


  PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->IsDirectoryPath) {
    return EFI_UNSUPPORTED;
  }

  if (PrivateFile->IsOpenedByRead) {
    return EFI_ACCESS_DENIED;
  }

  if (PrivateFile->fd < 0) {
    return EFI_DEVICE_ERROR;
  }

  if (fsync (PrivateFile->fd) != 0) {
    return ErrnoToEfiStatus ();
  }

  return EFI_SUCCESS;
}



EFI_STATUS
PosixFileSystmeThunkOpen (
  IN  EMU_IO_THUNK_PROTOCOL   *This
  )
{
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE  *Private;
  UINTN                           i;

  if (This->Private != NULL) {
    return EFI_ALREADY_STARTED;
  }

  if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
    return EFI_UNSUPPORTED;
  }

  Private = malloc (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE));
  if (Private == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->FilePath = malloc (StrLen (This->ConfigString) + 1);
  if (Private->FilePath == NULL) {
    free (Private);
    return EFI_OUT_OF_RESOURCES;
  }

  // Convert Unicode to Ascii
  for (i = 0; This->ConfigString[i] != 0; i++) {
    Private->FilePath[i] = This->ConfigString[i];
  }
  Private->FilePath[i] = 0;


  Private->VolumeLabel = malloc (StrSize (L"EFI_EMULATED"));
  if (Private->VolumeLabel == NULL) {
    free (Private->FilePath);
    free (Private);
    return EFI_OUT_OF_RESOURCES;
  }
  StrCpyS (
    Private->VolumeLabel,
    StrSize (L"EFI_EMULATED") / sizeof (CHAR16),
    L"EFI_EMULATED"
    );

  Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
  Private->Thunk     = This;
  CopyMem (&Private->SimpleFileSystem, &gPosixFileSystemProtocol, sizeof (Private->SimpleFileSystem));
  Private->FileHandlesOpen = FALSE;

  This->Interface = &Private->SimpleFileSystem;
  This->Private   = Private;
  return EFI_SUCCESS;
}


EFI_STATUS
PosixFileSystmeThunkClose (
  IN  EMU_IO_THUNK_PROTOCOL   *This
  )
{
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE  *Private;

  if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
    return EFI_UNSUPPORTED;
  }

  Private = This->Private;

  if (Private->FileHandlesOpen) {
    //
    // Close only supported if all the EFI_FILE_HANDLEs have been closed.
    //
    return EFI_NOT_READY;
  }

  if (This->Private != NULL) {
    if (Private->VolumeLabel != NULL) {
      free (Private->VolumeLabel);
    }
    free (This->Private);
    This->Private = NULL;
  }

  return EFI_SUCCESS;
}


EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo = {
  &gEfiSimpleFileSystemProtocolGuid,
  NULL,
  NULL,
  0,
  GasketPosixFileSystmeThunkOpen,
  GasketPosixFileSystmeThunkClose,
  NULL
};


