+++ /dev/null
-/**@file\r
-\r
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-Module Name:\r
-\r
- WinNtSimpleFileSystem.c\r
-\r
-Abstract:\r
-\r
- Produce Simple File System abstractions for directories on your PC using Win32 APIs.\r
- The configuration of what devices to mount or emulate comes from NT\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
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/FileSystemVolumeLabelInfo.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Guid/FileInfo.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Guid/FileSystemInfo.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-\r
-#include "WinNtSimpleFileSystem.h"\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {\r
- WinNtSimpleFileSystemDriverBindingSupported,\r
- WinNtSimpleFileSystemDriverBindingStart,\r
- WinNtSimpleFileSystemDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-/**\r
- The user Entry Point for module WinNtSimpleFileSystem. The user code starts with this function.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeWinNtSimpleFileSystem(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Install driver model protocol(s).\r
- //\r
- Status = EfiLibInstallDriverBindingComponentName2 (\r
- ImageHandle,\r
- SystemTable,\r
- &gWinNtSimpleFileSystemDriverBinding,\r
- ImageHandle,\r
- &gWinNtSimpleFileSystemComponentName,\r
- &gWinNtSimpleFileSystemComponentName2\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
-\r
- return Status;\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 CHAR16 *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
- CHAR16 *Pointer;\r
-\r
- if (StrLen (Str) < Count) {\r
- ASSERT (0);\r
- }\r
-\r
- if (Count != 0) {\r
- for (Pointer = Str; *(Pointer + Count); Pointer++) {\r
- *Pointer = *(Pointer + Count);\r
- }\r
- *Pointer = *(Pointer + Count);\r
- }\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemDriverBindingSupported (\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_WIN_NT_IO_PROTOCOL *WinNtIo;\r
-\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiWinNtIoProtocolGuid,\r
- (VOID **) &WinNtIo,\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 (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\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
- &gEfiWinNtIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemDriverBindingStart (\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_WIN_NT_IO_PROTOCOL *WinNtIo;\r
- WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
-\r
- Private = NULL;\r
-\r
- //\r
- // Open the IO Abstraction(s) needed\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiWinNtIoProtocolGuid,\r
- (VOID **) &WinNtIo,\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 (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- Private = AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE));\r
- if (Private == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
-\r
- goto Done;\r
- }\r
-\r
- Private->Signature = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;\r
- Private->WinNtThunk = WinNtIo->WinNtThunk;\r
-\r
- Private->FilePath = WinNtIo->EnvString;\r
-\r
- Private->VolumeLabel = AllocatePool (StrSize (L"EFI_EMULATED"));\r
- if (Private->VolumeLabel == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\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 = WinNtSimpleFileSystemOpenVolume;\r
-\r
- Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);\r
-\r
- Private->ControllerNameTable = NULL;\r
-\r
- AddUnicodeString2 (\r
- "eng",\r
- gWinNtSimpleFileSystemComponentName.SupportedLanguages,\r
- &Private->ControllerNameTable,\r
- WinNtIo->EnvString,\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gWinNtSimpleFileSystemComponentName2.SupportedLanguages,\r
- &Private->ControllerNameTable,\r
- WinNtIo->EnvString,\r
- FALSE\r
- );\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
- FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
- FreePool (Private);\r
- }\r
-\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiWinNtIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemDriverBindingStop (\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
- WIN_NT_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 = WIN_NT_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
- &gEfiWinNtIoProtocolGuid,\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
- FreePool (Private);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemOpenVolume (\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
- WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- EFI_TPL OldTpl;\r
- CHAR16 *TempFileName;\r
- UINTN Size;\r
-\r
- if (This == NULL || Root == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
- if (PrivateFile == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath));\r
- if (PrivateFile->FileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath));\r
- if (PrivateFile->FilePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (PrivateFile->FilePath, Private->FilePath);\r
- StrCpy (PrivateFile->FileName, PrivateFile->FilePath);\r
- PrivateFile->Signature = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;\r
- PrivateFile->WinNtThunk = Private->WinNtThunk;\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 = WinNtSimpleFileSystemOpen;\r
- PrivateFile->EfiFile.Close = WinNtSimpleFileSystemClose;\r
- PrivateFile->EfiFile.Delete = WinNtSimpleFileSystemDelete;\r
- PrivateFile->EfiFile.Read = WinNtSimpleFileSystemRead;\r
- PrivateFile->EfiFile.Write = WinNtSimpleFileSystemWrite;\r
- PrivateFile->EfiFile.GetPosition = WinNtSimpleFileSystemGetPosition;\r
- PrivateFile->EfiFile.SetPosition = WinNtSimpleFileSystemSetPosition;\r
- PrivateFile->EfiFile.GetInfo = WinNtSimpleFileSystemGetInfo;\r
- PrivateFile->EfiFile.SetInfo = WinNtSimpleFileSystemSetInfo;\r
- PrivateFile->EfiFile.Flush = WinNtSimpleFileSystemFlush;\r
- PrivateFile->IsValidFindBuf = FALSE;\r
-\r
- //\r
- // Set DirHandle\r
- //\r
- PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
- PrivateFile->FilePath,\r
- GENERIC_READ,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_FLAG_BACKUP_SEMANTICS,\r
- NULL\r
- );\r
-\r
- if (PrivateFile->DirHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Find the first file under it\r
- //\r
- Size = StrSize (PrivateFile->FilePath);\r
- Size += StrSize (L"\\*");\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- Size,\r
- (VOID **)&TempFileName\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- StrCpy (TempFileName, PrivateFile->FilePath);\r
- StrCat (TempFileName, L"\\*");\r
-\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &PrivateFile->FindBuf);\r
- FreePool (TempFileName);\r
-\r
- if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- PrivateFile->IsValidFindBuf = FALSE;\r
- } else {\r
- PrivateFile->IsValidFindBuf = TRUE;\r
- }\r
- *Root = &PrivateFile->EfiFile;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- if (PrivateFile) {\r
- if (PrivateFile->FileName) {\r
- FreePool (PrivateFile->FileName);\r
- }\r
-\r
- if (PrivateFile->FilePath) {\r
- FreePool (PrivateFile->FilePath);\r
- }\r
-\r
- FreePool (PrivateFile);\r
- }\r
- }\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Count the number of Leading Dot in FileNameToken.\r
-\r
- @param FileNameToken A string representing a token in the path name.\r
-\r
- @return UINTN The number of leading dot in the name.\r
-\r
-**/\r
-UINTN\r
-CountLeadingDots (\r
- IN CONST CHAR16 * FileNameToken\r
- )\r
-{\r
- UINTN Num;\r
-\r
- Num = 0;\r
- while (*FileNameToken == L'.') {\r
- Num++;\r
- FileNameToken++;\r
- }\r
- \r
- return Num;\r
-}\r
-\r
-BOOLEAN \r
-IsFileNameTokenValid (\r
- IN CONST CHAR16 * FileNameToken\r
- )\r
-{\r
- UINTN Num;\r
- if (StrStr (FileNameToken, L"/") != NULL) {\r
- //\r
- // No L'/' in file name.\r
- //\r
- return FALSE;\r
- } else {\r
- //\r
- // If Token has all dot, the number should not exceed 2\r
- //\r
- Num = CountLeadingDots (FileNameToken);\r
-\r
- if (Num == StrLen (FileNameToken)) {\r
- //\r
- // If the FileNameToken only contains a number of L'.'.\r
- //\r
- if (Num > 2) {\r
- return FALSE;\r
- }\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Return the first string token found in the indirect pointer a String named by FileName.\r
-\r
- On input, FileName is a indirect pointer pointing to a String.\r
- On output, FileName is a updated to point to the next character after the first\r
- found L"\" or NULL if there is no L"\" found.\r
-\r
- @param FileName A indirect pointer pointing to a FileName.\r
-\r
- @return Token The first string token found before a L"\".\r
-\r
-**/\r
-CHAR16 *\r
-GetNextFileNameToken (\r
- IN OUT CONST CHAR16 ** FileName \r
- )\r
-{\r
- CHAR16 *SlashPos;\r
- CHAR16 *Token;\r
- UINTN Offset;\r
- ASSERT (**FileName != L'\\');\r
- ASSERT (**FileName != L'\0');\r
-\r
- SlashPos = StrStr (*FileName, L"\\");\r
- if (SlashPos == NULL) {\r
- Token = AllocateCopyPool (StrSize(*FileName), *FileName);\r
- *FileName = NULL;\r
- } else {\r
- Offset = SlashPos - *FileName;\r
- Token = AllocateZeroPool ((Offset + 1) * sizeof (CHAR16));\r
- StrnCpy (Token, *FileName, Offset);\r
- //\r
- // Point *FileName to the next character after L'\'.\r
- //\r
- *FileName = *FileName + Offset + 1;\r
- //\r
- // If *FileName is an empty string, then set *FileName to NULL\r
- //\r
- if (**FileName == L'\0') {\r
- *FileName = NULL;\r
- }\r
- }\r
-\r
- return Token;\r
-}\r
-\r
-/**\r
- Check if a FileName contains only Valid Characters.\r
-\r
- If FileName contains only a single L'\', return TRUE.\r
- If FileName contains two adjacent L'\', return FALSE.\r
- If FileName conatins L'/' , return FALSE.\r
- If FielName contains more than two dots seperated with other FileName characters\r
- by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name.\r
-\r
- @param FileName The File Name String to check.\r
-\r
- @return TRUE FileName only contains valid characters.\r
- @return FALSE FileName contains at least one invalid character.\r
-\r
-**/\r
-\r
-BOOLEAN\r
-IsFileNameValid (\r
- IN CONST CHAR16 *FileName \r
- )\r
-{\r
- CHAR16 *Token;\r
- BOOLEAN Valid;\r
-\r
- //\r
- // If FileName is just L'\', then it is a valid pathname. \r
- //\r
- if (StrCmp (FileName, L"\\") == 0) {\r
- return TRUE;\r
- }\r
- //\r
- // We don't support two or more adjacent L'\'.\r
- //\r
- if (StrStr (FileName, L"\\\\") != NULL) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Is FileName has a leading L"\", skip to next character.\r
- //\r
- if (FileName [0] == L'\\') {\r
- FileName++;\r
- }\r
-\r
- do {\r
- Token = GetNextFileNameToken (&FileName);\r
- Valid = IsFileNameTokenValid (Token);\r
- FreePool (Token);\r
- \r
- if (!Valid)\r
- return FALSE;\r
- } while (FileName != NULL);\r
-\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemOpen (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- WIN_NT_EFI_FILE_PRIVATE *NewPrivateFile;\r
- WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
- EFI_STATUS Status;\r
- CHAR16 *RealFileName;\r
- CHAR16 *TempFileName;\r
- CHAR16 *ParseFileName;\r
- CHAR16 *GuardPointer;\r
- CHAR16 TempChar;\r
- DWORD LastError;\r
- UINTN Count;\r
- BOOLEAN LoopFinish;\r
- UINTN InfoSize;\r
- EFI_FILE_INFO *Info;\r
- UINTN Size;\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
- // Init local variables\r
- //\r
- PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
- PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
- NewPrivateFile = NULL;\r
-\r
- //\r
- // Allocate buffer for FileName as the passed in FileName may be read only\r
- //\r
- TempFileName = AllocatePool (StrSize (FileName));\r
- if (TempFileName == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- StrCpy (TempFileName, FileName);\r
- FileName = TempFileName;\r
-\r
- if (FileName[StrLen (FileName) - 1] == L'\\') {\r
- FileName[StrLen (FileName) - 1] = 0;\r
- }\r
-\r
- //\r
- // If file name does not equal to "." or ".." and not trailed with "\..",\r
- // then we trim the leading/trailing blanks and trailing dots\r
- //\r
- if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0 && \r
- ((StrLen (FileName) >= 3) ? (StrCmp (&FileName[StrLen (FileName) - 3], L"\\..") != 0) : TRUE)) {\r
- //\r
- // Trim leading blanks\r
- //\r
- Count = 0;\r
- for (TempFileName = FileName;\r
- *TempFileName != 0 && *TempFileName == L' ';\r
- TempFileName++) {\r
- Count++;\r
- }\r
- CutPrefix (FileName, Count);\r
- //\r
- // Trim trailing blanks\r
- //\r
- for (TempFileName = FileName + StrLen (FileName) - 1;\r
- TempFileName >= FileName && (*TempFileName == L' ');\r
- TempFileName--) {\r
- ;\r
- }\r
- *(TempFileName + 1) = 0;\r
- }\r
-\r
- //\r
- // Attempt to open the file\r
- //\r
- NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
- if (NewPrivateFile == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
-\r
- NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName));\r
- if (NewPrivateFile->FilePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
- StrCpy (NewPrivateFile->FilePath, PrivateFile->FileName);\r
- } else {\r
- StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath);\r
- }\r
-\r
- Size = StrSize (NewPrivateFile->FilePath);\r
- Size += StrSize (L"\\");\r
- Size += StrSize (FileName);\r
- NewPrivateFile->FileName = AllocatePool (Size);\r
- if (NewPrivateFile->FileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- if (*FileName == L'\\') {\r
- StrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);\r
- StrCat (NewPrivateFile->FileName, L"\\");\r
- StrCat (NewPrivateFile->FileName, FileName + 1);\r
- } else {\r
- StrCpy (NewPrivateFile->FileName, NewPrivateFile->FilePath);\r
- if (StrCmp (FileName, L"") != 0) {\r
- //\r
- // In case the filename becomes empty, especially after trimming dots and blanks\r
- //\r
- StrCat (NewPrivateFile->FileName, L"\\");\r
- StrCat (NewPrivateFile->FileName, FileName);\r
- }\r
- }\r
-\r
- if (!IsFileNameValid (NewPrivateFile->FileName)) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\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
- GuardPointer = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath);\r
-\r
- LoopFinish = FALSE;\r
-\r
- while (!LoopFinish) {\r
-\r
- LoopFinish = TRUE;\r
-\r
- for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {\r
- if (*ParseFileName == L'.' &&\r
- (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') &&\r
- *(ParseFileName - 1) == L'\\'\r
- ) {\r
-\r
- //\r
- // cut \.\r
- //\r
- CutPrefix (ParseFileName - 1, 2);\r
- LoopFinish = FALSE;\r
- break;\r
- }\r
-\r
- if (*ParseFileName == L'.' &&\r
- *(ParseFileName + 1) == L'.' &&\r
- (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') &&\r
- *(ParseFileName - 1) == L'\\'\r
- ) {\r
-\r
- ParseFileName--;\r
- Count = 3;\r
-\r
- while (ParseFileName != GuardPointer) {\r
- ParseFileName--;\r
- Count++;\r
- if (*ParseFileName == L'\\') {\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
- RealFileName = NewPrivateFile->FileName;\r
- while (EfiStrChr (RealFileName, L'\\') != NULL) {\r
- RealFileName = EfiStrChr (RealFileName, L'\\') + 1;\r
- }\r
-\r
- TempChar = 0;\r
- if (RealFileName != NewPrivateFile->FileName) {\r
- TempChar = *(RealFileName - 1);\r
- *(RealFileName - 1) = 0;\r
- }\r
- \r
- FreePool (NewPrivateFile->FilePath);\r
- NewPrivateFile->FilePath = NULL;\r
- NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName));\r
- if (NewPrivateFile->FilePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName);\r
- if (TempChar != 0) {\r
- *(RealFileName - 1) = TempChar;\r
- }\r
-\r
- NewPrivateFile->IsRootDirectory = FALSE;\r
-\r
- //\r
- // Test whether file or directory\r
- //\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
- NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
- NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- NewPrivateFile->FileName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
- NewPrivateFile->IsDirectoryPath = FALSE;\r
- NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
- } else {\r
- NewPrivateFile->IsDirectoryPath = TRUE;\r
- }\r
-\r
- NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\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
- Size = StrSize (NewPrivateFile->FileName);\r
- Size += StrSize (L"\\*");\r
- TempFileName = AllocatePool (Size);\r
- if (TempFileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (TempFileName, NewPrivateFile->FileName);\r
-\r
- if ((OpenMode & EFI_FILE_MODE_CREATE)) {\r
- //\r
- // Create a directory\r
- //\r
- if (!NewPrivateFile->WinNtThunk->CreateDirectory (TempFileName, NULL)) {\r
-\r
- LastError = PrivateFile->WinNtThunk->GetLastError ();\r
- if (LastError != ERROR_ALREADY_EXISTS) {\r
- FreePool (TempFileName);\r
- Status = EFI_ACCESS_DENIED;\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
- NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_FLAG_BACKUP_SEMANTICS,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) {\r
-\r
- NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_FLAG_BACKUP_SEMANTICS,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
- NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->DirHandle);\r
- NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
- Status = EFI_ACCESS_DENIED;\r
- } else {\r
- Status = EFI_NOT_FOUND;\r
- }\r
-\r
- FreePool (TempFileName);\r
- goto Done;\r
- }\r
-\r
- //\r
- // Find the first file under it\r
- //\r
- StrCat (TempFileName, L"\\*");\r
- NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);\r
- FreePool (TempFileName);\r
-\r
- if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- NewPrivateFile->IsValidFindBuf = FALSE;\r
- } else {\r
- NewPrivateFile->IsValidFindBuf = TRUE;\r
- }\r
- } else {\r
- //\r
- // deal with file\r
- //\r
- if (!NewPrivateFile->IsOpenedByRead) {\r
- NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- NewPrivateFile->FileName,\r
- GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- NewPrivateFile->FileName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_NOT_FOUND;\r
- } else {\r
- Status = EFI_ACCESS_DENIED;\r
- NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
- NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
- }\r
- }\r
- } else {\r
- NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
- NewPrivateFile->FileName,\r
- GENERIC_READ,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
-\r
- if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_NOT_FOUND;\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 = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
-\r
- if (Status != EFI_BUFFER_TOO_SMALL) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- Info = AllocatePool (InfoSize);\r
- if (Info == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- goto Done;\r
- }\r
-\r
- Info->Attribute = Attributes;\r
-\r
- WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);\r
- FreePool (Info);\r
- }\r
-\r
-Done:\r
- FreePool (FileName);\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (NewPrivateFile) {\r
- if (NewPrivateFile->FileName) {\r
- FreePool (NewPrivateFile->FileName);\r
- }\r
-\r
- if (NewPrivateFile->FilePath) {\r
- FreePool (NewPrivateFile->FilePath);\r
- }\r
-\r
- FreePool (NewPrivateFile);\r
- }\r
- } else {\r
- *NewHandle = &NewPrivateFile->EfiFile;\r
- if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
- NewPrivateFile->IsRootDirectory = TRUE;\r
- } \r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemClose (\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
- WIN_NT_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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
- if (PrivateFile->IsDirectoryPath) {\r
- PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
- } else {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
- }\r
-\r
- PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
- PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
- }\r
-\r
- if (PrivateFile->FileName) {\r
- FreePool (PrivateFile->FileName);\r
- }\r
-\r
- if (PrivateFile->FilePath) {\r
- FreePool (PrivateFile->FilePath);\r
- }\r
-\r
- FreePool (PrivateFile);\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemDelete (\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
- WIN_NT_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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- Status = EFI_WARN_DELETE_FAILURE;\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
- if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
- PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
- }\r
-\r
- if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
- PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
- }\r
-\r
- if (PrivateFile->WinNtThunk->RemoveDirectory (PrivateFile->FileName)) {\r
- Status = EFI_SUCCESS;\r
- }\r
- } else {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
- PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
-\r
- if (!PrivateFile->IsOpenedByRead) {\r
- if (PrivateFile->WinNtThunk->DeleteFile (PrivateFile->FileName)) {\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- FreePool (PrivateFile->FileName);\r
- FreePool (PrivateFile->FilePath);\r
- FreePool (PrivateFile);\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-VOID\r
-WinNtSystemTimeToEfiTime (\r
- IN SYSTEMTIME *SystemTime,\r
- IN TIME_ZONE_INFORMATION *TimeZone,\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
- Time->Year = (UINT16) SystemTime->wYear;\r
- Time->Month = (UINT8) SystemTime->wMonth;\r
- Time->Day = (UINT8) SystemTime->wDay;\r
- Time->Hour = (UINT8) SystemTime->wHour;\r
- Time->Minute = (UINT8) SystemTime->wMinute;\r
- Time->Second = (UINT8) SystemTime->wSecond;\r
- Time->Nanosecond = (UINT32) SystemTime->wMilliseconds * 1000000;\r
- Time->TimeZone = (INT16) TimeZone->Bias;\r
-\r
- if (TimeZone->StandardDate.wMonth) {\r
- Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;\r
- }\r
-}\r
-\r
-/**\r
- Convert the FileTime to EfiTime.\r
-\r
- @param PrivateFile Pointer to WIN_NT_EFI_FILE_PRIVATE.\r
- @param TimeZone Pointer to the current time zone.\r
- @param FileTime Pointer to file time.\r
- @param EfiTime Pointer to EFI time.\r
-**/\r
-VOID\r
-WinNtFileTimeToEfiTime ( \r
- IN CONST WIN_NT_EFI_FILE_PRIVATE *PrivateFile,\r
- IN TIME_ZONE_INFORMATION *TimeZone,\r
- IN CONST FILETIME *FileTime,\r
- OUT EFI_TIME *EfiTime\r
- )\r
-{\r
- FILETIME TempFileTime;\r
- SYSTEMTIME SystemTime;\r
-\r
- PrivateFile->WinNtThunk->FileTimeToLocalFileTime (FileTime, &TempFileTime);\r
- PrivateFile->WinNtThunk->FileTimeToSystemTime (&TempFileTime, &SystemTime);\r
- WinNtSystemTimeToEfiTime (&SystemTime, TimeZone, EfiTime);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemRead (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- EFI_STATUS Status;\r
- UINTN Size;\r
- UINTN NameSize;\r
- UINTN ResultSize;\r
- UINTN Index;\r
- EFI_FILE_INFO *Info;\r
- WCHAR *pw;\r
- TIME_ZONE_INFORMATION TimeZone;\r
- EFI_FILE_INFO *FileInfo;\r
- UINT64 Pos;\r
- UINT64 FileSize;\r
- UINTN FileInfoSize;\r
- EFI_TPL OldTpl;\r
-\r
- if (This == NULL || BufferSize == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- if (!PrivateFile->IsDirectoryPath) {\r
-\r
- if (This->GetPosition (This, &Pos) != EFI_SUCCESS) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO;\r
- FileInfo = AllocatePool (FileInfoSize);\r
-\r
- Status = This->GetInfo (\r
- This,\r
- &gEfiFileInfoGuid,\r
- &FileInfoSize,\r
- FileInfo\r
- );\r
-\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- FreePool (FileInfo);\r
- FileInfo = AllocatePool (FileInfoSize);\r
- Status = This->GetInfo (\r
- This,\r
- &gEfiFileInfoGuid,\r
- &FileInfoSize,\r
- FileInfo\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- FileSize = FileInfo->FileSize;\r
-\r
- FreePool (FileInfo);\r
-\r
- if (Pos >= FileSize) {\r
- *BufferSize = 0;\r
- if (Pos == FileSize) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
- }\r
-\r
- Status = PrivateFile->WinNtThunk->ReadFile (\r
- PrivateFile->LHandle,\r
- Buffer,\r
- (DWORD)*BufferSize,\r
- (LPDWORD)BufferSize,\r
- NULL\r
- ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Read on a directory. Perform a find next\r
- //\r
- if (!PrivateFile->IsValidFindBuf) {\r
- *BufferSize = 0;\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
-\r
- Size = SIZE_OF_EFI_FILE_INFO;\r
-\r
- NameSize = StrSize (PrivateFile->FindBuf.cFileName);\r
-\r
- ResultSize = Size + NameSize;\r
-\r
- Status = EFI_BUFFER_TOO_SMALL;\r
-\r
- if (*BufferSize >= ResultSize) {\r
- Status = EFI_SUCCESS;\r
-\r
- Info = Buffer;\r
- ZeroMem (Info, ResultSize);\r
-\r
- Info->Size = ResultSize;\r
-\r
- PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftCreationTime, &Info->CreateTime);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastAccessTime, &Info->LastAccessTime);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastWriteTime, &Info->ModificationTime);\r
-\r
- Info->FileSize = PrivateFile->FindBuf.nFileSizeLow;\r
-\r
- Info->PhysicalSize = PrivateFile->FindBuf.nFileSizeLow;\r
-\r
- if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
- Info->Attribute |= EFI_FILE_ARCHIVE;\r
- }\r
-\r
- if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
- Info->Attribute |= EFI_FILE_HIDDEN;\r
- }\r
-\r
- if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
- Info->Attribute |= EFI_FILE_SYSTEM;\r
- }\r
-\r
- if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
- Info->Attribute |= EFI_FILE_READ_ONLY;\r
- }\r
-\r
- if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
- Info->Attribute |= EFI_FILE_DIRECTORY;\r
- }\r
-\r
- NameSize = NameSize / sizeof (WCHAR);\r
-\r
- pw = (WCHAR *) (((CHAR8 *) Buffer) + Size);\r
-\r
- for (Index = 0; Index < NameSize; Index++) {\r
- pw[Index] = PrivateFile->FindBuf.cFileName[Index];\r
- }\r
-\r
- if (PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) {\r
- PrivateFile->IsValidFindBuf = TRUE;\r
- } else {\r
- PrivateFile->IsValidFindBuf = FALSE;\r
- }\r
- }\r
-\r
- *BufferSize = ResultSize;\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemWrite (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->IsOpenedByRead) {\r
- Status = EFI_ACCESS_DENIED;\r
- goto Done;\r
- }\r
-\r
- Status = PrivateFile->WinNtThunk->WriteFile (\r
- PrivateFile->LHandle,\r
- Buffer,\r
- (DWORD)*BufferSize,\r
- (LPDWORD)BufferSize,\r
- NULL\r
- ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-\r
- //\r
- // bugbug: need to access windows error reporting\r
- //\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemSetPosition (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- UINT32 PosLow;\r
- UINT32 PosHigh;\r
- CHAR16 *FileName;\r
- EFI_TPL OldTpl;\r
- UINTN Size;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- PrivateFile = WIN_NT_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
- Size = StrSize (PrivateFile->FileName);\r
- Size += StrSize (L"\\*");\r
- FileName = AllocatePool (Size);\r
- if (FileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (FileName, PrivateFile->FileName);\r
- StrCat (FileName, L"\\*");\r
-\r
- if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
- PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
- }\r
-\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (FileName, &PrivateFile->FindBuf);\r
-\r
- if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- PrivateFile->IsValidFindBuf = FALSE;\r
- } else {\r
- PrivateFile->IsValidFindBuf = TRUE;\r
- }\r
-\r
- FreePool (FileName);\r
-\r
- Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
- } else {\r
- if (Position == (UINT64) -1) {\r
- PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) 0, NULL, FILE_END);\r
- } else {\r
- PosHigh = (UINT32) RShiftU64 (Position, 32);\r
-\r
- PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, (PLONG)&PosHigh, FILE_BEGIN);\r
- }\r
-\r
- Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
- }\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemGetPosition (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- INT32 PositionHigh;\r
- UINT64 PosHigh64;\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
- PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- PositionHigh = 0;\r
- PosHigh64 = 0;\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
-\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
-\r
- } else {\r
-\r
- PositionHigh = 0;\r
- *Position = PrivateFile->WinNtThunk->SetFilePointer (\r
- PrivateFile->LHandle,\r
- 0,\r
- (PLONG)&PositionHigh,\r
- FILE_CURRENT\r
- );\r
-\r
- Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- PosHigh64 = PositionHigh;\r
- *Position += LShiftU64 (PosHigh64, 32);\r
- }\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-WinNtSimpleFileSystemFileInfo (\r
- IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile,\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
- BY_HANDLE_FILE_INFORMATION FileInfo;\r
- CHAR16 *RealFileName;\r
- CHAR16 *TempPointer;\r
- TIME_ZONE_INFORMATION TimeZone;\r
-\r
- Size = SIZE_OF_EFI_FILE_INFO;\r
-\r
- RealFileName = PrivateFile->FileName;\r
- TempPointer = RealFileName;\r
- while (*TempPointer) {\r
- if (*TempPointer == '\\') {\r
- RealFileName = TempPointer + 1;\r
- }\r
-\r
- TempPointer++;\r
- }\r
- NameSize = StrSize (RealFileName);\r
-\r
- ResultSize = Size + NameSize; \r
-\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- if (*BufferSize >= ResultSize) {\r
- Status = EFI_SUCCESS;\r
-\r
- Info = Buffer;\r
- ZeroMem (Info, ResultSize);\r
-\r
- Info->Size = ResultSize;\r
- PrivateFile->WinNtThunk->GetFileInformationByHandle (\r
- PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
- &FileInfo\r
- );\r
- Info->FileSize = FileInfo.nFileSizeLow;\r
- Info->PhysicalSize = Info->FileSize;\r
-\r
- PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftCreationTime, &Info->CreateTime);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastAccessTime, &Info->LastAccessTime);\r
- WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastWriteTime, &Info->ModificationTime);\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
- Info->Attribute |= EFI_FILE_ARCHIVE;\r
- }\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
- Info->Attribute |= EFI_FILE_HIDDEN;\r
- }\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
- Info->Attribute |= EFI_FILE_READ_ONLY;\r
- }\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
- Info->Attribute |= EFI_FILE_SYSTEM;\r
- }\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
- Info->Attribute |= EFI_FILE_DIRECTORY;\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
- Info->Attribute |= EFI_FILE_DIRECTORY;\r
- }\r
-\r
- if (PrivateFile->IsRootDirectory) {\r
- *((CHAR8 *) Buffer + Size) = 0;\r
- } else {\r
- CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);\r
- }\r
- }\r
-\r
- *BufferSize = ResultSize;\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemGetInfo (\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
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;\r
- UINT32 SectorsPerCluster;\r
- UINT32 BytesPerSector;\r
- UINT32 FreeClusters;\r
- UINT32 TotalClusters;\r
- UINT32 BytesPerCluster;\r
- CHAR16 *DriveName;\r
- BOOLEAN DriveNameFound;\r
- BOOL NtStatus;\r
- UINTN Index;\r
- WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
- PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
-\r
- Status = EFI_UNSUPPORTED;\r
-\r
- if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
- Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);\r
- }\r
-\r
- 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
- 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
- // Try to get the drive name\r
- //\r
- DriveNameFound = FALSE;\r
- DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1);\r
- if (DriveName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (DriveName, PrivateFile->FilePath);\r
- for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) {\r
- ;\r
- }\r
-\r
- if (DriveName[Index] == ':') {\r
- DriveName[Index + 1] = '\\';\r
- DriveName[Index + 2] = 0;\r
- DriveNameFound = TRUE;\r
- } else if (DriveName[0] == '\\' && DriveName[1] == '\\') {\r
- for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
- ;\r
- }\r
-\r
- if (DriveName[Index] == '\\') {\r
- DriveNameFound = TRUE;\r
- for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
- ;\r
- }\r
-\r
- DriveName[Index] = '\\';\r
- DriveName[Index + 1] = 0;\r
- }\r
- }\r
-\r
- //\r
- // Try GetDiskFreeSpace first\r
- //\r
- NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (\r
- DriveNameFound ? DriveName : NULL,\r
- (LPDWORD)&SectorsPerCluster,\r
- (LPDWORD)&BytesPerSector,\r
- (LPDWORD)&FreeClusters,\r
- (LPDWORD)&TotalClusters\r
- );\r
- if (DriveName) {\r
- FreePool (DriveName);\r
- }\r
-\r
- if (NtStatus) {\r
- //\r
- // Succeeded\r
- //\r
- BytesPerCluster = BytesPerSector * SectorsPerCluster;\r
- FileSystemInfoBuffer->VolumeSize = MultU64x32 (TotalClusters, BytesPerCluster);\r
- FileSystemInfoBuffer->FreeSpace = MultU64x32 (FreeClusters, BytesPerCluster);\r
- FileSystemInfoBuffer->BlockSize = BytesPerCluster;\r
-\r
- } else {\r
- //\r
- // try GetDiskFreeSpaceEx then\r
- //\r
- FileSystemInfoBuffer->BlockSize = 0;\r
- NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx (\r
- PrivateFile->FilePath,\r
- (PULARGE_INTEGER) (&FileSystemInfoBuffer->FreeSpace),\r
- (PULARGE_INTEGER) (&FileSystemInfoBuffer->VolumeSize),\r
- NULL\r
- );\r
- if (!NtStatus) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\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
- }\r
-\r
- 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
-WinNtSimpleFileSystemSetInfo (\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
- WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
- WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
- EFI_FILE_INFO *OldFileInfo;\r
- EFI_FILE_INFO *NewFileInfo;\r
- EFI_STATUS Status;\r
- UINTN OldInfoSize;\r
- INTN NtStatus;\r
- UINT32 NewAttr;\r
- UINT32 OldAttr;\r
- CHAR16 *OldFileName;\r
- CHAR16 *NewFileName;\r
- CHAR16 *TempFileName;\r
- CHAR16 *CharPointer;\r
- BOOLEAN AttrChangeFlag;\r
- BOOLEAN NameChangeFlag;\r
- BOOLEAN SizeChangeFlag;\r
- BOOLEAN TimeChangeFlag;\r
- UINT64 CurPos;\r
- SYSTEMTIME NewCreationSystemTime;\r
- SYSTEMTIME NewLastAccessSystemTime;\r
- SYSTEMTIME NewLastWriteSystemTime;\r
- FILETIME NewCreationFileTime;\r
- FILETIME NewLastAccessFileTime;\r
- FILETIME NewLastWriteFileTime;\r
- WIN32_FIND_DATA FindBuf;\r
- EFI_FILE_SYSTEM_INFO *NewFileSystemInfo;\r
- EFI_TPL OldTpl;\r
- UINTN Size;\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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
- PrivateRoot = WIN_NT_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
- NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
- if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (NewFileSystemInfo->VolumeLabel)) {\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- goto Done;\r
- }\r
-\r
-\r
- FreePool (PrivateRoot->VolumeLabel);\r
- PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel));\r
- if (PrivateRoot->VolumeLabel == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\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 = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL);\r
-\r
- if (Status != EFI_BUFFER_TOO_SMALL) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- OldFileInfo = AllocatePool (OldInfoSize);\r
- if (OldFileInfo == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- OldFileName = AllocatePool (StrSize (PrivateFile->FileName));\r
- if (OldFileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (OldFileName, PrivateFile->FileName);\r
-\r
- //\r
- // Make full pathname from new filename and rootpath.\r
- //\r
- if (NewFileInfo->FileName[0] == '\\') {\r
- Size = StrSize (PrivateRoot->FilePath);\r
- Size += StrSize (L"\\");\r
- Size += StrSize (NewFileInfo->FileName);\r
- NewFileName = AllocatePool (Size);\r
- if (NewFileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (NewFileName, PrivateRoot->FilePath);\r
- StrCat (NewFileName, L"\\");\r
- StrCat (NewFileName, NewFileInfo->FileName + 1);\r
- } else {\r
- Size = StrSize (PrivateFile->FilePath);\r
- Size += StrSize (L"\\");\r
- Size += StrSize (NewFileInfo->FileName);\r
- NewFileName = AllocatePool (Size);\r
- if (NewFileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (NewFileName, PrivateFile->FilePath);\r
- StrCat (NewFileName, L"\\");\r
- StrCat (NewFileName, NewFileInfo->FileName);\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
- OldAttr = PrivateFile->WinNtThunk->GetFileAttributes (OldFileName);\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
- if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
- if (PrivateFile->IsDirectoryPath) {\r
- PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
- } else {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
- PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
- }\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
- PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
- PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
- }\r
-\r
- NtStatus = PrivateFile->WinNtThunk->MoveFile (OldFileName, NewFileName);\r
-\r
- if (NtStatus) {\r
- //\r
- // modify file name\r
- //\r
- FreePool (PrivateFile->FileName);\r
-\r
- PrivateFile->FileName = AllocatePool (StrSize (NewFileName));\r
- if (PrivateFile->FileName == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- StrCpy (PrivateFile->FileName, NewFileName);\r
-\r
- Size = StrSize (NewFileName);\r
- Size += StrSize (L"\\*");\r
- TempFileName = AllocatePool (Size);\r
-\r
- StrCpy (TempFileName, NewFileName);\r
-\r
- if (!PrivateFile->IsDirectoryPath) {\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
-\r
- FreePool (TempFileName);\r
-\r
- //\r
- // Flush buffers just in case\r
- //\r
- if (PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) == 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
- } else {\r
- PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_FLAG_BACKUP_SEMANTICS,\r
- NULL\r
- );\r
-\r
- StrCat (TempFileName, L"\\*");\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
-\r
- FreePool (TempFileName);\r
- }\r
- } else {\r
- Status = EFI_ACCESS_DENIED;\r
-Reopen: ;\r
-\r
- NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr);\r
-\r
- if (!NtStatus) {\r
- goto Done;\r
- }\r
-\r
- Size = StrSize (OldFileName);\r
- Size += StrSize (L"\\*");\r
- TempFileName = AllocatePool (Size);\r
-\r
- StrCpy (TempFileName, OldFileName);\r
-\r
- if (!PrivateFile->IsDirectoryPath) {\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- 0,\r
- NULL\r
- );\r
- } else {\r
- PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
- TempFileName,\r
- PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_FLAG_BACKUP_SEMANTICS,\r
- NULL\r
- );\r
-\r
- StrCat (TempFileName, L"\\*");\r
- PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
- }\r
-\r
- FreePool (TempFileName);\r
-\r
- goto Done;\r
-\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
- Status = This->GetPosition (This, &CurPos);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Status = This->SetPosition (This, NewFileInfo->FileSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->WinNtThunk->SetEndOfFile (PrivateFile->LHandle) == 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- Status = This->SetPosition (This, CurPos);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // Time change\r
- //\r
- if (TimeChangeFlag) {\r
-\r
- NewCreationSystemTime.wYear = NewFileInfo->CreateTime.Year;\r
- NewCreationSystemTime.wMonth = NewFileInfo->CreateTime.Month;\r
- NewCreationSystemTime.wDay = NewFileInfo->CreateTime.Day;\r
- NewCreationSystemTime.wHour = NewFileInfo->CreateTime.Hour;\r
- NewCreationSystemTime.wMinute = NewFileInfo->CreateTime.Minute;\r
- NewCreationSystemTime.wSecond = NewFileInfo->CreateTime.Second;\r
- NewCreationSystemTime.wMilliseconds = 0;\r
-\r
- if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
- &NewCreationSystemTime,\r
- &NewCreationFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
- &NewCreationFileTime,\r
- &NewCreationFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- NewLastAccessSystemTime.wYear = NewFileInfo->LastAccessTime.Year;\r
- NewLastAccessSystemTime.wMonth = NewFileInfo->LastAccessTime.Month;\r
- NewLastAccessSystemTime.wDay = NewFileInfo->LastAccessTime.Day;\r
- NewLastAccessSystemTime.wHour = NewFileInfo->LastAccessTime.Hour;\r
- NewLastAccessSystemTime.wMinute = NewFileInfo->LastAccessTime.Minute;\r
- NewLastAccessSystemTime.wSecond = NewFileInfo->LastAccessTime.Second;\r
- NewLastAccessSystemTime.wMilliseconds = 0;\r
-\r
- if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
- &NewLastAccessSystemTime,\r
- &NewLastAccessFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
- &NewLastAccessFileTime,\r
- &NewLastAccessFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- NewLastWriteSystemTime.wYear = NewFileInfo->ModificationTime.Year;\r
- NewLastWriteSystemTime.wMonth = NewFileInfo->ModificationTime.Month;\r
- NewLastWriteSystemTime.wDay = NewFileInfo->ModificationTime.Day;\r
- NewLastWriteSystemTime.wHour = NewFileInfo->ModificationTime.Hour;\r
- NewLastWriteSystemTime.wMinute = NewFileInfo->ModificationTime.Minute;\r
- NewLastWriteSystemTime.wSecond = NewFileInfo->ModificationTime.Second;\r
- NewLastWriteSystemTime.wMilliseconds = 0;\r
-\r
- if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
- &NewLastWriteSystemTime,\r
- &NewLastWriteFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
- &NewLastWriteFileTime,\r
- &NewLastWriteFileTime\r
- )) {\r
- goto Done;\r
- }\r
-\r
- if (!PrivateFile->WinNtThunk->SetFileTime (\r
- PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
- &NewCreationFileTime,\r
- &NewLastAccessFileTime,\r
- &NewLastWriteFileTime\r
- )) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\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;\r
-\r
- if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) {\r
- NewAttr |= FILE_ATTRIBUTE_ARCHIVE;\r
- } else {\r
- NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE;\r
- }\r
-\r
- if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) {\r
- NewAttr |= FILE_ATTRIBUTE_HIDDEN;\r
- } else {\r
- NewAttr &= ~FILE_ATTRIBUTE_HIDDEN;\r
- }\r
-\r
- if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) {\r
- NewAttr |= FILE_ATTRIBUTE_SYSTEM;\r
- } else {\r
- NewAttr &= ~FILE_ATTRIBUTE_SYSTEM;\r
- }\r
-\r
- if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
- NewAttr |= FILE_ATTRIBUTE_READONLY;\r
- } else {\r
- NewAttr &= ~FILE_ATTRIBUTE_READONLY;\r
- }\r
-\r
- NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr);\r
-\r
- if (!NtStatus) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Reopen;\r
- }\r
-\r
-Done:\r
- if (OldFileInfo != NULL) {\r
- FreePool (OldFileInfo);\r
- }\r
-\r
- if (OldFileName != NULL) {\r
- FreePool (OldFileName);\r
- }\r
-\r
- if (NewFileName != NULL) {\r
- FreePool (NewFileName);\r
- }\r
-\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSimpleFileSystemFlush (\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
- BY_HANDLE_FILE_INFORMATION FileInfo;\r
- WIN_NT_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
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->IsDirectoryPath) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
-\r
- if (PrivateFile->IsOpenedByRead) {\r
- Status = EFI_ACCESS_DENIED;\r
- goto Done;\r
- }\r
-\r
- PrivateFile->WinNtThunk->GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo);\r
-\r
- if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
- Status = EFI_ACCESS_DENIED;\r
- goto Done;\r
- }\r
-\r
- Status = PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
- //\r
- // bugbug: - Use Windows error reporting.\r
- //\r
-}\r
-\r
-\r