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