summaryrefslogtreecommitdiff
path: root/Nt32Pkg/WinNtSimpleFileSystemDxe
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-06-27 06:39:45 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-06-27 06:39:45 +0000
commit068eac814d7f1a391d28505289b640bcab675004 (patch)
treedabb6023245a096e79005219ddc82a5cfb67db4d /Nt32Pkg/WinNtSimpleFileSystemDxe
parent5413e8e8aaebb5c2371c1ecf806570a5f654c282 (diff)
downloadedk2-platforms-068eac814d7f1a391d28505289b640bcab675004.tar.xz
Add WinNtSimpleFileSystemDxe driver into Nt32Pkg.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2782 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Nt32Pkg/WinNtSimpleFileSystemDxe')
-rw-r--r--Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c229
-rw-r--r--Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c2744
-rw-r--r--Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h592
-rw-r--r--Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf118
-rw-r--r--Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa92
5 files changed, 3775 insertions, 0 deletions
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 <Uefi.h>
+#include <WinNtDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Guid/FileSystemVolumeLabelInfo.h>
+#include <Protocol/WinNtIo.h>
+#include <Protocol/ComponentName.h>
+#include <Guid/FileInfo.h>
+#include <Protocol/DriverBinding.h>
+#include <Guid/FileSystemInfo.h>
+#include <Protocol/SimpleFileSystem.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#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 <Uefi.h>
+#include <WinNtDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Guid/FileSystemVolumeLabelInfo.h>
+#include <Protocol/WinNtIo.h>
+#include <Protocol/ComponentName.h>
+#include <Guid/FileInfo.h>
+#include <Protocol/DriverBinding.h>
+#include <Guid/FileSystemInfo.h>
+#include <Protocol/SimpleFileSystem.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>WinNtSimpleFileSystem</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>9C25E18B-76BA-43da-A132-DBB0997CEFEF</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Simple filesystem driver</Abstract>
+ <Description>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.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>WinNtSimpleFileSystem</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>WinNtSimpleFileSystem.h</Filename>
+ <Filename>WinNtSimpleFileSystem.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="0fb2aa2d-10d5-40a5-a9dc-060c12a4a3f3"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiWinNtIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiWinNtFileSystemGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileSystemInfoGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileInfoGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiFileSystemVolumeLabelInfoIdGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gWinNtSimpleFileSystemDriverBinding</DriverBinding>
+ <ComponentName>gWinNtSimpleFileSystemComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea> \ No newline at end of file