From 068eac814d7f1a391d28505289b640bcab675004 Mon Sep 17 00:00:00 2001 From: klu2 Date: Wed, 27 Jun 2007 06:39:45 +0000 Subject: [PATCH] Add WinNtSimpleFileSystemDxe driver into Nt32Pkg. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2782 6f19259b-4bc3-4df7-8a09-765794883524 --- Nt32Pkg/Nt32.dsc | 3 +- .../WinNtSimpleFileSystemDxe/ComponentName.c | 229 ++ .../WinNtSimpleFileSystem.c | 2744 +++++++++++++++++ .../WinNtSimpleFileSystem.h | 592 ++++ .../WinNtSimpleFileSystem.inf | 118 + .../WinNtSimpleFileSystem.msa | 92 + 6 files changed, 3777 insertions(+), 1 deletion(-) create mode 100644 Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c create mode 100644 Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c create mode 100644 Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h create mode 100644 Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf create mode 100644 Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa diff --git a/Nt32Pkg/Nt32.dsc b/Nt32Pkg/Nt32.dsc index 0372542850..bd47ba6bbb 100644 --- a/Nt32Pkg/Nt32.dsc +++ b/Nt32Pkg/Nt32.dsc @@ -406,4 +406,5 @@ $(WORKSPACE)\Nt32Pkg\WinNtAutoScanPeim\WinNtAutoScan.inf $(WORKSPACE)\Nt32Pkg\WinNtBlockIoDxe\WinNtBlockIo.inf $(WORKSPACE)\Nt32Pkg\WinNtBusDriverDxe\WinNtBusDriver.inf - $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf \ No newline at end of file + $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf + $(WORKSPACE)\Nt32Pkg\WinNtSimpleFileSystemDxe\WinNtSimpleFileSystem.inf \ No newline at end of file diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c b/Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c new file mode 100644 index 0000000000..4cfb565320 --- /dev/null +++ b/Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c @@ -0,0 +1,229 @@ +/*++ + +Copyright (c) 2006, 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: + + ComponentName.c + +Abstract: + +--*/ +// +// The package level header files this module uses +// +#include +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#include "WinNtSimpleFileSystem.h" + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gWinNtSimpleFileSystemComponentName = { + WinNtSimpleFileSystemComponentNameGetDriverName, + WinNtSimpleFileSystemComponentNameGetControllerName, + "eng" +}; + +static EFI_UNICODE_STRING_TABLE mWinNtSimpleFileSystemDriverNameTable[] = { + { + "eng", + L"Windows Simple File System Driver" + }, + { + NULL, + NULL + } +}; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + Language - A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + DriverName - A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return LookupUnicodeString ( + Language, + gWinNtSimpleFileSystemComponentName.SupportedLanguages, + mWinNtSimpleFileSystemDriverNameTable, + DriverName + ); +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + ControllerName - A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language from the point of view of the driver specified + by This. + + Returns: + EFI_SUCCESS - The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllerHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gWinNtSimpleFileSystemDriverBinding.DriverBindingHandle, + &gEfiWinNtIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + &SimpleFileSystem, + gWinNtSimpleFileSystemDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem); + + return LookupUnicodeString ( + Language, + gWinNtSimpleFileSystemComponentName.SupportedLanguages, + Private->ControllerNameTable, + ControllerName + ); +} diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c new file mode 100644 index 0000000000..62cb47960d --- /dev/null +++ b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c @@ -0,0 +1,2744 @@ +/*++ + +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: + + WinNtSimpleFileSystem.c + +Abstract: + + Produce Simple File System abstractions for directories on your PC using Win32 APIs. + The configuration of what devices to mount or emulate comes from NT + 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. + +--*/ + +// +// The package level header files this module uses +// +#include +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#include "WinNtSimpleFileSystem.h" + +EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = { + WinNtSimpleFileSystemDriverBindingSupported, + WinNtSimpleFileSystemDriverBindingStart, + WinNtSimpleFileSystemDriverBindingStop, + 0xa, + NULL, + NULL +}; + +/** + The user Entry Point for module WinNtSimpleFileSystem. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeWinNtSimpleFileSystem( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install driver model protocol(s). + // + Status = EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gWinNtSimpleFileSystemDriverBinding, + ImageHandle, + &gWinNtSimpleFileSystemComponentName, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + + return Status; +} + +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 CHAR16 *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 + +--*/ +{ + CHAR16 *Pointer; + + if (StrLen (Str) < Count) { + ASSERT (0); + } + + if (Count != 0) { + for (Pointer = Str; *(Pointer + Count); Pointer++) { + *Pointer = *(Pointer + Count); + } + *Pointer = *(Pointer + Count); + } +} + + + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDriverBindingSupported ( + 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_WIN_NT_IO_PROTOCOL *WinNtIo; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiWinNtIoProtocolGuid, + &WinNtIo, + 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 (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) { + Status = EFI_SUCCESS; + } + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + ControllerHandle, + &gEfiWinNtIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDriverBindingStart ( + 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_WIN_NT_IO_PROTOCOL *WinNtIo; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + Private = NULL; + + // + // Open the IO Abstraction(s) needed + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiWinNtIoProtocolGuid, + &WinNtIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Validate GUID + // + if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Private = AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE)); + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + + goto Done; + } + + Private->Signature = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE; + Private->WinNtThunk = WinNtIo->WinNtThunk; + + Private->FilePath = WinNtIo->EnvString; + + Private->VolumeLabel = AllocatePool (StrSize (L"EFI_EMULATED")); + if (Private->VolumeLabel == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (Private->VolumeLabel, L"EFI_EMULATED"); + + Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + Private->SimpleFileSystem.OpenVolume = WinNtSimpleFileSystemOpenVolume; + + Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS); + + Private->ControllerNameTable = NULL; + + AddUnicodeString ( + "eng", + gWinNtSimpleFileSystemComponentName.SupportedLanguages, + &Private->ControllerNameTable, + WinNtIo->EnvString + ); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + &Private->SimpleFileSystem, + NULL + ); + +Done: + if (EFI_ERROR (Status)) { + + if (Private != NULL) { + + FreeUnicodeStringTable (Private->ControllerNameTable); + + FreePool (Private); + } + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiWinNtIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDriverBindingStop ( + 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; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + &SimpleFileSystem, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = WIN_NT_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, + &gEfiWinNtIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + if (!EFI_ERROR (Status)) { + // + // Free our instance data + // + FreeUnicodeStringTable (Private->ControllerNameTable); + + FreePool (Private); + } + + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemOpenVolume ( + 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; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This); + + PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE)); + if (PrivateFile == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath)); + if (PrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath)); + if (PrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (PrivateFile->FilePath, Private->FilePath); + StrCpy (PrivateFile->FileName, PrivateFile->FilePath); + PrivateFile->Signature = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE; + PrivateFile->WinNtThunk = Private->WinNtThunk; + PrivateFile->SimpleFileSystem = This; + PrivateFile->IsRootDirectory = TRUE; + PrivateFile->IsDirectoryPath = TRUE; + PrivateFile->IsOpenedByRead = TRUE; + PrivateFile->EfiFile.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + PrivateFile->EfiFile.Open = WinNtSimpleFileSystemOpen; + PrivateFile->EfiFile.Close = WinNtSimpleFileSystemClose; + PrivateFile->EfiFile.Delete = WinNtSimpleFileSystemDelete; + PrivateFile->EfiFile.Read = WinNtSimpleFileSystemRead; + PrivateFile->EfiFile.Write = WinNtSimpleFileSystemWrite; + PrivateFile->EfiFile.GetPosition = WinNtSimpleFileSystemGetPosition; + PrivateFile->EfiFile.SetPosition = WinNtSimpleFileSystemSetPosition; + PrivateFile->EfiFile.GetInfo = WinNtSimpleFileSystemGetInfo; + PrivateFile->EfiFile.SetInfo = WinNtSimpleFileSystemSetInfo; + PrivateFile->EfiFile.Flush = WinNtSimpleFileSystemFlush; + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + PrivateFile->IsValidFindBuf = FALSE; + + *Root = &PrivateFile->EfiFile; + + Status = EFI_SUCCESS; + +Done: + if (EFI_ERROR (Status)) { + if (PrivateFile) { + if (PrivateFile->FileName) { + FreePool (PrivateFile->FileName); + } + + if (PrivateFile->FilePath) { + FreePool (PrivateFile->FilePath); + } + + FreePool (PrivateFile); + } + } + + gBS->RestoreTPL (OldTpl); + + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemOpen ( + 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; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + WIN_NT_EFI_FILE_PRIVATE *NewPrivateFile; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EFI_STATUS Status; + CHAR16 *RealFileName; + CHAR16 *TempFileName; + CHAR16 *ParseFileName; + CHAR16 *GuardPointer; + CHAR16 TempChar; + DWORD LastError; + UINTN Count; + BOOLEAN LoopFinish; + UINTN InfoSize; + EFI_FILE_INFO *Info; + + // + // 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; + } + + // + // Init local variables + // + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + NewPrivateFile = NULL; + + // + // Allocate buffer for FileName as the passed in FileName may be read only + // + TempFileName = AllocatePool (StrSize (FileName)); + if (TempFileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + StrCpy (TempFileName, FileName); + FileName = TempFileName; + + // + // 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 = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root); + NewPrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root); + goto Done; + } + + if (FileName[StrLen (FileName) - 1] == L'\\') { + FileName[StrLen (FileName) - 1] = 0; + } + + // + // If file name does not equal to "." or "..", + // then we trim the leading/trailing blanks and trailing dots + // + if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0) { + // + // Trim leading blanks + // + Count = 0; + for (TempFileName = FileName; + *TempFileName != 0 && *TempFileName == L' '; + TempFileName++) { + Count++; + } + CutPrefix (FileName, Count); + // + // Trim trailing dots and blanks + // + for (TempFileName = FileName + StrLen (FileName) - 1; + TempFileName >= FileName && (*TempFileName == L' ' || *TempFileName == L'.'); + TempFileName--) { + ; + } + *(TempFileName + 1) = 0; + } + + // + // Attempt to open the file + // + NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE)); + if (NewPrivateFile == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE)); + + NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName)); + if (NewPrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + StrCpy (NewPrivateFile->FilePath, PrivateFile->FileName); + } else { + StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath); + } + + NewPrivateFile->FileName = AllocatePool (StrSize (NewPrivateFile->FilePath) + StrSize (L"\\") + StrSize (FileName)); + if (NewPrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + if (*FileName == L'\\') { + StrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath); + StrCat (NewPrivateFile->FileName, L"\\"); + StrCat (NewPrivateFile->FileName, FileName + 1); + } else { + StrCpy (NewPrivateFile->FileName, NewPrivateFile->FilePath); + if (StrCmp (FileName, L"") != 0) { + // + // In case the filename becomes empty, especially after trimming dots and blanks + // + StrCat (NewPrivateFile->FileName, L"\\"); + StrCat (NewPrivateFile->FileName, FileName); + } + } + + // + // Get rid of . and .., except leading . or .. + // + + // + // GuardPointer protect simplefilesystem root path not be destroyed + // + GuardPointer = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath); + + LoopFinish = FALSE; + + while (!LoopFinish) { + + LoopFinish = TRUE; + + for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) { + if (*ParseFileName == L'.' && + (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') && + *(ParseFileName - 1) == L'\\' + ) { + + // + // cut \. + // + CutPrefix (ParseFileName - 1, 2); + LoopFinish = FALSE; + break; + } + + if (*ParseFileName == L'.' && + *(ParseFileName + 1) == L'.' && + (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') && + *(ParseFileName - 1) == L'\\' + ) { + + ParseFileName--; + Count = 3; + + while (ParseFileName != GuardPointer) { + ParseFileName--; + Count++; + if (*ParseFileName == L'\\') { + break; + } + } + + // + // cut \.. and its left directory + // + CutPrefix (ParseFileName, Count); + LoopFinish = FALSE; + break; + } + } + } + + if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) { + NewPrivateFile->IsRootDirectory = TRUE; + FreePool (NewPrivateFile->FilePath); + FreePool (NewPrivateFile->FileName); + FreePool (NewPrivateFile); + goto OpenRoot; + } + + RealFileName = NewPrivateFile->FileName; + while (EfiStrChr (RealFileName, L'\\') != NULL) { + RealFileName = EfiStrChr (RealFileName, L'\\') + 1; + } + + TempChar = *(RealFileName - 1); + *(RealFileName - 1) = 0; + + FreePool (NewPrivateFile->FilePath); + NewPrivateFile->FilePath = NULL; + NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName)); + if (NewPrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName); + + *(RealFileName - 1) = TempChar; + + NewPrivateFile->IsRootDirectory = FALSE; + + // + // Test whether file or directory + // + if (OpenMode & EFI_FILE_MODE_CREATE) { + if (Attributes & EFI_FILE_DIRECTORY) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } else { + NewPrivateFile->LHandle = INVALID_HANDLE_VALUE; + NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) { + NewPrivateFile->IsDirectoryPath = FALSE; + NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle); + } else { + NewPrivateFile->IsDirectoryPath = TRUE; + } + + NewPrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + + if (OpenMode & EFI_FILE_MODE_WRITE) { + NewPrivateFile->IsOpenedByRead = FALSE; + } else { + NewPrivateFile->IsOpenedByRead = TRUE; + } + + Status = EFI_SUCCESS; + + // + // deal with directory + // + if (NewPrivateFile->IsDirectoryPath) { + + TempFileName = AllocatePool (StrSize (NewPrivateFile->FileName) + StrSize (L"\\*")); + if (TempFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (TempFileName, NewPrivateFile->FileName); + + if ((OpenMode & EFI_FILE_MODE_CREATE)) { + // + // Create a directory + // + if (!NewPrivateFile->WinNtThunk->CreateDirectory (TempFileName, NULL)) { + + LastError = PrivateFile->WinNtThunk->GetLastError (); + if (LastError != ERROR_ALREADY_EXISTS) { + FreePool (TempFileName); + Status = EFI_ACCESS_DENIED; + goto Done; + } + } + } + + NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile ( + TempFileName, + NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) { + + NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile ( + TempFileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->DirHandle); + NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE; + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_NOT_FOUND; + } + + goto Done; + } + + // + // Find the first file under it + // + StrCat (TempFileName, L"\\*"); + NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + NewPrivateFile->IsValidFindBuf = FALSE; + } else { + NewPrivateFile->IsValidFindBuf = TRUE; + } + } else { + // + // deal with file + // + if (!NewPrivateFile->IsOpenedByRead) { + NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_NOT_FOUND; + } else { + Status = EFI_ACCESS_DENIED; + NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle); + NewPrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + } + } else { + NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_NOT_FOUND; + } + } + } + + if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) { + // + // Set the attribute + // + InfoSize = 0; + Info = NULL; + + Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Info = AllocatePool (InfoSize); + if (Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + + if (EFI_ERROR (Status)) { + goto Done; + } + + Info->Attribute = Attributes; + + WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info); + } + +Done: ; + FreePool (FileName); + + if (EFI_ERROR (Status)) { + if (NewPrivateFile) { + if (NewPrivateFile->FileName) { + FreePool (NewPrivateFile->FileName); + } + + if (NewPrivateFile->FilePath) { + FreePool (NewPrivateFile->FilePath); + } + + FreePool (NewPrivateFile); + } + } else { + *NewHandle = &NewPrivateFile->EfiFile; + } + + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemClose ( + 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 +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + if (PrivateFile->IsDirectoryPath) { + PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle); + } else { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle); + } + + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + + if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + if (PrivateFile->FileName) { + FreePool (PrivateFile->FileName); + } + + FreePool (PrivateFile); + + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDelete ( + 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; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = EFI_WARN_DELETE_FAILURE; + + if (PrivateFile->IsDirectoryPath) { + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle); + } + + if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + if (PrivateFile->WinNtThunk->RemoveDirectory (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } else { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle); + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + + if (!PrivateFile->IsOpenedByRead) { + if (PrivateFile->WinNtThunk->DeleteFile (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } + } + + FreePool (PrivateFile->FileName); + FreePool (PrivateFile); + + gBS->RestoreTPL (OldTpl); + + return Status; +} + +STATIC +VOID +WinNtSystemTimeToEfiTime ( + IN SYSTEMTIME *SystemTime, + IN TIME_ZONE_INFORMATION *TimeZone, + 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 + +--*/ +{ + Time->Year = (UINT16) SystemTime->wYear; + Time->Month = (UINT8) SystemTime->wMonth; + Time->Day = (UINT8) SystemTime->wDay; + Time->Hour = (UINT8) SystemTime->wHour; + Time->Minute = (UINT8) SystemTime->wMinute; + Time->Second = (UINT8) SystemTime->wSecond; + Time->Nanosecond = (UINT32) SystemTime->wMilliseconds * 1000000; + Time->TimeZone = (INT16) TimeZone->Bias; + + if (TimeZone->StandardDate.wMonth) { + Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT; + } +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemRead ( + 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 +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + UINTN Index; + SYSTEMTIME SystemTime; + EFI_FILE_INFO *Info; + WCHAR *pw; + TIME_ZONE_INFORMATION TimeZone; + EFI_FILE_INFO *FileInfo; + UINT64 Pos; + UINT64 FileSize; + UINTN FileInfoSize; + EFI_TPL OldTpl; + + if (This == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (!PrivateFile->IsDirectoryPath) { + + if (This->GetPosition (This, &Pos) != EFI_SUCCESS) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO; + FileInfo = AllocatePool (FileInfoSize); + + Status = This->GetInfo ( + This, + &gEfiFileInfoGuid, + &FileInfoSize, + FileInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (FileInfo); + FileInfo = AllocatePool (FileInfoSize); + Status = This->GetInfo ( + This, + &gEfiFileInfoGuid, + &FileInfoSize, + FileInfo + ); + } + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + FileSize = FileInfo->FileSize; + + FreePool (FileInfo); + + if (Pos >= FileSize) { + *BufferSize = 0; + if (Pos == FileSize) { + Status = EFI_SUCCESS; + goto Done; + } else { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + Status = PrivateFile->WinNtThunk->ReadFile ( + PrivateFile->LHandle, + Buffer, + *BufferSize, + BufferSize, + NULL + ) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + goto Done; + } + + // + // Read on a directory. Perform a find next + // + if (!PrivateFile->IsValidFindBuf) { + *BufferSize = 0; + Status = EFI_SUCCESS; + goto Done; + } + + Size = SIZE_OF_EFI_FILE_INFO; + + NameSize = StrSize (PrivateFile->FindBuf.cFileName); + + ResultSize = Size + NameSize; + + Status = EFI_BUFFER_TOO_SMALL; + + if (*BufferSize >= ResultSize) { + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + + PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone); + + PrivateFile->WinNtThunk->FileTimeToLocalFileTime ( + &PrivateFile->FindBuf.ftCreationTime, + &PrivateFile->FindBuf.ftCreationTime + ); + + PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftCreationTime, &SystemTime); + + WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime); + + PrivateFile->WinNtThunk->FileTimeToLocalFileTime ( + &PrivateFile->FindBuf.ftLastWriteTime, + &PrivateFile->FindBuf.ftLastWriteTime + ); + + PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftLastWriteTime, &SystemTime); + + WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime); + + Info->FileSize = PrivateFile->FindBuf.nFileSizeLow; + + Info->PhysicalSize = PrivateFile->FindBuf.nFileSizeLow; + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) { + Info->Attribute |= EFI_FILE_ARCHIVE; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + Info->Attribute |= EFI_FILE_HIDDEN; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { + Info->Attribute |= EFI_FILE_SYSTEM; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + NameSize = NameSize / sizeof (WCHAR); + + pw = (WCHAR *) (((CHAR8 *) Buffer) + Size); + + for (Index = 0; Index < NameSize; Index++) { + pw[Index] = PrivateFile->FindBuf.cFileName[Index]; + } + + if (PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) { + PrivateFile->IsValidFindBuf = TRUE; + } else { + PrivateFile->IsValidFindBuf = FALSE; + } + } + + *BufferSize = ResultSize; + +Done: + gBS->RestoreTPL (OldTpl); + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemWrite ( + 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 +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + EFI_TPL OldTpl; + + if (This == NULL || BufferSize == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + Status = PrivateFile->WinNtThunk->WriteFile ( + PrivateFile->LHandle, + Buffer, + *BufferSize, + BufferSize, + NULL + ) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + +Done: + gBS->RestoreTPL (OldTpl); + return Status; + + // + // bugbug: need to access windows error reporting + // +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemSetPosition ( + 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; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + UINT32 PosLow; + UINT32 PosHigh; + CHAR16 *FileName; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + if (Position != 0) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + FileName = AllocatePool (StrSize (PrivateFile->FileName) + StrSize (L"\\*")); + if (FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (FileName, PrivateFile->FileName); + StrCat (FileName, L"\\*"); + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle); + } + + PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (FileName, &PrivateFile->FindBuf); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + PrivateFile->IsValidFindBuf = FALSE; + } else { + PrivateFile->IsValidFindBuf = TRUE; + } + + FreePool (FileName); + + Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + } else { + if (Position == (UINT64) -1) { + PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) 0, NULL, FILE_END); + } else { + PosHigh = (UINT32) RShiftU64 (Position, 32); + + PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, &PosHigh, FILE_BEGIN); + } + + Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + } + +Done: + gBS->RestoreTPL (OldTpl); + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemGetPosition ( + 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; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + INT32 PositionHigh; + UINT64 PosHigh64; + EFI_TPL OldTpl; + + if (This == NULL || Position == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + PositionHigh = 0; + PosHigh64 = 0; + + if (PrivateFile->IsDirectoryPath) { + + Status = EFI_UNSUPPORTED; + goto Done; + + } else { + + PositionHigh = 0; + *Position = PrivateFile->WinNtThunk->SetFilePointer ( + PrivateFile->LHandle, + 0, + &PositionHigh, + FILE_CURRENT + ); + + Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS; + if (EFI_ERROR (Status)) { + goto Done; + } + + PosHigh64 = PositionHigh; + *Position += LShiftU64 (PosHigh64, 32); + } + +Done: + gBS->RestoreTPL (OldTpl); + return Status; +} + +STATIC +EFI_STATUS +WinNtSimpleFileSystemFileInfo ( + IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile, + 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; + BY_HANDLE_FILE_INFORMATION FileInfo; + SYSTEMTIME SystemTime; + CHAR16 *RealFileName; + CHAR16 *TempPointer; + EFI_FILE_INFO *DirInfo; + UINTN ReadSize; + UINT64 Location; + EFI_STATUS DirStatus; + + + Size = SIZE_OF_EFI_FILE_INFO; + NameSize = StrSize (PrivateFile->FileName); + ResultSize = Size + NameSize; + + Status = EFI_BUFFER_TOO_SMALL; + if (*BufferSize >= ResultSize) { + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + PrivateFile->WinNtThunk->GetFileInformationByHandle ( + PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle, + &FileInfo + ); + Info->FileSize = FileInfo.nFileSizeLow; + Info->PhysicalSize = Info->FileSize; + + PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftCreationTime, &SystemTime); + Info->CreateTime.Year = SystemTime.wYear; + Info->CreateTime.Month = (UINT8) SystemTime.wMonth; + Info->CreateTime.Day = (UINT8) SystemTime.wDay; + Info->CreateTime.Hour = (UINT8) SystemTime.wHour; + Info->CreateTime.Minute = (UINT8) SystemTime.wMinute; + Info->CreateTime.Second = (UINT8) SystemTime.wSecond; + + PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastAccessTime, &SystemTime); + Info->LastAccessTime.Year = SystemTime.wYear; + Info->LastAccessTime.Month = (UINT8) SystemTime.wMonth; + Info->LastAccessTime.Day = (UINT8) SystemTime.wDay; + Info->LastAccessTime.Hour = (UINT8) SystemTime.wHour; + Info->LastAccessTime.Minute = (UINT8) SystemTime.wMinute; + Info->LastAccessTime.Second = (UINT8) SystemTime.wSecond; + + PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastWriteTime, &SystemTime); + Info->ModificationTime.Year = SystemTime.wYear; + Info->ModificationTime.Month = (UINT8) SystemTime.wMonth; + Info->ModificationTime.Day = (UINT8) SystemTime.wDay; + Info->ModificationTime.Hour = (UINT8) SystemTime.wHour; + Info->ModificationTime.Minute = (UINT8) SystemTime.wMinute; + Info->ModificationTime.Second = (UINT8) SystemTime.wSecond; + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) { + Info->Attribute |= EFI_FILE_ARCHIVE; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + Info->Attribute |= EFI_FILE_HIDDEN; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { + Info->Attribute |= EFI_FILE_SYSTEM; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + if (PrivateFile->IsDirectoryPath) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + RealFileName = PrivateFile->FileName; + TempPointer = RealFileName; + + while (*TempPointer) { + if (*TempPointer == '\\') { + RealFileName = TempPointer + 1; + } + + TempPointer++; + } + + if (PrivateFile->IsRootDirectory) { + *((CHAR8 *) Buffer + Size) = 0; + } else { + CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize); + } + + if (Info->Attribute & EFI_FILE_DIRECTORY) { + // + // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we + // need to do the same thing the caller would do to get the right value + // + ASSERT (PrivateFile->EfiFile.Read != NULL); + DirStatus = PrivateFile->EfiFile.GetPosition (&PrivateFile->EfiFile, &Location); + if (EFI_ERROR (DirStatus)) { + Location = 0; + } + + PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, 0); + Info->FileSize = 0; + do { + ReadSize = 0; + DirInfo = NULL; + DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo); + if (DirStatus == EFI_BUFFER_TOO_SMALL) { + DirInfo = AllocatePool (ReadSize); + if (DirInfo != NULL) { + // + // Read each dir entry to figure out how big the directory is + // + DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo); + if (!EFI_ERROR (DirStatus) && (ReadSize != 0)) { + Info->FileSize += ReadSize; + } + FreePool (DirInfo); + } + } + + } while (!EFI_ERROR (DirStatus) && (ReadSize != 0)); + + // + // reset the file possition back to the previous location + // + PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, Location); + } + } + + *BufferSize = ResultSize; + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemGetInfo ( + 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; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer; + UINT32 SectorsPerCluster; + UINT32 BytesPerSector; + UINT32 FreeClusters; + UINT32 TotalClusters; + UINT32 BytesPerCluster; + CHAR16 *DriveName; + BOOLEAN DriveNameFound; + BOOL NtStatus; + UINTN Index; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EFI_TPL OldTpl; + + if (This == NULL || InformationType == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + + Status = EFI_UNSUPPORTED; + + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer); + } + + 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; + } + + FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer; + FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + FileSystemInfoBuffer->ReadOnly = FALSE; + + // + // Try to get the drive name + // + DriveNameFound = FALSE; + DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1); + if (DriveName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (DriveName, PrivateFile->FilePath); + for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) { + ; + } + + if (DriveName[Index] == ':') { + DriveName[Index + 1] = '\\'; + DriveName[Index + 2] = 0; + DriveNameFound = TRUE; + } else if (DriveName[0] == '\\' && DriveName[1] == '\\') { + for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) { + ; + } + + if (DriveName[Index] == '\\') { + DriveNameFound = TRUE; + for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) { + ; + } + + DriveName[Index] = '\\'; + DriveName[Index + 1] = 0; + } + } + + // + // Try GetDiskFreeSpace first + // + NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace ( + DriveNameFound ? DriveName : NULL, + &SectorsPerCluster, + &BytesPerSector, + &FreeClusters, + &TotalClusters + ); + if (DriveName) { + FreePool (DriveName); + } + + if (NtStatus) { + // + // Succeeded + // + BytesPerCluster = BytesPerSector * SectorsPerCluster; + FileSystemInfoBuffer->VolumeSize = MultU64x32 (TotalClusters, BytesPerCluster); + FileSystemInfoBuffer->FreeSpace = MultU64x32 (FreeClusters, BytesPerCluster); + FileSystemInfoBuffer->BlockSize = BytesPerCluster; + + } else { + // + // try GetDiskFreeSpaceEx then + // + FileSystemInfoBuffer->BlockSize = 0; + NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx ( + PrivateFile->FilePath, + (PULARGE_INTEGER) (&FileSystemInfoBuffer->FreeSpace), + (PULARGE_INTEGER) (&FileSystemInfoBuffer->VolumeSize), + NULL + ); + if (!NtStatus) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel); + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + Status = EFI_SUCCESS; + } + + 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 +WinNtSimpleFileSystemSetInfo ( + 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 +{ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_INFO *OldFileInfo; + EFI_FILE_INFO *NewFileInfo; + EFI_STATUS Status; + UINTN OldInfoSize; + INTN NtStatus; + UINT32 NewAttr; + UINT32 OldAttr; + CHAR16 *OldFileName; + CHAR16 *NewFileName; + CHAR16 *TempFileName; + CHAR16 *CharPointer; + BOOLEAN AttrChangeFlag; + BOOLEAN NameChangeFlag; + BOOLEAN SizeChangeFlag; + BOOLEAN TimeChangeFlag; + UINT64 CurPos; + SYSTEMTIME NewCreationSystemTime; + SYSTEMTIME NewLastAccessSystemTime; + SYSTEMTIME NewLastWriteSystemTime; + FILETIME NewCreationFileTime; + FILETIME NewLastAccessFileTime; + FILETIME NewLastWriteFileTime; + WIN32_FIND_DATA FindBuf; + EFI_FILE_SYSTEM_INFO *NewFileSystemInfo; + EFI_TPL OldTpl; + + // + // 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 = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_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; + + FreePool (PrivateRoot->VolumeLabel); + PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel)); + if (PrivateRoot->VolumeLabel == NULL) { + Status = EFI_OUT_OF_RESOURCES; + 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 = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL); + + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + OldFileInfo = AllocatePool (OldInfoSize); + if (OldFileInfo == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo); + + if (EFI_ERROR (Status)) { + goto Done; + } + + OldFileName = AllocatePool (StrSize (PrivateFile->FileName)); + if (OldFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (OldFileName, PrivateFile->FileName); + + // + // Make full pathname from new filename and rootpath. + // + if (NewFileInfo->FileName[0] == '\\') { + NewFileName = AllocatePool (StrSize (PrivateRoot->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName)); + if (NewFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (NewFileName, PrivateRoot->FilePath); + StrCat (NewFileName, L"\\"); + StrCat (NewFileName, NewFileInfo->FileName + 1); + } else { + NewFileName = AllocatePool (StrSize (PrivateFile->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName)); + if (NewFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (NewFileName, PrivateFile->FilePath); + StrCat (NewFileName, L"\\"); + StrCat (NewFileName, NewFileInfo->FileName); + } + + // + // 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. + // + OldAttr = PrivateFile->WinNtThunk->GetFileAttributes (OldFileName); + + // + // 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; + } + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + if (PrivateFile->IsDirectoryPath) { + PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle); + } else { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle); + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + } + + if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + NtStatus = PrivateFile->WinNtThunk->MoveFile (OldFileName, NewFileName); + + if (NtStatus) { + // + // modify file name + // + FreePool (PrivateFile->FileName); + + PrivateFile->FileName = AllocatePool (StrSize (NewFileName)); + if (PrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpy (PrivateFile->FileName, NewFileName); + + TempFileName = AllocatePool (StrSize (NewFileName) + StrSize (L"\\*")); + + StrCpy (TempFileName, NewFileName); + + if (!PrivateFile->IsDirectoryPath) { + PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + FreePool (TempFileName); + + // + // Flush buffers just in case + // + if (PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) == 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } else { + PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + StrCat (TempFileName, L"\\*"); + PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf); + + FreePool (TempFileName); + } + } else { +Reopen: ; + Status = EFI_DEVICE_ERROR; + + NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr); + + if (!NtStatus) { + goto Done; + } + + TempFileName = AllocatePool (StrSize (OldFileName) + StrSize (L"\\*")); + + StrCpy (TempFileName, OldFileName); + + if (!PrivateFile->IsDirectoryPath) { + PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + } else { + PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + StrCat (TempFileName, L"\\*"); + PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf); + } + + FreePool (TempFileName); + + 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; + } + + Status = This->GetPosition (This, &CurPos); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = This->SetPosition (This, NewFileInfo->FileSize); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (PrivateFile->WinNtThunk->SetEndOfFile (PrivateFile->LHandle) == 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Status = This->SetPosition (This, CurPos); + if (EFI_ERROR (Status)) { + goto Done; + } + } + + // + // Time change + // + if (TimeChangeFlag) { + + NewCreationSystemTime.wYear = NewFileInfo->CreateTime.Year; + NewCreationSystemTime.wMonth = NewFileInfo->CreateTime.Month; + NewCreationSystemTime.wDay = NewFileInfo->CreateTime.Day; + NewCreationSystemTime.wHour = NewFileInfo->CreateTime.Hour; + NewCreationSystemTime.wMinute = NewFileInfo->CreateTime.Minute; + NewCreationSystemTime.wSecond = NewFileInfo->CreateTime.Second; + NewCreationSystemTime.wMilliseconds = 0; + + if (!PrivateFile->WinNtThunk->SystemTimeToFileTime ( + &NewCreationSystemTime, + &NewCreationFileTime + )) { + goto Done; + } + + NewLastAccessSystemTime.wYear = NewFileInfo->LastAccessTime.Year; + NewLastAccessSystemTime.wMonth = NewFileInfo->LastAccessTime.Month; + NewLastAccessSystemTime.wDay = NewFileInfo->LastAccessTime.Day; + NewLastAccessSystemTime.wHour = NewFileInfo->LastAccessTime.Hour; + NewLastAccessSystemTime.wMinute = NewFileInfo->LastAccessTime.Minute; + NewLastAccessSystemTime.wSecond = NewFileInfo->LastAccessTime.Second; + NewLastAccessSystemTime.wMilliseconds = 0; + + if (!PrivateFile->WinNtThunk->SystemTimeToFileTime ( + &NewLastAccessSystemTime, + &NewLastAccessFileTime + )) { + goto Done; + } + + NewLastWriteSystemTime.wYear = NewFileInfo->ModificationTime.Year; + NewLastWriteSystemTime.wMonth = NewFileInfo->ModificationTime.Month; + NewLastWriteSystemTime.wDay = NewFileInfo->ModificationTime.Day; + NewLastWriteSystemTime.wHour = NewFileInfo->ModificationTime.Hour; + NewLastWriteSystemTime.wMinute = NewFileInfo->ModificationTime.Minute; + NewLastWriteSystemTime.wSecond = NewFileInfo->ModificationTime.Second; + NewLastWriteSystemTime.wMilliseconds = 0; + + if (!PrivateFile->WinNtThunk->SystemTimeToFileTime ( + &NewLastWriteSystemTime, + &NewLastWriteFileTime + )) { + goto Done; + } + + if (!PrivateFile->WinNtThunk->SetFileTime ( + PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle, + &NewCreationFileTime, + &NewLastAccessFileTime, + &NewLastWriteFileTime + )) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + } + + // + // No matter about AttrChangeFlag, Attribute must be set. + // Because operation before may cause attribute change. + // + NewAttr = OldAttr; + + if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) { + NewAttr |= FILE_ATTRIBUTE_ARCHIVE; + } else { + NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE; + } + + if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) { + NewAttr |= FILE_ATTRIBUTE_HIDDEN; + } else { + NewAttr &= ~FILE_ATTRIBUTE_HIDDEN; + } + + if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) { + NewAttr |= FILE_ATTRIBUTE_SYSTEM; + } else { + NewAttr &= ~FILE_ATTRIBUTE_SYSTEM; + } + + if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) { + NewAttr |= FILE_ATTRIBUTE_READONLY; + } else { + NewAttr &= ~FILE_ATTRIBUTE_READONLY; + } + + NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr); + + if (!NtStatus) { + goto Reopen; + } + +Done: + if (OldFileInfo != NULL) { + FreePool (OldFileInfo); + } + + if (OldFileName != NULL) { + FreePool (OldFileName); + } + + if (NewFileName != NULL) { + FreePool (NewFileName); + } + + gBS->RestoreTPL (OldTpl); + return Status; +} + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemFlush ( + 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 +{ + BY_HANDLE_FILE_INFORMATION FileInfo; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_SUCCESS; + goto Done; + } + + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + PrivateFile->WinNtThunk->GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo); + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + Status = PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + +Done: + gBS->RestoreTPL (OldTpl); + return Status; + // + // bugbug: - Use Windows error reporting. + // +} + + diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h new file mode 100644 index 0000000000..cde6ad5c36 --- /dev/null +++ b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h @@ -0,0 +1,592 @@ +/*++ + +Copyright (c) 2006, 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: + + WinNtSimpleFileSystem.h + +Abstract: + + Produce Simple File System abstractions for a directory on your PC using Win32 APIs. + The configuration of what devices to mount or emulate comes from NT + 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. + +--*/ + +#ifndef _WIN_NT_SIMPLE_FILE_SYSTEM_H_ +#define _WIN_NT_SIMPLE_FILE_SYSTEM_H_ + + +#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'f', 's') + +typedef struct { + UINTN Signature; + EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem; + CHAR16 *FilePath; + CHAR16 *VolumeLabel; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE; + +#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \ + SimpleFileSystem, \ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \ + ) + +#define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('l', 'o', 'f', 's') + +// +// Bit definitions for EFI_TIME.Daylight +// +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +typedef struct { + UINTN Signature; + EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE EfiFile; + HANDLE LHandle; + HANDLE DirHandle; + BOOLEAN IsRootDirectory; + BOOLEAN IsDirectoryPath; + BOOLEAN IsOpenedByRead; + CHAR16 *FilePath; + WCHAR *FileName; + BOOLEAN IsValidFindBuf; + WIN32_FIND_DATA FindBuf; +} WIN_NT_EFI_FILE_PRIVATE; + +#define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + WIN_NT_EFI_FILE_PRIVATE, \ + EfiFile, \ + WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \ + ) + +// +// Global Protocol Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gWinNtSimpleFileSystemComponentName; + +// +// Driver Binding protocol member functions +// +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +/*++ + +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 +EFIAPI +WinNtSimpleFileSystemDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +/*++ + +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 +EFIAPI +WinNtSimpleFileSystemDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +/*++ + +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. + +--*/ +; + +// +// Simple File System protocol member functions +// +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemOpenVolume ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemOpen ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemClose ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemDelete ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemRead ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemWrite ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemSetPosition ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemGetPosition ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemGetInfo ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemSetInfo ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +WinNtSimpleFileSystemFlush ( + 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. + +--*/ +; + +#endif /* _WIN_NT_SIMPLE_FILE_SYSTEM_H_ */ + +/* eof - WinNtSimpleFileSystem.h */ diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf new file mode 100644 index 0000000000..625a5fd76e --- /dev/null +++ b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf @@ -0,0 +1,118 @@ +#/** @file +# Simple filesystem driver +# +# Produce Simple File System abstractions for directories on your PC using Win32 APIs. +# The configuration of what devices to mount or emulate comes from NT +# environment variables. The variables must be visible to the Microsoft* +# Developer Studio for them to work. +# 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WinNtSimpleFileSystem + FILE_GUID = 9C25E18B-76BA-43da-A132-DBB0997CEFEF + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeWinNtSimpleFileSystem + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# +# DRIVER_BINDING = gWinNtSimpleFileSystemDriverBinding +# COMPONENT_NAME = gWinNtSimpleFileSystemComponentName +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + ComponentName.c + WinNtSimpleFileSystem.c + WinNtSimpleFileSystem.h + +################################################################################ +# +# Includes Section - list of Include locations that are required for +# this module. +# +################################################################################ + +[Includes] + $(WORKSPACE)/MdePkg/Include/Library + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + Nt32Pkg/Nt32Pkg.dec + MdePkg/MdePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + UefiLib + UefiDriverEntryPoint + BaseLib + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + gEfiWinNtFileSystemGuid # ALWAYS_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiSimpleFileSystemProtocolGuid # PROTOCOL BY_START + gEfiWinNtIoProtocolGuid # PROTOCOL TO_START + diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa new file mode 100644 index 0000000000..c60e293be1 --- /dev/null +++ b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa @@ -0,0 +1,92 @@ + + + + WinNtSimpleFileSystem + UEFI_DRIVER + 9C25E18B-76BA-43da-A132-DBB0997CEFEF + 1.0 + Simple filesystem driver + Produce Simple File System abstractions for directories on your PC using Win32 APIs. + The configuration of what devices to mount or emulate comes from NT + environment variables. The variables must be visible to the Microsoft* + Developer Studio for them to work. + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 + false + WinNtSimpleFileSystem + + + + DebugLib + + + BaseLib + + + UefiDriverModelLib + + + UefiDriverEntryPoint + + + UefiLib + + + BaseMemoryLib + + + UefiBootServicesTableLib + + + MemoryAllocationLib + + + + WinNtSimpleFileSystem.h + WinNtSimpleFileSystem.c + ComponentName.c + + + + + + + + gEfiWinNtIoProtocolGuid + + + gEfiSimpleFileSystemProtocolGuid + + + + + gEfiWinNtFileSystemGuid + + + gEfiFileSystemInfoGuid + + + gEfiFileInfoGuid + + + gEfiFileSystemVolumeLabelInfoIdGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + gWinNtSimpleFileSystemDriverBinding + gWinNtSimpleFileSystemComponentName + + + \ No newline at end of file