]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UnixPkg/UnixSimpleFileSystemDxe/UnixSimpleFileSystem.c
UnixPkg: Remove UnixPkg files (It is replaced by EmulatorPkg)
[mirror_edk2.git] / UnixPkg / UnixSimpleFileSystemDxe / UnixSimpleFileSystem.c
diff --git a/UnixPkg/UnixSimpleFileSystemDxe/UnixSimpleFileSystem.c b/UnixPkg/UnixSimpleFileSystemDxe/UnixSimpleFileSystem.c
deleted file mode 100644 (file)
index 0bd1c65..0000000
+++ /dev/null
@@ -1,2193 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  UnixSimpleFileSystem.c\r
-\r
-Abstract:\r
-\r
-  Produce Simple File System abstractions for directories on your PC using Posix APIs.\r
-  The configuration of what devices to mount or emulate comes from UNIX \r
-  environment variables. The variables must be visible to the Microsoft* \r
-  Developer Studio for them to work.\r
-\r
-  * Other names and brands may be claimed as the property of others.\r
-\r
---*/\r
-\r
-#include "UnixSimpleFileSystem.h"\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gUnixSimpleFileSystemDriverBinding = {\r
-  UnixSimpleFileSystemDriverBindingSupported,\r
-  UnixSimpleFileSystemDriverBindingStart,\r
-  UnixSimpleFileSystemDriverBindingStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-\r
-CHAR16 *\r
-EfiStrChr (\r
-  IN CHAR16   *Str,\r
-  IN CHAR16   Chr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Locate the first occurance of a character in a string.\r
-\r
-Arguments:\r
-\r
-  Str - Pointer to NULL terminated unicode string.\r
-  Chr - Character to locate.\r
-\r
-Returns:\r
-\r
-  If Str is NULL, then NULL is returned.\r
-  If Chr is not contained in Str, then NULL is returned.\r
-  If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.\r
-\r
---*/\r
-{\r
-  if (Str == NULL) {\r
-    return Str;\r
-  }\r
-\r
-  while (*Str != '\0' && *Str != Chr) {\r
-    ++Str;\r
-  }\r
-\r
-  return (*Str == Chr) ? Str : NULL;\r
-}\r
-\r
-BOOLEAN\r
-IsZero (\r
-  IN VOID   *Buffer,\r
-  IN UINTN  Length\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Buffer  - TODO: add argument description\r
-  Length  - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TODO: add return values\r
-\r
---*/\r
-{\r
-  if (Buffer == NULL || Length == 0) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (*(UINT8 *) Buffer != 0) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (Length > 1) {\r
-    if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-VOID\r
-CutPrefix (\r
-  IN  CHAR8  *Str,\r
-  IN  UINTN   Count\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Str   - TODO: add argument description\r
-  Count - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TODO: add return values\r
-\r
---*/\r
-{\r
-  CHAR8  *Pointer;\r
-\r
-  if (AsciiStrLen (Str) < Count) {\r
-    ASSERT (0);\r
-  }\r
-\r
-  for (Pointer = Str; *(Pointer + Count); Pointer++) {\r
-    *Pointer = *(Pointer + Count);\r
-  }\r
-\r
-  *Pointer = *(Pointer + Count);\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemDriverBindingSupported (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN  EFI_HANDLE                   ControllerHandle,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Check to see if the driver supports a given controller.\r
-\r
-Arguments:\r
-\r
-  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
-\r
-  ControllerHandle    - EFI handle of the controller to test.\r
-\r
-  RemainingDevicePath - Pointer to remaining portion of a device path.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS         - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver\r
-                        specified by This.\r
-\r
-  EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
-                        the driver specified by This.\r
-\r
-  EFI_ACCESS_DENIED   - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
-                        a different driver or an application that requires exclusive access.\r
-\r
-  EFI_UNSUPPORTED     - The device specified by ControllerHandle and RemainingDevicePath is not supported by the\r
-                        driver specified by This.\r
-\r
---*/\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_UNIX_IO_PROTOCOL  *UnixIo;\r
-\r
-  //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiUnixIoProtocolGuid,\r
-                  (VOID **)&UnixIo,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Make sure GUID is for a File System handle.\r
-  //\r
-  Status = EFI_UNSUPPORTED;\r
-  if (CompareGuid (UnixIo->TypeGuid, &gEfiUnixFileSystemGuid)) {\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Close the I/O Abstraction(s) used to perform the supported test\r
-  //\r
-  gBS->CloseProtocol (\r
-        ControllerHandle,\r
-        &gEfiUnixIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        ControllerHandle\r
-        );\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemDriverBindingStart (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
-  IN  EFI_HANDLE                    ControllerHandle,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Starts a device controller or a bus controller.\r
-\r
-Arguments:\r
-\r
-  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
-\r
-  ControllerHandle    - EFI handle of the controller to start.\r
-\r
-  RemainingDevicePath - Pointer to remaining portion of a device path.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The device or bus controller has been started.\r
-\r
-  EFI_DEVICE_ERROR      - The device could not be started due to a device failure.\r
-\r
-  EFI_OUT_OF_RESOURCES  - The request could not be completed due to lack of resources.\r
-\r
---*/\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_UNIX_IO_PROTOCOL            *UnixIo;\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
-  INTN i;\r
-\r
-  Private = NULL;\r
-\r
-  //\r
-  // Open the IO Abstraction(s) needed\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiUnixIoProtocolGuid,\r
-                  (VOID **)&UnixIo,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Validate GUID\r
-  //\r
-  if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixFileSystemGuid)) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  sizeof (UNIX_SIMPLE_FILE_SYSTEM_PRIVATE),\r
-                  (VOID **)&Private\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  Private->Signature  = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;\r
-  Private->UnixThunk = UnixIo->UnixThunk;\r
-  Private->FilePath   = NULL;\r
-  Private->VolumeLabel = NULL;\r
-\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  StrLen (UnixIo->EnvString) + 1,\r
-                  (VOID **)&Private->FilePath\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  for (i = 0; UnixIo->EnvString[i] != 0; i++)\r
-    Private->FilePath[i] = UnixIo->EnvString[i];\r
-  Private->FilePath[i] = 0;\r
-\r
-  Private->VolumeLabel      = NULL;\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  StrSize (L"EFI_EMULATED"),\r
-                  (VOID **)&Private->VolumeLabel\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  StrCpy (Private->VolumeLabel, L"EFI_EMULATED");\r
-\r
-  Private->SimpleFileSystem.Revision    = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
-  Private->SimpleFileSystem.OpenVolume  = UnixSimpleFileSystemOpenVolume;\r
-\r
-  Private->ControllerNameTable = NULL;\r
-\r
-  AddUnicodeString (\r
-    "eng",\r
-    gUnixSimpleFileSystemComponentName.SupportedLanguages,\r
-    &Private->ControllerNameTable,\r
-    UnixIo->EnvString\r
-    );\r
-\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &ControllerHandle,\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  &Private->SimpleFileSystem,\r
-                  NULL\r
-                  );\r
-\r
-Done:\r
-  if (EFI_ERROR (Status)) {\r
-\r
-    if (Private != NULL) {\r
-\r
-      if (Private->VolumeLabel != NULL)\r
-  gBS->FreePool (Private->VolumeLabel);\r
-      if (Private->FilePath != NULL)\r
-  gBS->FreePool (Private->FilePath);\r
-      FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
-      gBS->FreePool (Private);\r
-    }\r
-\r
-    gBS->CloseProtocol (\r
-          ControllerHandle,\r
-          &gEfiUnixIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          ControllerHandle\r
-          );\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN  EFI_HANDLE                   ControllerHandle,\r
-  IN  UINTN                        NumberOfChildren,\r
-  IN  EFI_HANDLE                   *ChildHandleBuffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This              - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
-\r
-  ControllerHandle  - A handle to the device to be stopped.\r
-\r
-  NumberOfChildren  - The number of child device handles in ChildHandleBuffer.\r
-\r
-  ChildHandleBuffer - An array of child device handles to be freed.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS       - The device has been stopped.\r
-\r
-  EFI_DEVICE_ERROR  - The device could not be stopped due to a device failure.\r
-\r
---*/\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFileSystem;\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
-\r
-  //\r
-  // Get our context back\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  (VOID **)&SimpleFileSystem,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Private = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);\r
-\r
-  //\r
-  // Uninstall the Simple File System Protocol from ControllerHandle\r
-  //\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  ControllerHandle,\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  &Private->SimpleFileSystem,\r
-                  NULL\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = gBS->CloseProtocol (\r
-                    ControllerHandle,\r
-                    &gEfiUnixIoProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    ControllerHandle\r
-                    );\r
-  }\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Free our instance data\r
-    //\r
-    FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
-    gBS->FreePool (Private);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemOpenVolume (\r
-  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,\r
-  OUT EFI_FILE_PROTOCOL               **Root\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Open the root directory on a volume.\r
-\r
-Arguments:\r
-\r
-  This  - A pointer to the volume to open.\r
-\r
-  Root  - A pointer to storage for the returned opened file handle of the root directory.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The volume was opened.\r
-\r
-  EFI_UNSUPPORTED       - The volume does not support the requested file system type.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
-\r
-  EFI_ACCESS_DENIED     - The service denied access to the file.\r
-\r
-  EFI_OUT_OF_RESOURCES  - The file volume could not be opened due to lack of resources.\r
-\r
-  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_STATUS                        Status;\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
-  UNIX_EFI_FILE_PRIVATE           *PrivateFile;\r
-  EFI_TPL                           OldTpl;\r
-\r
-  if (This == NULL || Root == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  Private     = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  PrivateFile = NULL;\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  sizeof (UNIX_EFI_FILE_PRIVATE),\r
-                  (VOID **)&PrivateFile\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  PrivateFile->FileName = NULL;\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  AsciiStrSize (Private->FilePath),\r
-                  (VOID **)&PrivateFile->FileName\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  AsciiStrCpy (PrivateFile->FileName, Private->FilePath);\r
-  PrivateFile->Signature            = UNIX_EFI_FILE_PRIVATE_SIGNATURE;\r
-  PrivateFile->UnixThunk           = Private->UnixThunk;\r
-  PrivateFile->SimpleFileSystem     = This;\r
-  PrivateFile->IsRootDirectory      = TRUE;\r
-  PrivateFile->IsDirectoryPath      = TRUE;\r
-  PrivateFile->IsOpenedByRead       = TRUE;\r
-  PrivateFile->EfiFile.Revision     = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
-  PrivateFile->EfiFile.Open         = UnixSimpleFileSystemOpen;\r
-  PrivateFile->EfiFile.Close        = UnixSimpleFileSystemClose;\r
-  PrivateFile->EfiFile.Delete       = UnixSimpleFileSystemDelete;\r
-  PrivateFile->EfiFile.Read         = UnixSimpleFileSystemRead;\r
-  PrivateFile->EfiFile.Write        = UnixSimpleFileSystemWrite;\r
-  PrivateFile->EfiFile.GetPosition  = UnixSimpleFileSystemGetPosition;\r
-  PrivateFile->EfiFile.SetPosition  = UnixSimpleFileSystemSetPosition;\r
-  PrivateFile->EfiFile.GetInfo      = UnixSimpleFileSystemGetInfo;\r
-  PrivateFile->EfiFile.SetInfo      = UnixSimpleFileSystemSetInfo;\r
-  PrivateFile->EfiFile.Flush        = UnixSimpleFileSystemFlush;\r
-  PrivateFile->fd                   = -1;\r
-  PrivateFile->Dir                  = NULL;\r
-  PrivateFile->Dirent               = NULL;\r
-  \r
-  *Root = &PrivateFile->EfiFile;\r
-\r
-  PrivateFile->Dir = PrivateFile->UnixThunk->OpenDir(PrivateFile->FileName);\r
-\r
-  if (PrivateFile->Dir == NULL) {\r
-    Status = EFI_ACCESS_DENIED;\r
-  }\r
-  else {\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-Done:\r
-  if (EFI_ERROR (Status)) {\r
-    if (PrivateFile) {\r
-      if (PrivateFile->FileName) {\r
-        gBS->FreePool (PrivateFile->FileName);\r
-      }\r
-\r
-      gBS->FreePool (PrivateFile);\r
-    }\r
-    \r
-    *Root = NULL;\r
-  }\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemOpen (\r
-  IN  EFI_FILE_PROTOCOL   *This,\r
-  OUT EFI_FILE_PROTOCOL   **NewHandle,\r
-  IN  CHAR16              *FileName,\r
-  IN  UINT64              OpenMode,\r
-  IN  UINT64              Attributes\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Open a file relative to the source file location.\r
-\r
-Arguments:\r
-\r
-  This        - A pointer to the source file location.\r
-\r
-  NewHandle   - Pointer to storage for the new file handle.\r
-\r
-  FileName    - Pointer to the file name to be opened.\r
-\r
-  OpenMode    - File open mode information.\r
-\r
-  Attributes  - File creation attributes.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The file was opened.\r
-\r
-  EFI_NOT_FOUND         - The file could not be found in the volume.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
-\r
-  EFI_WRITE_PROTECTED   - The volume or file is write protected.\r
-\r
-  EFI_ACCESS_DENIED     - The service denied access to the file.\r
-\r
-  EFI_OUT_OF_RESOURCES  - Not enough resources were available to open the file.\r
-\r
-  EFI_VOLUME_FULL       - There is not enough space left to create the new file.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_FILE_PROTOCOL                 *Root;\r
-  UNIX_EFI_FILE_PRIVATE           *PrivateFile;\r
-  UNIX_EFI_FILE_PRIVATE           *NewPrivateFile;\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
-  EFI_STATUS                        Status;\r
-  CHAR16                            *Src;\r
-  char                              *Dst;\r
-  CHAR8                             *RealFileName;\r
-  char                              *ParseFileName;\r
-  char                              *GuardPointer;\r
-  CHAR8                             TempChar;\r
-  UINTN                             Count;\r
-  BOOLEAN                           TrailingDash;\r
-  BOOLEAN                           LoopFinish;\r
-  UINTN                             InfoSize;\r
-  EFI_FILE_INFO                     *Info;\r
-\r
-  TrailingDash = FALSE;\r
-\r
-  //\r
-  // Check for obvious invalid parameters.\r
-  //\r
-  if (This == NULL || NewHandle == NULL || FileName == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  switch (OpenMode) {\r
-  case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
-    if (Attributes &~EFI_FILE_VALID_ATTR) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (Attributes & EFI_FILE_READ_ONLY) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-  //\r
-  // fall through\r
-  //\r
-  case EFI_FILE_MODE_READ:\r
-  case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
-    break;\r
-\r
-  default:\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-\r
-  PrivateFile     = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-  PrivateRoot     = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
-  NewPrivateFile  = NULL;\r
-\r
-  //\r
-  // BUGBUG: assume an open of root\r
-  // if current location, return current data\r
-  //\r
-  if (StrCmp (FileName, L"\\") == 0\r
-      || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {\r
-    //\r
-    // BUGBUG: assume an open root\r
-    //\r
-OpenRoot:\r
-    Status          = UnixSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);\r
-    NewPrivateFile  = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);\r
-    goto Done;\r
-  }\r
-\r
-  if (FileName[StrLen (FileName) - 1] == L'\\') {\r
-    TrailingDash                        = TRUE;\r
-    FileName[StrLen (FileName) - 1]  = 0;\r
-  }\r
-\r
-  //\r
-  // Attempt to open the file\r
-  //\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  sizeof (UNIX_EFI_FILE_PRIVATE),\r
-                  (VOID **)&NewPrivateFile\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  CopyMem (NewPrivateFile, PrivateFile, sizeof (UNIX_EFI_FILE_PRIVATE));\r
-\r
-  NewPrivateFile->FileName = NULL;\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1,\r
-                  (VOID **)&NewPrivateFile->FileName\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  if (*FileName == L'\\') {\r
-    AsciiStrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);\r
-    // Skip first '\'.\r
-    Src = FileName + 1;\r
-  } else {\r
-    AsciiStrCpy (NewPrivateFile->FileName, PrivateFile->FileName);\r
-    Src = FileName;\r
-  }\r
-  Dst = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName);\r
-  GuardPointer = NewPrivateFile->FileName + AsciiStrLen(PrivateRoot->FilePath);\r
-  *Dst++ = '/';\r
-  // Convert unicode to ascii and '\' to '/'\r
-  while (*Src) {\r
-    if (*Src == '\\')\r
-      *Dst++ = '/';\r
-    else\r
-      *Dst++ = *Src;\r
-    Src++;\r
-  }\r
-  *Dst = 0;\r
-      \r
-\r
-  //\r
-  // Get rid of . and .., except leading . or ..\r
-  //\r
-\r
-  //\r
-  // GuardPointer protect simplefilesystem root path not be destroyed\r
-  //\r
-\r
-  LoopFinish    = FALSE;\r
-\r
-  while (!LoopFinish) {\r
-\r
-    LoopFinish = TRUE;\r
-\r
-    for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {\r
-      if (*ParseFileName == '.' &&\r
-          (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == '/') &&\r
-          *(ParseFileName - 1) == '/'\r
-          ) {\r
-\r
-        //\r
-        // cut /.\r
-        //\r
-        CutPrefix (ParseFileName - 1, 2);\r
-        LoopFinish = FALSE;\r
-        break;\r
-      }\r
-\r
-      if (*ParseFileName == '.' &&\r
-          *(ParseFileName + 1) == '.' &&\r
-          (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == '/') &&\r
-          *(ParseFileName - 1) == '/'\r
-          ) {\r
-\r
-        ParseFileName--;\r
-        Count = 3;\r
-\r
-        while (ParseFileName != GuardPointer) {\r
-          ParseFileName--;\r
-          Count++;\r
-          if (*ParseFileName == '/') {\r
-            break;\r
-          }\r
-        }\r
-\r
-        //\r
-        // cut /.. and its left directory\r
-        //\r
-        CutPrefix (ParseFileName, Count);\r
-        LoopFinish = FALSE;\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
-    NewPrivateFile->IsRootDirectory = TRUE;\r
-    gBS->FreePool (NewPrivateFile->FileName);\r
-    gBS->FreePool (NewPrivateFile);\r
-    goto OpenRoot;\r
-  }\r
-\r
-  RealFileName = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName) - 1;\r
-  while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/')\r
-    RealFileName--;\r
-\r
-  TempChar            = *(RealFileName - 1);\r
-  *(RealFileName - 1) = 0;\r
-\r
-  *(RealFileName - 1)             = TempChar;\r
-\r
-\r
-\r
-  //\r
-  // Test whether file or directory\r
-  //\r
-  NewPrivateFile->IsRootDirectory = FALSE;\r
-  NewPrivateFile->fd = -1;\r
-  NewPrivateFile->Dir = NULL;\r
-  if (OpenMode & EFI_FILE_MODE_CREATE) {\r
-    if (Attributes & EFI_FILE_DIRECTORY) {\r
-      NewPrivateFile->IsDirectoryPath = TRUE;\r
-    } else {\r
-      NewPrivateFile->IsDirectoryPath = FALSE;\r
-    }\r
-  } else {\r
-    STAT_FIX finfo;\r
-    int res = NewPrivateFile->UnixThunk->Stat (NewPrivateFile->FileName, &finfo);\r
-    if (res == 0 && S_ISDIR(finfo.st_mode))\r
-      NewPrivateFile->IsDirectoryPath = TRUE;\r
-    else\r
-      NewPrivateFile->IsDirectoryPath = FALSE;\r
-  }\r
-\r
-  if (OpenMode & EFI_FILE_MODE_WRITE) {\r
-    NewPrivateFile->IsOpenedByRead = FALSE;\r
-  } else {\r
-    NewPrivateFile->IsOpenedByRead = TRUE;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // deal with directory\r
-  //\r
-  if (NewPrivateFile->IsDirectoryPath) {\r
-\r
-    if ((OpenMode & EFI_FILE_MODE_CREATE)) {\r
-      //\r
-      // Create a directory\r
-      //\r
-      if (NewPrivateFile->UnixThunk->MkDir (NewPrivateFile->FileName, 0777) != 0) {\r
-  INTN LastError;\r
-\r
-        LastError = PrivateFile->UnixThunk->GetErrno ();\r
-        if (LastError != EEXIST) {\r
-          //gBS->FreePool (TempFileName);\r
-          Status = EFI_ACCESS_DENIED;\r
-          goto Done;\r
-        }\r
-      }\r
-    }\r
-\r
-    NewPrivateFile->Dir = NewPrivateFile->UnixThunk->OpenDir\r
-      (NewPrivateFile->FileName);\r
-\r
-    if (NewPrivateFile->Dir == NULL) {\r
-      if (PrivateFile->UnixThunk->GetErrno () == EACCES) {\r
-        Status                    = EFI_ACCESS_DENIED;\r
-      } else {\r
-        Status = EFI_NOT_FOUND;\r
-      }\r
-\r
-      goto Done;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // deal with file\r
-    //\r
-    NewPrivateFile->fd = NewPrivateFile->UnixThunk->Open\r
-      (NewPrivateFile->FileName,\r
-       ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0)\r
-       | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR),\r
-       0666);\r
-    if (NewPrivateFile->fd < 0) {\r
-      if (PrivateFile->UnixThunk->GetErrno () == ENOENT) {\r
-  Status = EFI_NOT_FOUND;\r
-      } else {\r
-  Status = EFI_ACCESS_DENIED;\r
-      }\r
-    }\r
-  }\r
-\r
-  if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {\r
-    //\r
-    // Set the attribute\r
-    //\r
-    InfoSize  = 0;\r
-    Info      = NULL;\r
-\r
-    Status    = UnixSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
-\r
-    if (Status != EFI_BUFFER_TOO_SMALL) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-\r
-    Status = gBS->AllocatePool (\r
-                    EfiBootServicesData,\r
-                    InfoSize,\r
-                    (VOID **)&Info\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    Status = UnixSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    Info->Attribute = Attributes;\r
-\r
-    UnixSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);\r
-  }\r
-\r
-Done: ;\r
-  if (TrailingDash) {\r
-    FileName[StrLen (FileName) + 1]  = 0;\r
-    FileName[StrLen (FileName)]      = L'\\';\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (NewPrivateFile) {\r
-      if (NewPrivateFile->FileName) {\r
-        gBS->FreePool (NewPrivateFile->FileName);\r
-      }\r
-\r
-      gBS->FreePool (NewPrivateFile);\r
-    }\r
-  } else {\r
-    *NewHandle = &NewPrivateFile->EfiFile;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemClose (\r
-  IN EFI_FILE_PROTOCOL  *This\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Close the specified file handle.\r
-\r
-Arguments:\r
-\r
-  This  - Pointer to a returned opened file handle.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - The file handle has been closed.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  UNIX_EFI_FILE_PRIVATE *PrivateFile;\r
-  EFI_TPL                OldTpl;\r
-\r
-  if (This == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  if (PrivateFile->fd >= 0) {\r
-    PrivateFile->UnixThunk->Close (PrivateFile->fd);\r
-  }\r
-  if (PrivateFile->Dir != NULL) {\r
-    PrivateFile->UnixThunk->CloseDir (PrivateFile->Dir);\r
-  }\r
-\r
-  PrivateFile->fd = -1;\r
-  PrivateFile->Dir = NULL;\r
-\r
-  if (PrivateFile->FileName) {\r
-    gBS->FreePool (PrivateFile->FileName);\r
-  }\r
-\r
-  gBS->FreePool (PrivateFile);\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-  \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemDelete (\r
-  IN EFI_FILE_PROTOCOL  *This\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Close and delete a file.\r
-\r
-Arguments:\r
-\r
-  This  - Pointer to a returned opened file handle.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS             - The file handle was closed and deleted.\r
-\r
-  EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_STATUS              Status;\r
-  UNIX_EFI_FILE_PRIVATE   *PrivateFile;\r
-  EFI_TPL                 OldTpl;\r
-\r
-  if (This == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  Status      = EFI_WARN_DELETE_FAILURE;\r
-\r
-  if (PrivateFile->IsDirectoryPath) {\r
-    if (PrivateFile->Dir != NULL) {\r
-      PrivateFile->UnixThunk->CloseDir (PrivateFile->Dir);\r
-      PrivateFile->Dir = NULL;\r
-    }\r
-\r
-    if (PrivateFile->UnixThunk->RmDir (PrivateFile->FileName) == 0) {\r
-      Status = EFI_SUCCESS;\r
-    }\r
-  } else {\r
-    PrivateFile->UnixThunk->Close (PrivateFile->fd);\r
-    PrivateFile->fd = -1;\r
-\r
-    if (!PrivateFile->IsOpenedByRead) {\r
-      if (!PrivateFile->UnixThunk->UnLink (PrivateFile->FileName)) {\r
-        Status = EFI_SUCCESS;\r
-      }\r
-    }\r
-  }\r
-\r
-  gBS->FreePool (PrivateFile->FileName);\r
-  gBS->FreePool (PrivateFile);\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-}\r
-\r
-VOID\r
-UnixSystemTimeToEfiTime (\r
-  EFI_UNIX_THUNK_PROTOCOL        *UnixThunk,\r
-  IN time_t                 SystemTime,\r
-  OUT EFI_TIME              *Time\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  SystemTime  - TODO: add argument description\r
-  TimeZone    - TODO: add argument description\r
-  Time        - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TODO: add return values\r
-\r
---*/\r
-{\r
-  struct tm *tm;\r
-  tm = UnixThunk->GmTime (&SystemTime);\r
-  Time->Year   = tm->tm_year;\r
-  Time->Month  = tm->tm_mon + 1;\r
-  Time->Day    = tm->tm_mday;\r
-  Time->Hour   = tm->tm_hour;\r
-  Time->Minute = tm->tm_min;\r
-  Time->Second = tm->tm_sec;\r
-  Time->Nanosecond  = 0;\r
-\r
-  Time->TimeZone    = UnixThunk->GetTimeZone ();\r
-\r
-  if (UnixThunk->GetDayLight ()) {\r
-    Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;\r
-  }\r
-}\r
-\r
-EFI_STATUS\r
-UnixSimpleFileSystemFileInfo (\r
-  UNIX_EFI_FILE_PRIVATE          *PrivateFile,\r
-  IN     CHAR8                    *FileName,\r
-  IN OUT UINTN                    *BufferSize,\r
-  OUT    VOID                     *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  PrivateFile - TODO: add argument description\r
-  BufferSize  - TODO: add argument description\r
-  Buffer      - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TODO: add return values\r
-\r
---*/\r
-{\r
-  EFI_STATUS                  Status;\r
-  UINTN                       Size;\r
-  UINTN                       NameSize;\r
-  UINTN                       ResultSize;\r
-  EFI_FILE_INFO               *Info;\r
-  CHAR8                       *RealFileName;\r
-  CHAR8                       *TempPointer;\r
-  CHAR16                      *BufferFileName;\r
-  STAT_FIX                    buf;\r
-\r
-  if (FileName != NULL) {\r
-    RealFileName = FileName;\r
-  }\r
-  else if (PrivateFile->IsRootDirectory) {\r
-    RealFileName = "";\r
-  } else {\r
-    RealFileName  = PrivateFile->FileName;\r
-  }\r
-\r
-  TempPointer   = RealFileName;\r
-  while (*TempPointer) {\r
-    if (*TempPointer == '/') {\r
-      RealFileName = TempPointer + 1;\r
-    }\r
-\r
-    TempPointer++;\r
-  }\r
-\r
-  Size        = SIZE_OF_EFI_FILE_INFO;\r
-  NameSize    = AsciiStrSize (RealFileName) * 2;\r
-  ResultSize  = Size + NameSize;\r
-\r
-  if (*BufferSize < ResultSize) {\r
-    *BufferSize = ResultSize;\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-  if (PrivateFile->UnixThunk->Stat (\r
-          FileName == NULL ? PrivateFile->FileName : FileName,\r
-    &buf) < 0)\r
-    return EFI_DEVICE_ERROR;\r
-\r
-  Status  = EFI_SUCCESS;\r
-\r
-  Info    = Buffer;\r
-  ZeroMem (Info, ResultSize);\r
-\r
-  Info->Size = ResultSize;\r
-  Info->FileSize      = buf.st_size;\r
-  Info->PhysicalSize  = MultU64x32 (buf.st_blocks, buf.st_blksize);\r
-\r
-  UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_ctime, &Info->CreateTime);\r
-  UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_atime, &Info->LastAccessTime);\r
-  UnixSystemTimeToEfiTime (PrivateFile->UnixThunk, buf.st_mtime, &Info->ModificationTime);\r
-\r
-  if (!(buf.st_mode & S_IWUSR)) {\r
-    Info->Attribute |= EFI_FILE_READ_ONLY;\r
-  }\r
-\r
-  if (S_ISDIR(buf.st_mode)) {\r
-    Info->Attribute |= EFI_FILE_DIRECTORY;\r
-  }\r
-\r
-\r
-  BufferFileName = (CHAR16 *)((CHAR8 *) Buffer + Size);\r
-  while (*RealFileName)\r
-    *BufferFileName++ = *RealFileName++;\r
-  *BufferFileName = 0;\r
-\r
-  *BufferSize = ResultSize;\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemRead (\r
-  IN     EFI_FILE_PROTOCOL  *This,\r
-  IN OUT UINTN              *BufferSize,\r
-  OUT    VOID               *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read data from a file.\r
-\r
-Arguments:\r
-\r
-  This        - Pointer to a returned open file handle.\r
-\r
-  BufferSize  - On input, the size of the Buffer.  On output, the number of bytes stored in the Buffer.\r
-\r
-  Buffer      - Pointer to the first byte of the read Buffer.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The data was read.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
-\r
-  EFI_BUFFER_TOO_SMALL  - The supplied buffer size was too small to store the current directory entry.\r
-                          *BufferSize has been updated with the size needed to complete the request.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  UNIX_EFI_FILE_PRIVATE *PrivateFile;\r
-  EFI_STATUS              Status;\r
-  INTN                    Res;\r
-  UINTN                   Size;\r
-  UINTN                   NameSize;\r
-  UINTN                   ResultSize;\r
-  CHAR8                   *FullFileName;\r
-  EFI_TPL                 OldTpl;\r
-\r
-  if (This == NULL || BufferSize == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  if ((*BufferSize != 0) && (Buffer == NULL)) {\r
-    // Buffer can be NULL  if *BufferSize is zero\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  if (!PrivateFile->IsDirectoryPath) {\r
-\r
-    if (PrivateFile->fd < 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-\r
-    Res = PrivateFile->UnixThunk->Read (\r
-           PrivateFile->fd,\r
-           Buffer,\r
-           *BufferSize);\r
-    if (Res < 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-    *BufferSize = Res;\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Read on a directory.\r
-  //\r
-  if (PrivateFile->Dir == NULL) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  if (PrivateFile->Dirent == NULL) {\r
-    PrivateFile->Dirent = PrivateFile->UnixThunk->ReadDir (PrivateFile->Dir);\r
-    if (PrivateFile->Dirent == NULL) {\r
-      *BufferSize = 0;\r
-      Status = EFI_SUCCESS;\r
-      goto Done;\r
-    }\r
-  }\r
-\r
-  Size        = SIZE_OF_EFI_FILE_INFO;\r
-  NameSize    = AsciiStrLen (PrivateFile->Dirent->d_name) + 1;\r
-  ResultSize  = Size + 2 * NameSize;\r
-\r
-  if (*BufferSize < ResultSize) {\r
-    *BufferSize = ResultSize;\r
-    Status = EFI_BUFFER_TOO_SMALL;\r
-    goto Done;\r
-  }\r
-  Status  = EFI_SUCCESS;\r
-\r
-  *BufferSize = ResultSize;\r
-\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  AsciiStrLen(PrivateFile->FileName) + 1 + NameSize,\r
-                  (VOID **)&FullFileName\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-      \r
-  AsciiStrCpy(FullFileName, PrivateFile->FileName);\r
-  AsciiStrCat(FullFileName, "/");\r
-  AsciiStrCat(FullFileName, PrivateFile->Dirent->d_name);\r
-  Status = UnixSimpleFileSystemFileInfo (PrivateFile,\r
-            FullFileName,\r
-            BufferSize,\r
-            Buffer);\r
-  gBS->FreePool (FullFileName);\r
-\r
-  PrivateFile->Dirent = NULL;\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemWrite (\r
-  IN     EFI_FILE_PROTOCOL  *This,\r
-  IN OUT UINTN              *BufferSize,\r
-  IN     VOID               *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Write data to a file.\r
-\r
-Arguments:\r
-\r
-  This        - Pointer to an opened file handle.\r
-\r
-  BufferSize  - On input, the number of bytes in the Buffer to write to the file.  On output, the number of bytes\r
-                of data written to the file.\r
-\r
-  Buffer      - Pointer to the first by of data in the buffer to write to the file.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The data was written to the file.\r
-\r
-  EFI_UNSUPPORTED       - Writes to an open directory are not supported.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
-\r
-  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
-\r
-  EFI_ACCESS_DENIED     - The file was opened read-only.\r
-\r
-  EFI_VOLUME_FULL       - The volume is full.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  UNIX_EFI_FILE_PRIVATE *PrivateFile;\r
-  UINTN                 Res;\r
-  EFI_STATUS            Status;\r
-  EFI_TPL               OldTpl;\r
-\r
-  if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  if (PrivateFile->fd < 0) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (PrivateFile->IsDirectoryPath) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if (PrivateFile->IsOpenedByRead) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-\r
-  Res = PrivateFile->UnixThunk->Write (\r
-          PrivateFile->fd,\r
-          Buffer,\r
-          *BufferSize);\r
-  if (Res == (UINTN)-1) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-  *BufferSize = Res;\r
-  Status = EFI_SUCCESS;\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-\r
-  //\r
-  // bugbug: need to access unix error reporting\r
-  //\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemSetPosition (\r
-  IN EFI_FILE_PROTOCOL  *This,\r
-  IN UINT64             Position\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set a file's current position.\r
-\r
-Arguments:\r
-\r
-  This      - Pointer to an opened file handle.\r
-\r
-  Position  - The byte position from the start of the file to set.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS     - The file position has been changed.\r
-\r
-  EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_STATUS              Status;\r
-  UNIX_EFI_FILE_PRIVATE *PrivateFile;\r
-  UINT64                  Pos;\r
-  EFI_TPL                 OldTpl;\r
-\r
-  if (This == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  if (PrivateFile->IsDirectoryPath) {\r
-    if (Position != 0) {\r
-      Status = EFI_UNSUPPORTED;\r
-      goto Done;\r
-    }\r
-\r
-    if (PrivateFile->Dir == NULL) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-    PrivateFile->UnixThunk->RewindDir (PrivateFile->Dir);\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  } else {\r
-    if (Position == (UINT64) -1) {\r
-      Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_END);\r
-    } else {\r
-      Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, Position, SEEK_SET);\r
-    }\r
-    Status = (Pos == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
-  }\r
-\r
-Done:\r
-    gBS->RestoreTPL (OldTpl);\r
-    return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemGetPosition (\r
-  IN  EFI_FILE_PROTOCOL   *This,\r
-  OUT UINT64              *Position\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get a file's current position.\r
-\r
-Arguments:\r
-\r
-  This      - Pointer to an opened file handle.\r
-\r
-  Position  - Pointer to storage for the current position.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS     - The file position has been reported.\r
-\r
-  EFI_UNSUPPORTED - Not valid for directories.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_STATUS            Status;\r
-  UNIX_EFI_FILE_PRIVATE *PrivateFile;\r
-  EFI_TPL               OldTpl;\r
-\r
-  if (This == NULL || Position == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  PrivateFile   = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  if (PrivateFile->IsDirectoryPath) {\r
-    Status = EFI_UNSUPPORTED;\r
-  } else {\r
-    *Position = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_CUR);\r
-    Status = (*Position == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
-  }\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemGetInfo (\r
-  IN     EFI_FILE_PROTOCOL  *This,\r
-  IN     EFI_GUID           *InformationType,\r
-  IN OUT UINTN              *BufferSize,\r
-  OUT    VOID               *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Return information about a file or volume.\r
-\r
-Arguments:\r
-\r
-  This            - Pointer to an opened file handle.\r
-\r
-  InformationType - GUID describing the type of information to be returned.\r
-\r
-  BufferSize      - On input, the size of the information buffer.  On output, the number of bytes written to the\r
-                    information buffer.\r
-\r
-  Buffer          - Pointer to the first byte of the information buffer.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The requested information has been written into the buffer.\r
-\r
-  EFI_UNSUPPORTED       - The InformationType is not known.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
-\r
-  EFI_BUFFER_TOO_SMALL  - The buffer size was too small to contain the requested information.  The buffer size has\r
-                          been updated with the size needed to complete the requested operation.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  EFI_STATUS                        Status;\r
-  UNIX_EFI_FILE_PRIVATE           *PrivateFile;\r
-  EFI_FILE_SYSTEM_INFO              *FileSystemInfoBuffer;\r
-  INTN                              UnixStatus;\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
-  struct statfs                     buf;\r
-  EFI_TPL                           OldTpl;\r
-\r
-  if (This == NULL || InformationType == NULL || BufferSize == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-    \r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-  PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
-\r
-  Status      = EFI_UNSUPPORTED;\r
-\r
-  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
-    Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer);\r
-  } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
-    if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
-      *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-      goto Done;\r
-    }\r
-\r
-    UnixStatus = PrivateFile->UnixThunk->StatFs (PrivateFile->FileName, &buf);\r
-    if (UnixStatus < 0) {\r
-        Status = EFI_DEVICE_ERROR;\r
-        goto Done;\r
-    }\r
-\r
-    FileSystemInfoBuffer            = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
-    FileSystemInfoBuffer->Size      = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
-    FileSystemInfoBuffer->ReadOnly  = FALSE;\r
-\r
-    //\r
-    // Succeeded\r
-    //\r
-    FileSystemInfoBuffer->VolumeSize  = MultU64x32 (buf.f_blocks, buf.f_bsize);\r
-    FileSystemInfoBuffer->FreeSpace   = MultU64x32 (buf.f_bavail, buf.f_bsize);\r
-    FileSystemInfoBuffer->BlockSize   = buf.f_bsize;\r
-\r
-\r
-    StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel);\r
-    *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
-    Status      = EFI_SUCCESS;\r
-  } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
-    if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
-      *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-      goto Done;\r
-    }\r
-\r
-    StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel);\r
-    *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
-    Status      = EFI_SUCCESS;\r
-  }\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemSetInfo (\r
-  IN EFI_FILE_PROTOCOL*This,\r
-  IN EFI_GUID         *InformationType,\r
-  IN UINTN            BufferSize,\r
-  IN VOID             *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set information about a file or volume.\r
-\r
-Arguments:\r
-\r
-  This            - Pointer to an opened file handle.\r
-\r
-  InformationType - GUID identifying the type of information to set.\r
-\r
-  BufferSize      - Number of bytes of data in the information buffer.\r
-\r
-  Buffer          - Pointer to the first byte of data in the information buffer.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The file or volume information has been updated.\r
-\r
-  EFI_UNSUPPORTED       - The information identifier is not recognised.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
-\r
-  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
-\r
-  EFI_ACCESS_DENIED     - The file was opened read-only.\r
-\r
-  EFI_VOLUME_FULL       - The volume is full.\r
-\r
-  EFI_BAD_BUFFER_SIZE   - The buffer size is smaller than the type indicated by InformationType.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
-  UNIX_EFI_FILE_PRIVATE           *PrivateFile;\r
-  EFI_FILE_INFO                     *OldFileInfo;\r
-  EFI_FILE_INFO                     *NewFileInfo;\r
-  EFI_STATUS                        Status;\r
-  UINTN                             OldInfoSize;\r
-  EFI_TPL                           OldTpl;\r
-  mode_t                            NewAttr;\r
-  STAT_FIX                          OldAttr;\r
-  CHAR8                             *OldFileName;\r
-  CHAR8                             *NewFileName;\r
-  CHAR8                             *CharPointer;\r
-  BOOLEAN                           AttrChangeFlag;\r
-  BOOLEAN                           NameChangeFlag;\r
-  BOOLEAN                           SizeChangeFlag;\r
-  BOOLEAN                           TimeChangeFlag;\r
-  struct tm                         NewLastAccessSystemTime;\r
-  struct tm                         NewLastWriteSystemTime;\r
-  EFI_FILE_SYSTEM_INFO              *NewFileSystemInfo;\r
-  CHAR8                             *AsciiFilePtr;\r
-  CHAR16                            *UnicodeFilePtr;\r
-  INTN                              UnixStatus;\r
-\r
-  //\r
-  // Check for invalid parameters.\r
-  //\r
-  if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  //\r
-  // Initialise locals.\r
-  //\r
-  PrivateFile               = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-  PrivateRoot               = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
-\r
-  Status                    = EFI_UNSUPPORTED;\r
-  OldFileInfo               = NewFileInfo = NULL;\r
-  OldFileName               = NewFileName = NULL;\r
-  AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;\r
-\r
-  //\r
-  // Set file system information.\r
-  //\r
-  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
-    if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
-      Status = EFI_BAD_BUFFER_SIZE;\r
-      goto Done;\r
-    }\r
-\r
-    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
-\r
-    gBS->FreePool (PrivateRoot->VolumeLabel);\r
-\r
-    PrivateRoot->VolumeLabel = NULL;\r
-    Status = gBS->AllocatePool (\r
-                    EfiBootServicesData,\r
-                    StrSize (NewFileSystemInfo->VolumeLabel),\r
-                    (VOID **)&PrivateRoot->VolumeLabel\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel);\r
-\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Set volume label information.\r
-  //\r
-  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
-    if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
-      Status = EFI_BAD_BUFFER_SIZE;\r
-      goto Done;\r
-    }\r
-\r
-    StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer);\r
-\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
-\r
-  if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-\r
-  if (BufferSize < SIZE_OF_EFI_FILE_INFO) {\r
-    Status = EFI_BAD_BUFFER_SIZE;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Set file/directory information.\r
-  //\r
-\r
-  //\r
-  // Check for invalid set file information parameters.\r
-  //\r
-  NewFileInfo = (EFI_FILE_INFO *) Buffer;\r
-\r
-  if ((NewFileInfo->Size <= SIZE_OF_EFI_FILE_INFO) ||\r
-      (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||\r
-      (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)\r
-      ) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // bugbug: - This is not safe.  We need something like EfiStrMaxSize()\r
-  // that would have an additional parameter that would be the size\r
-  // of the string array just in case there are no NULL characters in\r
-  // the string array.\r
-  //\r
-  //\r
-  // Get current file information so we can determine what kind\r
-  // of change request this is.\r
-  //\r
-  OldInfoSize = 0;\r
-  Status      = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL);\r
-\r
-  if (Status != EFI_BUFFER_TOO_SMALL) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  Status = gBS->AllocatePool (EfiBootServicesData, OldInfoSize,\r
-            (VOID **)&OldFileInfo);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  AsciiStrSize (PrivateFile->FileName),\r
-                  (VOID **)&OldFileName\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  AsciiStrCpy (OldFileName, PrivateFile->FileName);\r
-\r
-  //\r
-  // Make full pathname from new filename and rootpath.\r
-  //\r
-  if (NewFileInfo->FileName[0] == '\\') {\r
-    Status = gBS->AllocatePool (\r
-                    EfiBootServicesData,\r
-                    AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1,\r
-                    (VOID **)&NewFileName\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    AsciiStrCpy (NewFileName, PrivateRoot->FilePath);\r
-    AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);\r
-    UnicodeFilePtr = NewFileInfo->FileName + 1;\r
-    *AsciiFilePtr++ ='/';\r
-  } else {\r
-    Status = gBS->AllocatePool (\r
-                    EfiBootServicesData,\r
-                    AsciiStrLen (PrivateFile->FileName) + 2 + StrLen (NewFileInfo->FileName) + 1,\r
-                    (VOID **)&NewFileName\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    AsciiStrCpy (NewFileName, PrivateRoot->FilePath);\r
-    AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName);\r
-    if ((AsciiFilePtr[-1] != '/') && (NewFileInfo->FileName[0] != '/')) {\r
-      // make sure there is a / between Root FilePath and NewFileInfo Filename\r
-      AsciiFilePtr[0] = '/';      \r
-      AsciiFilePtr[1] = '\0';\r
-      AsciiFilePtr++;\r
-    }\r
-    UnicodeFilePtr = NewFileInfo->FileName;\r
-  }\r
-  // Convert to ascii.\r
-  while (*UnicodeFilePtr) {\r
-    *AsciiFilePtr++ = *UnicodeFilePtr++;\r
-  }\r
-  *AsciiFilePtr = 0;\r
-\r
-\r
-  //\r
-  // Is there an attribute change request?\r
-  //\r
-  if (NewFileInfo->Attribute != OldFileInfo->Attribute) {\r
-    if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    }\r
-\r
-    AttrChangeFlag = TRUE;\r
-  }\r
-\r
-  //\r
-  // Is there a name change request?\r
-  // bugbug: - Need EfiStrCaseCmp()\r
-  //\r
-  if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {\r
-    NameChangeFlag = TRUE;\r
-  }\r
-\r
-  //\r
-  // Is there a size change request?\r
-  //\r
-  if (NewFileInfo->FileSize != OldFileInfo->FileSize) {\r
-    SizeChangeFlag = TRUE;\r
-  }\r
-\r
-  //\r
-  // Is there a time stamp change request?\r
-  //\r
-  if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&\r
-      CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))\r
-        ) {\r
-    TimeChangeFlag = TRUE;\r
-  } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&\r
-           CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))\r
-            ) {\r
-    TimeChangeFlag = TRUE;\r
-  } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&\r
-           CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))\r
-            ) {\r
-    TimeChangeFlag = TRUE;\r
-  }\r
-\r
-  //\r
-  // All done if there are no change requests being made.\r
-  //\r
-  if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Set file or directory information.\r
-  //\r
-  if (PrivateFile->UnixThunk->Stat (OldFileName, &OldAttr) != 0) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Name change.\r
-  //\r
-  if (NameChangeFlag) {\r
-    //\r
-    // Close the handles first\r
-    //\r
-    if (PrivateFile->IsOpenedByRead) {\r
-      Status = EFI_ACCESS_DENIED;\r
-      goto Done;\r
-    }\r
-\r
-    for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {\r
-    }\r
-\r
-    if (*CharPointer != 0) {\r
-      Status = EFI_ACCESS_DENIED;\r
-      goto Done;\r
-    }\r
-\r
-    UnixStatus = PrivateFile->UnixThunk->Rename (OldFileName, NewFileName);\r
-\r
-    if (UnixStatus == 0) {\r
-      //\r
-      // modify file name\r
-      //\r
-      gBS->FreePool (PrivateFile->FileName);\r
-\r
-      Status = gBS->AllocatePool (\r
-                      EfiBootServicesData,\r
-                      AsciiStrSize (NewFileName),\r
-                      (VOID **)&PrivateFile->FileName\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        goto Done;\r
-      }\r
-\r
-      AsciiStrCpy (PrivateFile->FileName, NewFileName);\r
-    } else {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Size change\r
-  //\r
-  if (SizeChangeFlag) {\r
-    if (PrivateFile->IsDirectoryPath) {\r
-      Status = EFI_UNSUPPORTED;\r
-      goto Done;\r
-    }\r
-\r
-    if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
-      Status = EFI_ACCESS_DENIED;\r
-      goto Done;\r
-    }\r
-\r
-    if (PrivateFile->UnixThunk->FTruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto Done;\r
-    }\r
-\r
-  }\r
-\r
-  //\r
-  // Time change\r
-  //\r
-  if (TimeChangeFlag) {\r
-    struct utimbuf utime;\r
-\r
-    NewLastAccessSystemTime.tm_year    = NewFileInfo->LastAccessTime.Year;\r
-    NewLastAccessSystemTime.tm_mon     = NewFileInfo->LastAccessTime.Month;\r
-    NewLastAccessSystemTime.tm_mday    = NewFileInfo->LastAccessTime.Day;\r
-    NewLastAccessSystemTime.tm_hour    = NewFileInfo->LastAccessTime.Hour;\r
-    NewLastAccessSystemTime.tm_min     = NewFileInfo->LastAccessTime.Minute;\r
-    NewLastAccessSystemTime.tm_sec     = NewFileInfo->LastAccessTime.Second;\r
-    NewLastAccessSystemTime.tm_isdst   = 0;\r
-\r
-    utime.actime = PrivateFile->UnixThunk->MkTime (&NewLastAccessSystemTime);\r
-\r
-    NewLastWriteSystemTime.tm_year    = NewFileInfo->ModificationTime.Year;\r
-    NewLastWriteSystemTime.tm_mon     = NewFileInfo->ModificationTime.Month;\r
-    NewLastWriteSystemTime.tm_mday    = NewFileInfo->ModificationTime.Day;\r
-    NewLastWriteSystemTime.tm_hour    = NewFileInfo->ModificationTime.Hour;\r
-    NewLastWriteSystemTime.tm_min     = NewFileInfo->ModificationTime.Minute;\r
-    NewLastWriteSystemTime.tm_sec     = NewFileInfo->ModificationTime.Second;\r
-    NewLastWriteSystemTime.tm_isdst   = 0;\r
-\r
-    utime.modtime = PrivateFile->UnixThunk->MkTime (&NewLastWriteSystemTime);\r
-\r
-    if (utime.actime == (time_t)-1 || utime.modtime == (time_t)-1) {\r
-      goto Done;\r
-    }\r
-\r
-    if (PrivateFile->UnixThunk->UTime (PrivateFile->FileName, &utime) == -1) {\r
-      goto Done;\r
-    }\r
-  }\r
-\r
-  //\r
-  // No matter about AttrChangeFlag, Attribute must be set.\r
-  // Because operation before may cause attribute change.\r
-  //\r
-  NewAttr = OldAttr.st_mode;\r
-\r
-  if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
-    NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH);\r
-  } else {\r
-    NewAttr |= S_IRUSR;\r
-  }\r
-\r
-  UnixStatus = PrivateFile->UnixThunk->Chmod (NewFileName, NewAttr);\r
-  if (UnixStatus != 0) {\r
-    Status    = EFI_DEVICE_ERROR;\r
-  }\r
-\r
-Done:\r
-  if (OldFileInfo != NULL) {\r
-    gBS->FreePool (OldFileInfo);\r
-  }\r
-\r
-  if (OldFileName != NULL) {\r
-    gBS->FreePool (OldFileName);\r
-  }\r
-\r
-  if (NewFileName != NULL) {\r
-    gBS->FreePool (NewFileName);\r
-  }\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-  \r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSimpleFileSystemFlush (\r
-  IN EFI_FILE_PROTOCOL  *This\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Flush all modified data to the media.\r
-\r
-Arguments:\r
-\r
-  This  - Pointer to an opened file handle.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The data has been flushed.\r
-\r
-  EFI_NO_MEDIA          - The device has no media.\r
-\r
-  EFI_DEVICE_ERROR      - The device reported an error.\r
-\r
-  EFI_VOLUME_CORRUPTED  - The file system structures have been corrupted.\r
-\r
-  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
-\r
-  EFI_ACCESS_DENIED     - The file was opened read-only.\r
-\r
-  EFI_VOLUME_FULL       - The volume is full.\r
-\r
---*/\r
-// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
-  UNIX_EFI_FILE_PRIVATE     *PrivateFile;\r
-  EFI_STATUS                Status;\r
-  EFI_TPL                   OldTpl;\r
-\r
-  if (This == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  \r
-  PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-\r
-  if (PrivateFile->IsDirectoryPath) {\r
-    goto Done;\r
-  }\r
-\r
-  if (PrivateFile->IsOpenedByRead) {\r
-    Status = EFI_ACCESS_DENIED;\r
-    goto Done;\r
-  }\r
-\r
-  if (PrivateFile->fd < 0) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  PrivateFile->UnixThunk->FSync (PrivateFile->fd) == 0 ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-\r
-  //\r
-  // bugbug: - Use Unix error reporting.\r
-  //\r
-}\r
-\r
-\r