]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add WinNtSimpleFileSystemDxe driver into Nt32Pkg.
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jun 2007 06:39:45 +0000 (06:39 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 27 Jun 2007 06:39:45 +0000 (06:39 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2782 6f19259b-4bc3-4df7-8a09-765794883524

Nt32Pkg/Nt32.dsc
Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c [new file with mode: 0644]
Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c [new file with mode: 0644]
Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h [new file with mode: 0644]
Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf [new file with mode: 0644]
Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa [new file with mode: 0644]

index 03725428507ecbf1b5523f4c25a10cdea645807f..bd47ba6bbb807438479c53faeb80b935fafae65a 100644 (file)
   $(WORKSPACE)\Nt32Pkg\WinNtAutoScanPeim\WinNtAutoScan.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtBlockIoDxe\WinNtBlockIo.inf\r
   $(WORKSPACE)\Nt32Pkg\WinNtBusDriverDxe\WinNtBusDriver.inf\r
-  $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf
\ No newline at end of file
+  $(WORKSPACE)\Nt32Pkg\WinNtConsoleDxe\WinNtConsole.inf\r
+  $(WORKSPACE)\Nt32Pkg\WinNtSimpleFileSystemDxe\WinNtSimpleFileSystem.inf
\ No newline at end of file
diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c b/Nt32Pkg/WinNtSimpleFileSystemDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..4cfb565
--- /dev/null
@@ -0,0 +1,229 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/FileSystemVolumeLabelInfo.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Guid/FileInfo.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Guid/FileSystemInfo.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtSimpleFileSystem.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                                        *This,\r
+  IN  EFI_HANDLE                                                         ControllerHandle,\r
+  IN  EFI_HANDLE                                                         ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                                              *Language,\r
+  OUT CHAR16                                                             **ControllerName\r
+  );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gWinNtSimpleFileSystemComponentName = {\r
+  WinNtSimpleFileSystemComponentNameGetDriverName,\r
+  WinNtSimpleFileSystemComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mWinNtSimpleFileSystemDriverNameTable[] = {\r
+  {\r
+    "eng",\r
+    L"Windows Simple File System Driver"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  Arguments:\r
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    Language   - A pointer to a three character ISO 639-2 language identifier.\r
+                 This is the language of the driver name that that the caller \r
+                 is requesting, and it must match one of the languages specified\r
+                 in SupportedLanguages.  The number of languages supported by a \r
+                 driver is up to the driver writer.\r
+    DriverName - A pointer to the Unicode string to return.  This Unicode string\r
+                 is the name of the driver specified by This in the language \r
+                 specified by Language.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This\r
+                            and the language specified by Language was returned \r
+                            in DriverName.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - DriverName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gWinNtSimpleFileSystemComponentName.SupportedLanguages,\r
+          mWinNtSimpleFileSystemDriverNameTable,\r
+          DriverName\r
+          );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                                        *This,\r
+  IN  EFI_HANDLE                                                         ControllerHandle,\r
+  IN  EFI_HANDLE                                                         ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                                              *Language,\r
+  OUT CHAR16                                                             **ControllerName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the controller\r
+    that is being managed by an EFI Driver.\r
+\r
+  Arguments:\r
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    ControllerHandle - The handle of a controller that the driver specified by \r
+                       This is managing.  This handle specifies the controller \r
+                       whose name is to be returned.\r
+    ChildHandle      - The handle of the child controller to retrieve the name \r
+                       of.  This is an optional parameter that may be NULL.  It \r
+                       will be NULL for device drivers.  It will also be NULL \r
+                       for a bus drivers that wish to retrieve the name of the \r
+                       bus controller.  It will not be NULL for a bus driver \r
+                       that wishes to retrieve the name of a child controller.\r
+    Language         - A pointer to a three character ISO 639-2 language \r
+                       identifier.  This is the language of the controller name \r
+                       that that the caller is requesting, and it must match one\r
+                       of the languages specified in SupportedLanguages.  The \r
+                       number of languages supported by a driver is up to the \r
+                       driver writer.\r
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode\r
+                       string is the name of the controller specified by \r
+                       ControllerHandle and ChildHandle in the language specified\r
+                       by Language from the point of view of the driver specified\r
+                       by This. \r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the user readable name in the \r
+                            language specified by Language for the driver \r
+                            specified by This was returned in DriverName.\r
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing \r
+                            the controller specified by ControllerHandle and \r
+                            ChildHandle.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFileSystem;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
+\r
+  //\r
+  // This is a device driver, so ChildHandle must be NULL.\r
+  //\r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Make sure this driver is currently managing ControllerHandle\r
+  //\r
+  Status = EfiTestManagedDevice (\r
+             ControllerHandle,\r
+             gWinNtSimpleFileSystemDriverBinding.DriverBindingHandle,\r
+             &gEfiWinNtIoProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Get our context back\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &SimpleFileSystem,\r
+                  gWinNtSimpleFileSystemDriverBinding.DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);\r
+\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gWinNtSimpleFileSystemComponentName.SupportedLanguages,\r
+          Private->ControllerNameTable,\r
+          ControllerName\r
+          );\r
+}\r
diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c
new file mode 100644 (file)
index 0000000..62cb479
--- /dev/null
@@ -0,0 +1,2744 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  WinNtSimpleFileSystem.c\r
+\r
+Abstract:\r
+\r
+  Produce Simple File System abstractions for directories on your PC using Win32 APIs.\r
+  The configuration of what devices to mount or emulate comes from NT\r
+  environment variables. The variables must be visible to the Microsoft*\r
+  Developer Studio for them to work.\r
+\r
+  * Other names and brands may be claimed as the property of others.\r
+\r
+--*/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/FileSystemVolumeLabelInfo.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Guid/FileInfo.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Guid/FileSystemInfo.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "WinNtSimpleFileSystem.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {\r
+  WinNtSimpleFileSystemDriverBindingSupported,\r
+  WinNtSimpleFileSystemDriverBindingStart,\r
+  WinNtSimpleFileSystemDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+/**\r
+  The user Entry Point for module WinNtSimpleFileSystem. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeWinNtSimpleFileSystem(\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallAllDriverProtocols (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gWinNtSimpleFileSystemDriverBinding,\r
+             ImageHandle,\r
+             &gWinNtSimpleFileSystemComponentName,\r
+             NULL,\r
+             NULL\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
+\r
+CHAR16 *\r
+EfiStrChr (\r
+  IN CHAR16   *Str,\r
+  IN CHAR16   Chr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locate the first occurance of a character in a string.\r
+\r
+Arguments:\r
+\r
+  Str - Pointer to NULL terminated unicode string.\r
+  Chr - Character to locate.\r
+\r
+Returns:\r
+\r
+  If Str is NULL, then NULL is returned.\r
+  If Chr is not contained in Str, then NULL is returned.\r
+  If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.\r
+\r
+--*/\r
+{\r
+  if (Str == NULL) {\r
+    return Str;\r
+  }\r
+\r
+  while (*Str != '\0' && *Str != Chr) {\r
+    ++Str;\r
+  }\r
+\r
+  return (*Str == Chr) ? Str : NULL;\r
+}\r
+\r
+BOOLEAN\r
+IsZero (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Buffer  - TODO: add argument description\r
+  Length  - TODO: add argument description\r
+\r
+Returns:\r
+\r
+  TODO: add return values\r
+\r
+--*/\r
+{\r
+  if (Buffer == NULL || Length == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (*(UINT8 *) Buffer != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (Length > 1) {\r
+    if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+VOID\r
+CutPrefix (\r
+  IN  CHAR16  *Str,\r
+  IN  UINTN   Count\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Str   - TODO: add argument description\r
+  Count - TODO: add argument description\r
+\r
+Returns:\r
+\r
+  TODO: add return values\r
+\r
+--*/\r
+{\r
+  CHAR16  *Pointer;\r
+\r
+  if (StrLen (Str) < Count) {\r
+    ASSERT (0);\r
+  }\r
+\r
+  if (Count != 0) {\r
+    for (Pointer = Str; *(Pointer + Count); Pointer++) {\r
+      *Pointer = *(Pointer + Count);\r
+    }\r
+    *Pointer = *(Pointer + Count);\r
+  }\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check to see if the driver supports a given controller.\r
+\r
+Arguments:\r
+\r
+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle    - EFI handle of the controller to test.\r
+\r
+  RemainingDevicePath - Pointer to remaining portion of a device path.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS         - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver\r
+                        specified by This.\r
+\r
+  EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
+                        the driver specified by This.\r
+\r
+  EFI_ACCESS_DENIED   - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
+                        a different driver or an application that requires exclusive access.\r
+\r
+  EFI_UNSUPPORTED     - The device specified by ControllerHandle and RemainingDevicePath is not supported by the\r
+                        driver specified by This.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiWinNtIoProtocolGuid,\r
+                  &WinNtIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Make sure GUID is for a File System handle.\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
+  gBS->CloseProtocol (\r
+        ControllerHandle,\r
+        &gEfiWinNtIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        ControllerHandle\r
+        );\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
+  IN  EFI_HANDLE                    ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Starts a device controller or a bus controller.\r
+\r
+Arguments:\r
+\r
+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle    - EFI handle of the controller to start.\r
+\r
+  RemainingDevicePath - Pointer to remaining portion of a device path.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The device or bus controller has been started.\r
+\r
+  EFI_DEVICE_ERROR      - The device could not be started due to a device failure.\r
+\r
+  EFI_OUT_OF_RESOURCES  - The request could not be completed due to lack of resources.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_WIN_NT_IO_PROTOCOL            *WinNtIo;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
+\r
+  Private = NULL;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiWinNtIoProtocolGuid,\r
+                  &WinNtIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Validate GUID\r
+  //\r
+  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  Private = AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE));\r
+  if (Private == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+\r
+    goto Done;\r
+  }\r
+\r
+  Private->Signature  = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;\r
+  Private->WinNtThunk = WinNtIo->WinNtThunk;\r
+\r
+  Private->FilePath = WinNtIo->EnvString;\r
+\r
+  Private->VolumeLabel = AllocatePool (StrSize (L"EFI_EMULATED"));\r
+  if (Private->VolumeLabel == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  StrCpy (Private->VolumeLabel, L"EFI_EMULATED");\r
+\r
+  Private->SimpleFileSystem.Revision    = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
+  Private->SimpleFileSystem.OpenVolume  = WinNtSimpleFileSystemOpenVolume;\r
+\r
+  Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);\r
+\r
+  Private->ControllerNameTable = NULL;\r
+\r
+  AddUnicodeString (\r
+    "eng",\r
+    gWinNtSimpleFileSystemComponentName.SupportedLanguages,\r
+    &Private->ControllerNameTable,\r
+    WinNtIo->EnvString\r
+    );\r
+\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &Private->SimpleFileSystem,\r
+                  NULL\r
+                  );\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+\r
+    if (Private != NULL) {\r
+\r
+      FreeUnicodeStringTable (Private->ControllerNameTable);\r
+\r
+      FreePool (Private);\r
+    }\r
+\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiWinNtIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This              - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle  - A handle to the device to be stopped.\r
+\r
+  NumberOfChildren  - The number of child device handles in ChildHandleBuffer.\r
+\r
+  ChildHandleBuffer - An array of child device handles to be freed.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - The device has been stopped.\r
+\r
+  EFI_DEVICE_ERROR  - The device could not be stopped due to a device failure.\r
+\r
+--*/\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFileSystem;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
+\r
+  //\r
+  // Get our context back\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &SimpleFileSystem,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);\r
+\r
+  //\r
+  // Uninstall the Simple File System Protocol from ControllerHandle\r
+  //\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &Private->SimpleFileSystem,\r
+                  NULL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->CloseProtocol (\r
+                    ControllerHandle,\r
+                    &gEfiWinNtIoProtocolGuid,\r
+                    This->DriverBindingHandle,\r
+                    ControllerHandle\r
+                    );\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Free our instance data\r
+    //\r
+    FreeUnicodeStringTable (Private->ControllerNameTable);\r
+\r
+    FreePool (Private);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemOpenVolume (\r
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,\r
+  OUT EFI_FILE                        **Root\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Open the root directory on a volume.\r
+\r
+Arguments:\r
+\r
+  This  - A pointer to the volume to open.\r
+\r
+  Root  - A pointer to storage for the returned opened file handle of the root directory.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The volume was opened.\r
+\r
+  EFI_UNSUPPORTED       - The volume does not support the requested file system type.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_ACCESS_DENIED     - The service denied access to the file.\r
+\r
+  EFI_OUT_OF_RESOURCES  - The file volume could not be opened due to lack of resources.\r
+\r
+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS                        Status;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
+  EFI_TPL                           OldTpl;\r
+\r
+  if (This == NULL || Root == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  Private     = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
+  if (PrivateFile == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath));\r
+  if (PrivateFile->FileName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath));\r
+  if (PrivateFile->FilePath == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  StrCpy (PrivateFile->FilePath, Private->FilePath);\r
+  StrCpy (PrivateFile->FileName, PrivateFile->FilePath);\r
+  PrivateFile->Signature            = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;\r
+  PrivateFile->WinNtThunk           = Private->WinNtThunk;\r
+  PrivateFile->SimpleFileSystem     = This;\r
+  PrivateFile->IsRootDirectory      = TRUE;\r
+  PrivateFile->IsDirectoryPath      = TRUE;\r
+  PrivateFile->IsOpenedByRead       = TRUE;\r
+  PrivateFile->EfiFile.Revision     = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
+  PrivateFile->EfiFile.Open         = WinNtSimpleFileSystemOpen;\r
+  PrivateFile->EfiFile.Close        = WinNtSimpleFileSystemClose;\r
+  PrivateFile->EfiFile.Delete       = WinNtSimpleFileSystemDelete;\r
+  PrivateFile->EfiFile.Read         = WinNtSimpleFileSystemRead;\r
+  PrivateFile->EfiFile.Write        = WinNtSimpleFileSystemWrite;\r
+  PrivateFile->EfiFile.GetPosition  = WinNtSimpleFileSystemGetPosition;\r
+  PrivateFile->EfiFile.SetPosition  = WinNtSimpleFileSystemSetPosition;\r
+  PrivateFile->EfiFile.GetInfo      = WinNtSimpleFileSystemGetInfo;\r
+  PrivateFile->EfiFile.SetInfo      = WinNtSimpleFileSystemSetInfo;\r
+  PrivateFile->EfiFile.Flush        = WinNtSimpleFileSystemFlush;\r
+  PrivateFile->LHandle              = INVALID_HANDLE_VALUE;\r
+  PrivateFile->DirHandle            = INVALID_HANDLE_VALUE;\r
+  PrivateFile->IsValidFindBuf       = FALSE;\r
+\r
+  *Root = &PrivateFile->EfiFile;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    if (PrivateFile) {\r
+      if (PrivateFile->FileName) {\r
+        FreePool (PrivateFile->FileName);\r
+      }\r
+\r
+      if (PrivateFile->FilePath) {\r
+        FreePool (PrivateFile->FilePath);\r
+      }\r
+\r
+      FreePool (PrivateFile);\r
+    }\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemOpen (\r
+  IN  EFI_FILE  *This,\r
+  OUT EFI_FILE  **NewHandle,\r
+  IN  CHAR16    *FileName,\r
+  IN  UINT64    OpenMode,\r
+  IN  UINT64    Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Open a file relative to the source file location.\r
+\r
+Arguments:\r
+\r
+  This        - A pointer to the source file location.\r
+\r
+  NewHandle   - Pointer to storage for the new file handle.\r
+\r
+  FileName    - Pointer to the file name to be opened.\r
+\r
+  OpenMode    - File open mode information.\r
+\r
+  Attributes  - File creation attributes.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The file was opened.\r
+\r
+  EFI_NOT_FOUND         - The file could not be found in the volume.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_WRITE_PROTECTED   - The volume or file is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The service denied access to the file.\r
+\r
+  EFI_OUT_OF_RESOURCES  - Not enough resources were available to open the file.\r
+\r
+  EFI_VOLUME_FULL       - There is not enough space left to create the new file.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_FILE                          *Root;\r
+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
+  WIN_NT_EFI_FILE_PRIVATE           *NewPrivateFile;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
+  EFI_STATUS                        Status;\r
+  CHAR16                            *RealFileName;\r
+  CHAR16                            *TempFileName;\r
+  CHAR16                            *ParseFileName;\r
+  CHAR16                            *GuardPointer;\r
+  CHAR16                            TempChar;\r
+  DWORD                             LastError;\r
+  UINTN                             Count;\r
+  BOOLEAN                           LoopFinish;\r
+  UINTN                             InfoSize;\r
+  EFI_FILE_INFO                     *Info;\r
+\r
+  //\r
+  // Check for obvious invalid parameters.\r
+  //\r
+  if (This == NULL || NewHandle == NULL || FileName == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  switch (OpenMode) {\r
+  case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
+    if (Attributes &~EFI_FILE_VALID_ATTR) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (Attributes & EFI_FILE_READ_ONLY) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+  //\r
+  // fall through\r
+  //\r
+  case EFI_FILE_MODE_READ:\r
+  case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
+    break;\r
+\r
+  default:\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Init local variables\r
+  //\r
+  PrivateFile     = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+  PrivateRoot     = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
+  NewPrivateFile  = NULL;\r
+\r
+  //\r
+  // Allocate buffer for FileName as the passed in FileName may be read only\r
+  //\r
+  TempFileName = AllocatePool (StrSize (FileName));\r
+  if (TempFileName == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  StrCpy (TempFileName, FileName);\r
+  FileName = TempFileName;\r
+\r
+  //\r
+  // BUGBUG: assume an open of root\r
+  // if current location, return current data\r
+  //\r
+  if (StrCmp (FileName, L"\\") == 0 || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {\r
+    //\r
+    // BUGBUG: assume an open root\r
+    //\r
+OpenRoot:\r
+    Status          = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);\r
+    NewPrivateFile  = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);\r
+    goto Done;\r
+  }\r
+\r
+  if (FileName[StrLen (FileName) - 1] == L'\\') {\r
+    FileName[StrLen (FileName) - 1]  = 0;\r
+  }\r
+\r
+  //\r
+  // If file name does not equal to "." or "..",\r
+  // then we trim the leading/trailing blanks and trailing dots\r
+  //\r
+  if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0) {\r
+    //\r
+    // Trim leading blanks\r
+    //\r
+    Count = 0;\r
+    for (TempFileName = FileName;\r
+      *TempFileName != 0 && *TempFileName == L' ';\r
+      TempFileName++) {\r
+      Count++;\r
+    }\r
+    CutPrefix (FileName, Count);\r
+    //\r
+    // Trim trailing dots and blanks\r
+    //\r
+    for (TempFileName = FileName + StrLen (FileName) - 1;\r
+      TempFileName >= FileName && (*TempFileName == L' ' || *TempFileName == L'.');\r
+      TempFileName--) {\r
+      ;\r
+    }\r
+    *(TempFileName + 1) = 0;\r
+  }\r
+\r
+  //\r
+  // Attempt to open the file\r
+  //\r
+  NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
+  if (NewPrivateFile == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
+\r
+  NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName));\r
+  if (NewPrivateFile->FilePath == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+    StrCpy (NewPrivateFile->FilePath, PrivateFile->FileName);\r
+  } else {\r
+    StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath);\r
+  }\r
+\r
+  NewPrivateFile->FileName = AllocatePool (StrSize (NewPrivateFile->FilePath) + StrSize (L"\\") + StrSize (FileName));\r
+  if (NewPrivateFile->FileName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  if (*FileName == L'\\') {\r
+    StrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);\r
+    StrCat (NewPrivateFile->FileName, L"\\");\r
+    StrCat (NewPrivateFile->FileName, FileName + 1);\r
+  } else {\r
+    StrCpy (NewPrivateFile->FileName, NewPrivateFile->FilePath);\r
+    if (StrCmp (FileName, L"") != 0) {\r
+      //\r
+      // In case the filename becomes empty, especially after trimming dots and blanks\r
+      //\r
+      StrCat (NewPrivateFile->FileName, L"\\");\r
+      StrCat (NewPrivateFile->FileName, FileName);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get rid of . and .., except leading . or ..\r
+  //\r
+\r
+  //\r
+  // GuardPointer protect simplefilesystem root path not be destroyed\r
+  //\r
+  GuardPointer  = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath);\r
+\r
+  LoopFinish    = FALSE;\r
+\r
+  while (!LoopFinish) {\r
+\r
+    LoopFinish = TRUE;\r
+\r
+    for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {\r
+      if (*ParseFileName == L'.' &&\r
+          (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') &&\r
+          *(ParseFileName - 1) == L'\\'\r
+          ) {\r
+\r
+        //\r
+        // cut \.\r
+        //\r
+        CutPrefix (ParseFileName - 1, 2);\r
+        LoopFinish = FALSE;\r
+        break;\r
+      }\r
+\r
+      if (*ParseFileName == L'.' &&\r
+          *(ParseFileName + 1) == L'.' &&\r
+          (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') &&\r
+          *(ParseFileName - 1) == L'\\'\r
+          ) {\r
+\r
+        ParseFileName--;\r
+        Count = 3;\r
+\r
+        while (ParseFileName != GuardPointer) {\r
+          ParseFileName--;\r
+          Count++;\r
+          if (*ParseFileName == L'\\') {\r
+            break;\r
+          }\r
+        }\r
+\r
+        //\r
+        // cut \.. and its left directory\r
+        //\r
+        CutPrefix (ParseFileName, Count);\r
+        LoopFinish = FALSE;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
+    NewPrivateFile->IsRootDirectory = TRUE;\r
+    FreePool (NewPrivateFile->FilePath);\r
+    FreePool (NewPrivateFile->FileName);\r
+    FreePool (NewPrivateFile);\r
+    goto OpenRoot;\r
+  }\r
+\r
+  RealFileName = NewPrivateFile->FileName;\r
+  while (EfiStrChr (RealFileName, L'\\') != NULL) {\r
+    RealFileName = EfiStrChr (RealFileName, L'\\') + 1;\r
+  }\r
+\r
+  TempChar            = *(RealFileName - 1);\r
+  *(RealFileName - 1) = 0;\r
+\r
+  FreePool (NewPrivateFile->FilePath);\r
+  NewPrivateFile->FilePath = NULL;\r
+  NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName));\r
+  if (NewPrivateFile->FilePath == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName);\r
+\r
+  *(RealFileName - 1)             = TempChar;\r
+\r
+  NewPrivateFile->IsRootDirectory = FALSE;\r
+\r
+  //\r
+  // Test whether file or directory\r
+  //\r
+  if (OpenMode & EFI_FILE_MODE_CREATE) {\r
+    if (Attributes & EFI_FILE_DIRECTORY) {\r
+      NewPrivateFile->IsDirectoryPath = TRUE;\r
+    } else {\r
+      NewPrivateFile->IsDirectoryPath = FALSE;\r
+    }\r
+  } else {\r
+    NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+    NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                            NewPrivateFile->FileName,\r
+                                                            GENERIC_READ,\r
+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                            NULL,\r
+                                                            OPEN_EXISTING,\r
+                                                            0,\r
+                                                            NULL\r
+                                                            );\r
+\r
+    if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
+      NewPrivateFile->IsDirectoryPath = FALSE;\r
+      NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
+    } else {\r
+      NewPrivateFile->IsDirectoryPath = TRUE;\r
+    }\r
+\r
+    NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+  }\r
+\r
+  if (OpenMode & EFI_FILE_MODE_WRITE) {\r
+    NewPrivateFile->IsOpenedByRead = FALSE;\r
+  } else {\r
+    NewPrivateFile->IsOpenedByRead = TRUE;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // deal with directory\r
+  //\r
+  if (NewPrivateFile->IsDirectoryPath) {\r
+\r
+    TempFileName = AllocatePool (StrSize (NewPrivateFile->FileName) + StrSize (L"\\*"));\r
+    if (TempFileName == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (TempFileName, NewPrivateFile->FileName);\r
+\r
+    if ((OpenMode & EFI_FILE_MODE_CREATE)) {\r
+      //\r
+      // Create a directory\r
+      //\r
+      if (!NewPrivateFile->WinNtThunk->CreateDirectory (TempFileName, NULL)) {\r
+\r
+        LastError = PrivateFile->WinNtThunk->GetLastError ();\r
+        if (LastError != ERROR_ALREADY_EXISTS) {\r
+          FreePool (TempFileName);\r
+          Status = EFI_ACCESS_DENIED;\r
+          goto Done;\r
+        }\r
+      }\r
+    }\r
+\r
+    NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                              TempFileName,\r
+                                                              NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),\r
+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                              NULL,\r
+                                                              OPEN_EXISTING,\r
+                                                              FILE_FLAG_BACKUP_SEMANTICS,\r
+                                                              NULL\r
+                                                              );\r
+\r
+    if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) {\r
+\r
+      NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                                TempFileName,\r
+                                                                GENERIC_READ,\r
+                                                                FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                                NULL,\r
+                                                                OPEN_EXISTING,\r
+                                                                FILE_FLAG_BACKUP_SEMANTICS,\r
+                                                                NULL\r
+                                                                );\r
+\r
+      if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
+        NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->DirHandle);\r
+        NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
+        Status                    = EFI_ACCESS_DENIED;\r
+      } else {\r
+        Status = EFI_NOT_FOUND;\r
+      }\r
+\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Find the first file under it\r
+    //\r
+    StrCat (TempFileName, L"\\*");\r
+    NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);\r
+\r
+    if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+      NewPrivateFile->IsValidFindBuf = FALSE;\r
+    } else {\r
+      NewPrivateFile->IsValidFindBuf = TRUE;\r
+    }\r
+  } else {\r
+    //\r
+    // deal with file\r
+    //\r
+    if (!NewPrivateFile->IsOpenedByRead) {\r
+      NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                              NewPrivateFile->FileName,\r
+                                                              GENERIC_READ | GENERIC_WRITE,\r
+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                              NULL,\r
+                                                              (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,\r
+                                                              0,\r
+                                                              NULL\r
+                                                              );\r
+\r
+      if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+        NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                                NewPrivateFile->FileName,\r
+                                                                GENERIC_READ,\r
+                                                                FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                                NULL,\r
+                                                                OPEN_EXISTING,\r
+                                                                0,\r
+                                                                NULL\r
+                                                                );\r
+\r
+        if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+          Status = EFI_NOT_FOUND;\r
+        } else {\r
+          Status = EFI_ACCESS_DENIED;\r
+          NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
+          NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+        }\r
+      }\r
+    } else {\r
+      NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
+                                                              NewPrivateFile->FileName,\r
+                                                              GENERIC_READ,\r
+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                              NULL,\r
+                                                              OPEN_EXISTING,\r
+                                                              0,\r
+                                                              NULL\r
+                                                              );\r
+\r
+      if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+        Status = EFI_NOT_FOUND;\r
+      }\r
+    }\r
+  }\r
+\r
+  if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {\r
+    //\r
+    // Set the attribute\r
+    //\r
+    InfoSize  = 0;\r
+    Info      = NULL;\r
+\r
+    Status    = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
+\r
+    if (Status != EFI_BUFFER_TOO_SMALL) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    Info = AllocatePool (InfoSize);\r
+    if (Info == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    Info->Attribute = Attributes;\r
+\r
+    WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);\r
+  }\r
+\r
+Done: ;\r
+  FreePool (FileName);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    if (NewPrivateFile) {\r
+      if (NewPrivateFile->FileName) {\r
+        FreePool (NewPrivateFile->FileName);\r
+      }\r
+\r
+      if (NewPrivateFile->FilePath) {\r
+        FreePool (NewPrivateFile->FilePath);\r
+      }\r
+\r
+      FreePool (NewPrivateFile);\r
+    }\r
+  } else {\r
+    *NewHandle = &NewPrivateFile->EfiFile;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemClose (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Close the specified file handle.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to a returned opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - The file handle has been closed.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
+    if (PrivateFile->IsDirectoryPath) {\r
+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
+    } else {\r
+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
+    }\r
+\r
+    PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+  }\r
+\r
+  if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
+    PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
+    PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
+  }\r
+\r
+  if (PrivateFile->FileName) {\r
+    FreePool (PrivateFile->FileName);\r
+  }\r
+\r
+  FreePool (PrivateFile);\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDelete (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Close and delete a file.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to a returned opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             - The file handle was closed and deleted.\r
+\r
+  EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS              Status;\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  Status      = EFI_WARN_DELETE_FAILURE;\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
+    }\r
+\r
+    if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
+      PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    if (PrivateFile->WinNtThunk->RemoveDirectory (PrivateFile->FileName)) {\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  } else {\r
+    PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
+    PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+\r
+    if (!PrivateFile->IsOpenedByRead) {\r
+      if (PrivateFile->WinNtThunk->DeleteFile (PrivateFile->FileName)) {\r
+        Status = EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (PrivateFile->FileName);\r
+  FreePool (PrivateFile);\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+VOID\r
+WinNtSystemTimeToEfiTime (\r
+  IN SYSTEMTIME             *SystemTime,\r
+  IN TIME_ZONE_INFORMATION  *TimeZone,\r
+  OUT EFI_TIME              *Time\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  SystemTime  - TODO: add argument description\r
+  TimeZone    - TODO: add argument description\r
+  Time        - TODO: add argument description\r
+\r
+Returns:\r
+\r
+  TODO: add return values\r
+\r
+--*/\r
+{\r
+  Time->Year        = (UINT16) SystemTime->wYear;\r
+  Time->Month       = (UINT8) SystemTime->wMonth;\r
+  Time->Day         = (UINT8) SystemTime->wDay;\r
+  Time->Hour        = (UINT8) SystemTime->wHour;\r
+  Time->Minute      = (UINT8) SystemTime->wMinute;\r
+  Time->Second      = (UINT8) SystemTime->wSecond;\r
+  Time->Nanosecond  = (UINT32) SystemTime->wMilliseconds * 1000000;\r
+  Time->TimeZone    = (INT16) TimeZone->Bias;\r
+\r
+  if (TimeZone->StandardDate.wMonth) {\r
+    Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemRead (\r
+  IN     EFI_FILE  *This,\r
+  IN OUT UINTN     *BufferSize,\r
+  OUT    VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read data from a file.\r
+\r
+Arguments:\r
+\r
+  This        - Pointer to a returned open file handle.\r
+\r
+  BufferSize  - On input, the size of the Buffer.  On output, the number of bytes stored in the Buffer.\r
+\r
+  Buffer      - Pointer to the first byte of the read Buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data was read.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The supplied buffer size was too small to store the current directory entry.\r
+                          *BufferSize has been updated with the size needed to complete the request.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  EFI_STATUS              Status;\r
+  UINTN                   Size;\r
+  UINTN                   NameSize;\r
+  UINTN                   ResultSize;\r
+  UINTN                   Index;\r
+  SYSTEMTIME              SystemTime;\r
+  EFI_FILE_INFO           *Info;\r
+  WCHAR                   *pw;\r
+  TIME_ZONE_INFORMATION   TimeZone;\r
+  EFI_FILE_INFO           *FileInfo;\r
+  UINT64                  Pos;\r
+  UINT64                  FileSize;\r
+  UINTN                   FileInfoSize;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL || BufferSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  if (!PrivateFile->IsDirectoryPath) {\r
+\r
+    if (This->GetPosition (This, &Pos) != EFI_SUCCESS) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO;\r
+    FileInfo = AllocatePool (FileInfoSize);\r
+\r
+    Status = This->GetInfo (\r
+                    This,\r
+                    &gEfiFileInfoGuid,\r
+                    &FileInfoSize,\r
+                    FileInfo\r
+                    );\r
+\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      FreePool (FileInfo);\r
+      FileInfo = AllocatePool (FileInfoSize);\r
+      Status = This->GetInfo (\r
+                      This,\r
+                      &gEfiFileInfoGuid,\r
+                      &FileInfoSize,\r
+                      FileInfo\r
+                      );\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    FileSize = FileInfo->FileSize;\r
+\r
+    FreePool (FileInfo);\r
+\r
+    if (Pos >= FileSize) {\r
+      *BufferSize = 0;\r
+      if (Pos == FileSize) {\r
+        Status = EFI_SUCCESS;\r
+        goto Done;\r
+      } else {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    Status = PrivateFile->WinNtThunk->ReadFile (\r
+                                      PrivateFile->LHandle,\r
+                                      Buffer,\r
+                                      *BufferSize,\r
+                                      BufferSize,\r
+                                      NULL\r
+                                      ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Read on a directory.  Perform a find next\r
+  //\r
+  if (!PrivateFile->IsValidFindBuf) {\r
+    *BufferSize = 0;\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  Size        = SIZE_OF_EFI_FILE_INFO;\r
+\r
+  NameSize    = StrSize (PrivateFile->FindBuf.cFileName);\r
+\r
+  ResultSize  = Size + NameSize;\r
+\r
+  Status      = EFI_BUFFER_TOO_SMALL;\r
+\r
+  if (*BufferSize >= ResultSize) {\r
+    Status  = EFI_SUCCESS;\r
+\r
+    Info    = Buffer;\r
+    ZeroMem (Info, ResultSize);\r
+\r
+    Info->Size = ResultSize;\r
+\r
+    PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
+                              &PrivateFile->FindBuf.ftCreationTime,\r
+                              &PrivateFile->FindBuf.ftCreationTime\r
+                              );\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftCreationTime, &SystemTime);\r
+\r
+    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime);\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
+                              &PrivateFile->FindBuf.ftLastWriteTime,\r
+                              &PrivateFile->FindBuf.ftLastWriteTime\r
+                              );\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftLastWriteTime, &SystemTime);\r
+\r
+    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime);\r
+\r
+    Info->FileSize      = PrivateFile->FindBuf.nFileSizeLow;\r
+\r
+    Info->PhysicalSize  = PrivateFile->FindBuf.nFileSizeLow;\r
+\r
+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
+      Info->Attribute |= EFI_FILE_ARCHIVE;\r
+    }\r
+\r
+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
+      Info->Attribute |= EFI_FILE_HIDDEN;\r
+    }\r
+\r
+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
+      Info->Attribute |= EFI_FILE_SYSTEM;\r
+    }\r
+\r
+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
+      Info->Attribute |= EFI_FILE_READ_ONLY;\r
+    }\r
+\r
+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
+      Info->Attribute |= EFI_FILE_DIRECTORY;\r
+    }\r
+\r
+    NameSize  = NameSize / sizeof (WCHAR);\r
+\r
+    pw        = (WCHAR *) (((CHAR8 *) Buffer) + Size);\r
+\r
+    for (Index = 0; Index < NameSize; Index++) {\r
+      pw[Index] = PrivateFile->FindBuf.cFileName[Index];\r
+    }\r
+\r
+    if (PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) {\r
+      PrivateFile->IsValidFindBuf = TRUE;\r
+    } else {\r
+      PrivateFile->IsValidFindBuf = FALSE;\r
+    }\r
+  }\r
+\r
+  *BufferSize = ResultSize;\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemWrite (\r
+  IN     EFI_FILE  *This,\r
+  IN OUT UINTN     *BufferSize,\r
+  IN     VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write data to a file.\r
+\r
+Arguments:\r
+\r
+  This        - Pointer to an opened file handle.\r
+\r
+  BufferSize  - On input, the number of bytes in the Buffer to write to the file.  On output, the number of bytes\r
+                of data written to the file.\r
+\r
+  Buffer      - Pointer to the first by of data in the buffer to write to the file.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data was written to the file.\r
+\r
+  EFI_UNSUPPORTED       - Writes to an open directory are not supported.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  EFI_STATUS              Status;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  if (PrivateFile->IsOpenedByRead) {\r
+    Status = EFI_ACCESS_DENIED;\r
+    goto Done;\r
+  }\r
+\r
+  Status = PrivateFile->WinNtThunk->WriteFile (\r
+                                    PrivateFile->LHandle,\r
+                                    Buffer,\r
+                                    *BufferSize,\r
+                                    BufferSize,\r
+                                    NULL\r
+                                    ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+\r
+  //\r
+  // bugbug: need to access windows error reporting\r
+  //\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemSetPosition (\r
+  IN EFI_FILE  *This,\r
+  IN UINT64    Position\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set a file's current position.\r
+\r
+Arguments:\r
+\r
+  This      - Pointer to an opened file handle.\r
+\r
+  Position  - The byte position from the start of the file to set.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS     - The file position has been changed.\r
+\r
+  EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS              Status;\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  UINT32                  PosLow;\r
+  UINT32                  PosHigh;\r
+  CHAR16                  *FileName;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+    if (Position != 0) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    FileName = AllocatePool (StrSize (PrivateFile->FileName) + StrSize (L"\\*"));\r
+    if (FileName == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (FileName, PrivateFile->FileName);\r
+    StrCat (FileName, L"\\*");\r
+\r
+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
+    }\r
+\r
+    PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (FileName, &PrivateFile->FindBuf);\r
+\r
+    if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+      PrivateFile->IsValidFindBuf = FALSE;\r
+    } else {\r
+      PrivateFile->IsValidFindBuf = TRUE;\r
+    }\r
+\r
+    FreePool (FileName);\r
+\r
+    Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+  } else {\r
+    if (Position == (UINT64) -1) {\r
+      PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) 0, NULL, FILE_END);\r
+    } else {\r
+      PosHigh = (UINT32) RShiftU64 (Position, 32);\r
+\r
+      PosLow  = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, &PosHigh, FILE_BEGIN);\r
+    }\r
+\r
+    Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemGetPosition (\r
+  IN  EFI_FILE  *This,\r
+  OUT UINT64    *Position\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get a file's current position.\r
+\r
+Arguments:\r
+\r
+  This      - Pointer to an opened file handle.\r
+\r
+  Position  - Pointer to storage for the current position.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS     - The file position has been reported.\r
+\r
+  EFI_UNSUPPORTED - Not valid for directories.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS              Status;\r
+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
+  INT32                   PositionHigh;\r
+  UINT64                  PosHigh64;\r
+  EFI_TPL                 OldTpl;\r
+\r
+  if (This == NULL || Position == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+  PrivateFile   = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  PositionHigh  = 0;\r
+  PosHigh64     = 0;\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+\r
+  } else {\r
+\r
+    PositionHigh = 0;\r
+    *Position = PrivateFile->WinNtThunk->SetFilePointer (\r
+                                          PrivateFile->LHandle,\r
+                                          0,\r
+                                          &PositionHigh,\r
+                                          FILE_CURRENT\r
+                                          );\r
+\r
+    Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    PosHigh64 = PositionHigh;\r
+    *Position += LShiftU64 (PosHigh64, 32);\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+WinNtSimpleFileSystemFileInfo (\r
+  IN     WIN_NT_EFI_FILE_PRIVATE  *PrivateFile,\r
+  IN OUT UINTN                    *BufferSize,\r
+  OUT    VOID                     *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  PrivateFile - TODO: add argument description\r
+  BufferSize  - TODO: add argument description\r
+  Buffer      - TODO: add argument description\r
+\r
+Returns:\r
+\r
+  TODO: add return values\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINTN                       Size;\r
+  UINTN                       NameSize;\r
+  UINTN                       ResultSize;\r
+  EFI_FILE_INFO               *Info;\r
+  BY_HANDLE_FILE_INFORMATION  FileInfo;\r
+  SYSTEMTIME                  SystemTime;\r
+  CHAR16                      *RealFileName;\r
+  CHAR16                      *TempPointer;\r
+  EFI_FILE_INFO               *DirInfo;\r
+  UINTN                       ReadSize;\r
+  UINT64                      Location;\r
+  EFI_STATUS                  DirStatus;\r
+\r
+\r
+  Size        = SIZE_OF_EFI_FILE_INFO;\r
+  NameSize    = StrSize (PrivateFile->FileName);\r
+  ResultSize  = Size + NameSize;\r
+\r
+  Status      = EFI_BUFFER_TOO_SMALL;\r
+  if (*BufferSize >= ResultSize) {\r
+    Status  = EFI_SUCCESS;\r
+\r
+    Info    = Buffer;\r
+    ZeroMem (Info, ResultSize);\r
+\r
+    Info->Size = ResultSize;\r
+    PrivateFile->WinNtThunk->GetFileInformationByHandle (\r
+                              PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
+                              &FileInfo\r
+                              );\r
+    Info->FileSize      = FileInfo.nFileSizeLow;\r
+    Info->PhysicalSize  = Info->FileSize;\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftCreationTime, &SystemTime);\r
+    Info->CreateTime.Year   = SystemTime.wYear;\r
+    Info->CreateTime.Month  = (UINT8) SystemTime.wMonth;\r
+    Info->CreateTime.Day    = (UINT8) SystemTime.wDay;\r
+    Info->CreateTime.Hour   = (UINT8) SystemTime.wHour;\r
+    Info->CreateTime.Minute = (UINT8) SystemTime.wMinute;\r
+    Info->CreateTime.Second = (UINT8) SystemTime.wSecond;\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastAccessTime, &SystemTime);\r
+    Info->LastAccessTime.Year   = SystemTime.wYear;\r
+    Info->LastAccessTime.Month  = (UINT8) SystemTime.wMonth;\r
+    Info->LastAccessTime.Day    = (UINT8) SystemTime.wDay;\r
+    Info->LastAccessTime.Hour   = (UINT8) SystemTime.wHour;\r
+    Info->LastAccessTime.Minute = (UINT8) SystemTime.wMinute;\r
+    Info->LastAccessTime.Second = (UINT8) SystemTime.wSecond;\r
+\r
+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastWriteTime, &SystemTime);\r
+    Info->ModificationTime.Year   = SystemTime.wYear;\r
+    Info->ModificationTime.Month  = (UINT8) SystemTime.wMonth;\r
+    Info->ModificationTime.Day    = (UINT8) SystemTime.wDay;\r
+    Info->ModificationTime.Hour   = (UINT8) SystemTime.wHour;\r
+    Info->ModificationTime.Minute = (UINT8) SystemTime.wMinute;\r
+    Info->ModificationTime.Second = (UINT8) SystemTime.wSecond;\r
+\r
+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
+      Info->Attribute |= EFI_FILE_ARCHIVE;\r
+    }\r
+\r
+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
+      Info->Attribute |= EFI_FILE_HIDDEN;\r
+    }\r
+\r
+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
+      Info->Attribute |= EFI_FILE_READ_ONLY;\r
+    }\r
+\r
+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
+      Info->Attribute |= EFI_FILE_SYSTEM;\r
+    }\r
+\r
+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
+      Info->Attribute |= EFI_FILE_DIRECTORY;\r
+    }\r
+\r
+    if (PrivateFile->IsDirectoryPath) {\r
+      Info->Attribute |= EFI_FILE_DIRECTORY;\r
+    }\r
+\r
+    RealFileName  = PrivateFile->FileName;\r
+    TempPointer   = RealFileName;\r
+\r
+    while (*TempPointer) {\r
+      if (*TempPointer == '\\') {\r
+        RealFileName = TempPointer + 1;\r
+      }\r
+\r
+      TempPointer++;\r
+    }\r
+\r
+    if (PrivateFile->IsRootDirectory) {\r
+      *((CHAR8 *) Buffer + Size) = 0;\r
+    } else {\r
+      CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);\r
+    }\r
+\r
+    if (Info->Attribute & EFI_FILE_DIRECTORY) {\r
+      //\r
+      // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we \r
+      // need to do the same thing the caller would do to get the right value\r
+      //\r
+      ASSERT (PrivateFile->EfiFile.Read != NULL);\r
+      DirStatus = PrivateFile->EfiFile.GetPosition (&PrivateFile->EfiFile, &Location);\r
+      if (EFI_ERROR (DirStatus)) {\r
+        Location = 0;\r
+      }\r
+\r
+      PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, 0);\r
+      Info->FileSize = 0; \r
+      do {\r
+        ReadSize = 0;\r
+        DirInfo = NULL;\r
+        DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
+        if (DirStatus == EFI_BUFFER_TOO_SMALL) {\r
+          DirInfo = AllocatePool (ReadSize);\r
+          if (DirInfo != NULL) {\r
+            //\r
+            // Read each dir entry to figure out how big the directory is\r
+            //\r
+            DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
+            if (!EFI_ERROR (DirStatus) && (ReadSize != 0)) {\r
+              Info->FileSize += ReadSize;\r
+            }\r
+            FreePool (DirInfo);\r
+          }\r
+        }\r
+        \r
+      } while (!EFI_ERROR (DirStatus) && (ReadSize != 0));\r
+\r
+      //\r
+      // reset the file possition back to the previous location\r
+      //\r
+      PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, Location);\r
+    }\r
+  }\r
+\r
+  *BufferSize = ResultSize;\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemGetInfo (\r
+  IN     EFI_FILE  *This,\r
+  IN     EFI_GUID  *InformationType,\r
+  IN OUT UINTN     *BufferSize,\r
+  OUT    VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return information about a file or volume.\r
+\r
+Arguments:\r
+\r
+  This            - Pointer to an opened file handle.\r
+\r
+  InformationType - GUID describing the type of information to be returned.\r
+\r
+  BufferSize      - On input, the size of the information buffer.  On output, the number of bytes written to the\r
+                    information buffer.\r
+\r
+  Buffer          - Pointer to the first byte of the information buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The requested information has been written into the buffer.\r
+\r
+  EFI_UNSUPPORTED       - The InformationType is not known.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The buffer size was too small to contain the requested information.  The buffer size has\r
+                          been updated with the size needed to complete the requested operation.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS                        Status;\r
+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
+  EFI_FILE_SYSTEM_INFO              *FileSystemInfoBuffer;\r
+  UINT32                            SectorsPerCluster;\r
+  UINT32                            BytesPerSector;\r
+  UINT32                            FreeClusters;\r
+  UINT32                            TotalClusters;\r
+  UINT32                            BytesPerCluster;\r
+  CHAR16                            *DriveName;\r
+  BOOLEAN                           DriveNameFound;\r
+  BOOL                              NtStatus;\r
+  UINTN                             Index;\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
+  EFI_TPL                           OldTpl;\r
+\r
+  if (This == NULL || InformationType == NULL || BufferSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+  PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
+\r
+  Status      = EFI_UNSUPPORTED;\r
+\r
+  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
+    Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);\r
+  }\r
+\r
+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
+    if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
+      *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+      goto Done;\r
+    }\r
+\r
+    FileSystemInfoBuffer            = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
+    FileSystemInfoBuffer->Size      = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
+    FileSystemInfoBuffer->ReadOnly  = FALSE;\r
+\r
+    //\r
+    // Try to get the drive name\r
+    //\r
+    DriveNameFound  = FALSE;\r
+    DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1);\r
+    if (DriveName == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (DriveName, PrivateFile->FilePath);\r
+    for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) {\r
+      ;\r
+    }\r
+\r
+    if (DriveName[Index] == ':') {\r
+      DriveName[Index + 1]  = '\\';\r
+      DriveName[Index + 2]  = 0;\r
+      DriveNameFound        = TRUE;\r
+    } else if (DriveName[0] == '\\' && DriveName[1] == '\\') {\r
+      for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
+        ;\r
+      }\r
+\r
+      if (DriveName[Index] == '\\') {\r
+        DriveNameFound = TRUE;\r
+        for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
+          ;\r
+        }\r
+\r
+        DriveName[Index]      = '\\';\r
+        DriveName[Index + 1]  = 0;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Try GetDiskFreeSpace first\r
+    //\r
+    NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (\r
+                                          DriveNameFound ? DriveName : NULL,\r
+                                          &SectorsPerCluster,\r
+                                          &BytesPerSector,\r
+                                          &FreeClusters,\r
+                                          &TotalClusters\r
+                                          );\r
+    if (DriveName) {\r
+      FreePool (DriveName);\r
+    }\r
+\r
+    if (NtStatus) {\r
+      //\r
+      // Succeeded\r
+      //\r
+      BytesPerCluster                   = BytesPerSector * SectorsPerCluster;\r
+      FileSystemInfoBuffer->VolumeSize  = MultU64x32 (TotalClusters, BytesPerCluster);\r
+      FileSystemInfoBuffer->FreeSpace   = MultU64x32 (FreeClusters, BytesPerCluster);\r
+      FileSystemInfoBuffer->BlockSize   = BytesPerCluster;\r
+\r
+    } else {\r
+      //\r
+      // try GetDiskFreeSpaceEx then\r
+      //\r
+      FileSystemInfoBuffer->BlockSize = 0;\r
+      NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx (\r
+                                            PrivateFile->FilePath,\r
+                                            (PULARGE_INTEGER) (&FileSystemInfoBuffer->FreeSpace),\r
+                                            (PULARGE_INTEGER) (&FileSystemInfoBuffer->VolumeSize),\r
+                                            NULL\r
+                                            );\r
+      if (!NtStatus) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel);\r
+    *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
+    Status      = EFI_SUCCESS;\r
+  }\r
+\r
+  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
+    if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
+      *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel);\r
+    *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
+    Status      = EFI_SUCCESS;\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemSetInfo (\r
+  IN EFI_FILE         *This,\r
+  IN EFI_GUID         *InformationType,\r
+  IN UINTN            BufferSize,\r
+  IN VOID             *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set information about a file or volume.\r
+\r
+Arguments:\r
+\r
+  This            - Pointer to an opened file handle.\r
+\r
+  InformationType - GUID identifying the type of information to set.\r
+\r
+  BufferSize      - Number of bytes of data in the information buffer.\r
+\r
+  Buffer          - Pointer to the first byte of data in the information buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The file or volume information has been updated.\r
+\r
+  EFI_UNSUPPORTED       - The information identifier is not recognised.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+  EFI_BAD_BUFFER_SIZE   - The buffer size is smaller than the type indicated by InformationType.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
+  EFI_FILE_INFO                     *OldFileInfo;\r
+  EFI_FILE_INFO                     *NewFileInfo;\r
+  EFI_STATUS                        Status;\r
+  UINTN                             OldInfoSize;\r
+  INTN                              NtStatus;\r
+  UINT32                            NewAttr;\r
+  UINT32                            OldAttr;\r
+  CHAR16                            *OldFileName;\r
+  CHAR16                            *NewFileName;\r
+  CHAR16                            *TempFileName;\r
+  CHAR16                            *CharPointer;\r
+  BOOLEAN                           AttrChangeFlag;\r
+  BOOLEAN                           NameChangeFlag;\r
+  BOOLEAN                           SizeChangeFlag;\r
+  BOOLEAN                           TimeChangeFlag;\r
+  UINT64                            CurPos;\r
+  SYSTEMTIME                        NewCreationSystemTime;\r
+  SYSTEMTIME                        NewLastAccessSystemTime;\r
+  SYSTEMTIME                        NewLastWriteSystemTime;\r
+  FILETIME                          NewCreationFileTime;\r
+  FILETIME                          NewLastAccessFileTime;\r
+  FILETIME                          NewLastWriteFileTime;\r
+  WIN32_FIND_DATA                   FindBuf;\r
+  EFI_FILE_SYSTEM_INFO              *NewFileSystemInfo;\r
+  EFI_TPL                           OldTpl;\r
+\r
+  //\r
+  // Check for invalid parameters.\r
+  //\r
+  if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  //\r
+  // Initialise locals.\r
+  //\r
+  PrivateFile               = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+  PrivateRoot               = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
+\r
+  Status                    = EFI_UNSUPPORTED;\r
+  OldFileInfo               = NewFileInfo = NULL;\r
+  OldFileName               = NewFileName = NULL;\r
+  AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;\r
+\r
+  //\r
+  // Set file system information.\r
+  //\r
+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
+    if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
+      Status = EFI_BAD_BUFFER_SIZE;\r
+      goto Done;\r
+    }\r
+\r
+    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
+\r
+    FreePool (PrivateRoot->VolumeLabel);\r
+    PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel));\r
+    if (PrivateRoot->VolumeLabel == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel);\r
+\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Set volume label information.\r
+  //\r
+  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
+    if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
+      Status = EFI_BAD_BUFFER_SIZE;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer);\r
+\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  if (BufferSize < SIZE_OF_EFI_FILE_INFO) {\r
+    Status = EFI_BAD_BUFFER_SIZE;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Set file/directory information.\r
+  //\r
+\r
+  //\r
+  // Check for invalid set file information parameters.\r
+  //\r
+  NewFileInfo = (EFI_FILE_INFO *) Buffer;\r
+\r
+  if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||\r
+      (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||\r
+      (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)\r
+      ) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // bugbug: - This is not safe.  We need something like EfiStrMaxSize()\r
+  // that would have an additional parameter that would be the size\r
+  // of the string array just in case there are no NULL characters in\r
+  // the string array.\r
+  //\r
+  //\r
+  // Get current file information so we can determine what kind\r
+  // of change request this is.\r
+  //\r
+  OldInfoSize = 0;\r
+  Status      = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL);\r
+\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  OldFileInfo = AllocatePool (OldInfoSize);\r
+  if (OldFileInfo == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  OldFileName = AllocatePool (StrSize (PrivateFile->FileName));\r
+  if (OldFileName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  StrCpy (OldFileName, PrivateFile->FileName);\r
+\r
+  //\r
+  // Make full pathname from new filename and rootpath.\r
+  //\r
+  if (NewFileInfo->FileName[0] == '\\') {\r
+    NewFileName = AllocatePool (StrSize (PrivateRoot->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
+    if (NewFileName == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (NewFileName, PrivateRoot->FilePath);\r
+    StrCat (NewFileName, L"\\");\r
+    StrCat (NewFileName, NewFileInfo->FileName + 1);\r
+  } else {\r
+    NewFileName = AllocatePool (StrSize (PrivateFile->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
+    if (NewFileName == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    StrCpy (NewFileName, PrivateFile->FilePath);\r
+    StrCat (NewFileName, L"\\");\r
+    StrCat (NewFileName, NewFileInfo->FileName);\r
+  }\r
+\r
+  //\r
+  // Is there an attribute change request?\r
+  //\r
+  if (NewFileInfo->Attribute != OldFileInfo->Attribute) {\r
+    if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    AttrChangeFlag = TRUE;\r
+  }\r
+\r
+  //\r
+  // Is there a name change request?\r
+  // bugbug: - Need EfiStrCaseCmp()\r
+  //\r
+  if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {\r
+    NameChangeFlag = TRUE;\r
+  }\r
+\r
+  //\r
+  // Is there a size change request?\r
+  //\r
+  if (NewFileInfo->FileSize != OldFileInfo->FileSize) {\r
+    SizeChangeFlag = TRUE;\r
+  }\r
+\r
+  //\r
+  // Is there a time stamp change request?\r
+  //\r
+  if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&\r
+      CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))\r
+        ) {\r
+    TimeChangeFlag = TRUE;\r
+  } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&\r
+           CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))\r
+            ) {\r
+    TimeChangeFlag = TRUE;\r
+  } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&\r
+           CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))\r
+            ) {\r
+    TimeChangeFlag = TRUE;\r
+  }\r
+\r
+  //\r
+  // All done if there are no change requests being made.\r
+  //\r
+  if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Set file or directory information.\r
+  //\r
+  OldAttr = PrivateFile->WinNtThunk->GetFileAttributes (OldFileName);\r
+\r
+  //\r
+  // Name change.\r
+  //\r
+  if (NameChangeFlag) {\r
+    //\r
+    // Close the handles first\r
+    //\r
+    if (PrivateFile->IsOpenedByRead) {\r
+      Status = EFI_ACCESS_DENIED;\r
+      goto Done;\r
+    }\r
+\r
+    for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {\r
+    }\r
+\r
+    if (*CharPointer != 0) {\r
+      Status = EFI_ACCESS_DENIED;\r
+      goto Done;\r
+    }\r
+\r
+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
+      if (PrivateFile->IsDirectoryPath) {\r
+        PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
+      } else {\r
+        PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
+        PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
+      }\r
+    }\r
+\r
+    if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
+      PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    NtStatus = PrivateFile->WinNtThunk->MoveFile (OldFileName, NewFileName);\r
+\r
+    if (NtStatus) {\r
+      //\r
+      // modify file name\r
+      //\r
+      FreePool (PrivateFile->FileName);\r
+\r
+      PrivateFile->FileName = AllocatePool (StrSize (NewFileName));\r
+      if (PrivateFile->FileName == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      StrCpy (PrivateFile->FileName, NewFileName);\r
+\r
+      TempFileName = AllocatePool (StrSize (NewFileName) + StrSize (L"\\*"));\r
+\r
+      StrCpy (TempFileName, NewFileName);\r
+\r
+      if (!PrivateFile->IsDirectoryPath) {\r
+       PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
+                                                          TempFileName,\r
+                                                          PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
+                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                          NULL,\r
+                                                          OPEN_EXISTING,\r
+                                                          0,\r
+                                                          NULL\r
+                                                          );\r
+\r
+        FreePool (TempFileName);\r
+\r
+        //\r
+        //  Flush buffers just in case\r
+        //\r
+        if (PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) == 0) {\r
+          Status = EFI_DEVICE_ERROR;\r
+          goto Done;\r
+        }\r
+      } else {\r
+        PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
+                                                            TempFileName,\r
+                                                            PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                            NULL,\r
+                                                            OPEN_EXISTING,\r
+                                                            FILE_FLAG_BACKUP_SEMANTICS,\r
+                                                            NULL\r
+                                                            );\r
+\r
+        StrCat (TempFileName, L"\\*");\r
+        PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
+\r
+        FreePool (TempFileName);\r
+      }\r
+    } else {\r
+Reopen: ;\r
+      Status    = EFI_DEVICE_ERROR;\r
+\r
+      NtStatus  = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr);\r
+\r
+      if (!NtStatus) {\r
+        goto Done;\r
+      }\r
+\r
+      TempFileName = AllocatePool (StrSize (OldFileName) + StrSize (L"\\*"));\r
+\r
+      StrCpy (TempFileName, OldFileName);\r
+\r
+      if (!PrivateFile->IsDirectoryPath) {\r
+        PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
+                                                          TempFileName,\r
+                                                          PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
+                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                          NULL,\r
+                                                          OPEN_EXISTING,\r
+                                                          0,\r
+                                                          NULL\r
+                                                          );\r
+      } else {\r
+        PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
+                                                            TempFileName,\r
+                                                            PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                            NULL,\r
+                                                            OPEN_EXISTING,\r
+                                                            FILE_FLAG_BACKUP_SEMANTICS,\r
+                                                            NULL\r
+                                                            );\r
+\r
+        StrCat (TempFileName, L"\\*");\r
+        PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
+      }\r
+\r
+      FreePool (TempFileName);\r
+\r
+      goto Done;\r
+\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Size change\r
+  //\r
+  if (SizeChangeFlag) {\r
+    if (PrivateFile->IsDirectoryPath) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
+      Status = EFI_ACCESS_DENIED;\r
+      goto Done;\r
+    }\r
+\r
+    Status = This->GetPosition (This, &CurPos);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    Status = This->SetPosition (This, NewFileInfo->FileSize);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (PrivateFile->WinNtThunk->SetEndOfFile (PrivateFile->LHandle) == 0) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    Status = This->SetPosition (This, CurPos);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Time change\r
+  //\r
+  if (TimeChangeFlag) {\r
+\r
+    NewCreationSystemTime.wYear         = NewFileInfo->CreateTime.Year;\r
+    NewCreationSystemTime.wMonth        = NewFileInfo->CreateTime.Month;\r
+    NewCreationSystemTime.wDay          = NewFileInfo->CreateTime.Day;\r
+    NewCreationSystemTime.wHour         = NewFileInfo->CreateTime.Hour;\r
+    NewCreationSystemTime.wMinute       = NewFileInfo->CreateTime.Minute;\r
+    NewCreationSystemTime.wSecond       = NewFileInfo->CreateTime.Second;\r
+    NewCreationSystemTime.wMilliseconds = 0;\r
+\r
+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
+                                    &NewCreationSystemTime,\r
+                                    &NewCreationFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
+    NewLastAccessSystemTime.wYear         = NewFileInfo->LastAccessTime.Year;\r
+    NewLastAccessSystemTime.wMonth        = NewFileInfo->LastAccessTime.Month;\r
+    NewLastAccessSystemTime.wDay          = NewFileInfo->LastAccessTime.Day;\r
+    NewLastAccessSystemTime.wHour         = NewFileInfo->LastAccessTime.Hour;\r
+    NewLastAccessSystemTime.wMinute       = NewFileInfo->LastAccessTime.Minute;\r
+    NewLastAccessSystemTime.wSecond       = NewFileInfo->LastAccessTime.Second;\r
+    NewLastAccessSystemTime.wMilliseconds = 0;\r
+\r
+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
+                                    &NewLastAccessSystemTime,\r
+                                    &NewLastAccessFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
+    NewLastWriteSystemTime.wYear          = NewFileInfo->ModificationTime.Year;\r
+    NewLastWriteSystemTime.wMonth         = NewFileInfo->ModificationTime.Month;\r
+    NewLastWriteSystemTime.wDay           = NewFileInfo->ModificationTime.Day;\r
+    NewLastWriteSystemTime.wHour          = NewFileInfo->ModificationTime.Hour;\r
+    NewLastWriteSystemTime.wMinute        = NewFileInfo->ModificationTime.Minute;\r
+    NewLastWriteSystemTime.wSecond        = NewFileInfo->ModificationTime.Second;\r
+    NewLastWriteSystemTime.wMilliseconds  = 0;\r
+\r
+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
+                                    &NewLastWriteSystemTime,\r
+                                    &NewLastWriteFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
+    if (!PrivateFile->WinNtThunk->SetFileTime (\r
+                                    PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
+                                    &NewCreationFileTime,\r
+                                    &NewLastAccessFileTime,\r
+                                    &NewLastWriteFileTime\r
+                                    )) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+  }\r
+\r
+  //\r
+  // No matter about AttrChangeFlag, Attribute must be set.\r
+  // Because operation before may cause attribute change.\r
+  //\r
+  NewAttr = OldAttr;\r
+\r
+  if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) {\r
+    NewAttr |= FILE_ATTRIBUTE_ARCHIVE;\r
+  } else {\r
+    NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE;\r
+  }\r
+\r
+  if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) {\r
+    NewAttr |= FILE_ATTRIBUTE_HIDDEN;\r
+  } else {\r
+    NewAttr &= ~FILE_ATTRIBUTE_HIDDEN;\r
+  }\r
+\r
+  if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) {\r
+    NewAttr |= FILE_ATTRIBUTE_SYSTEM;\r
+  } else {\r
+    NewAttr &= ~FILE_ATTRIBUTE_SYSTEM;\r
+  }\r
+\r
+  if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
+    NewAttr |= FILE_ATTRIBUTE_READONLY;\r
+  } else {\r
+    NewAttr &= ~FILE_ATTRIBUTE_READONLY;\r
+  }\r
+\r
+  NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr);\r
+\r
+  if (!NtStatus) {\r
+    goto Reopen;\r
+  }\r
+\r
+Done:\r
+  if (OldFileInfo != NULL) {\r
+    FreePool (OldFileInfo);\r
+  }\r
+\r
+  if (OldFileName != NULL) {\r
+    FreePool (OldFileName);\r
+  }\r
+\r
+  if (NewFileName != NULL) {\r
+    FreePool (NewFileName);\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemFlush (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Flush all modified data to the media.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to an opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data has been flushed.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures have been corrupted.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+--*/\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  BY_HANDLE_FILE_INFORMATION  FileInfo;\r
+  WIN_NT_EFI_FILE_PRIVATE     *PrivateFile;\r
+  EFI_STATUS                  Status;\r
+  EFI_TPL                     OldTpl;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  if (PrivateFile->IsDirectoryPath) {\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  if (PrivateFile->IsOpenedByRead) {\r
+    Status = EFI_ACCESS_DENIED;\r
+    goto Done;\r
+  }\r
+\r
+  PrivateFile->WinNtThunk->GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo);\r
+\r
+  if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
+    Status = EFI_ACCESS_DENIED;\r
+    goto Done;\r
+  }\r
+\r
+  Status = PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+  //\r
+  // bugbug: - Use Windows error reporting.\r
+  //\r
+}\r
+\r
+\r
diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.h
new file mode 100644 (file)
index 0000000..cde6ad5
--- /dev/null
@@ -0,0 +1,592 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  WinNtSimpleFileSystem.h\r
+\r
+Abstract:\r
+\r
+  Produce Simple File System abstractions for a directory on your PC using Win32 APIs.\r
+  The configuration of what devices to mount or emulate comes from NT \r
+  environment variables. The variables must be visible to the Microsoft* \r
+  Developer Studio for them to work.\r
+\r
+  * Other names and brands may be claimed as the property of others.\r
+\r
+--*/\r
+\r
+#ifndef _WIN_NT_SIMPLE_FILE_SYSTEM_H_\r
+#define _WIN_NT_SIMPLE_FILE_SYSTEM_H_\r
+\r
+\r
+#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'f', 's')\r
+\r
+typedef struct {\r
+  UINTN                           Signature;\r
+  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;\r
+  CHAR16                          *FilePath;\r
+  CHAR16                          *VolumeLabel;\r
+  EFI_UNICODE_STRING_TABLE        *ControllerNameTable;\r
+} WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE;\r
+\r
+#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \\r
+  CR (a, \\r
+      WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \\r
+      SimpleFileSystem, \\r
+      WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \\r
+      )\r
+\r
+#define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('l', 'o', 'f', 's')\r
+\r
+//\r
+// Bit definitions for EFI_TIME.Daylight\r
+//\r
+#define EFI_TIME_ADJUST_DAYLIGHT  0x01\r
+#define EFI_TIME_IN_DAYLIGHT      0x02\r
+\r
+typedef struct {\r
+  UINTN                           Signature;\r
+  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;\r
+  EFI_FILE                        EfiFile;\r
+  HANDLE                          LHandle;\r
+  HANDLE                          DirHandle;\r
+  BOOLEAN                         IsRootDirectory;\r
+  BOOLEAN                         IsDirectoryPath;\r
+  BOOLEAN                         IsOpenedByRead;\r
+  CHAR16                          *FilePath;\r
+  WCHAR                           *FileName;\r
+  BOOLEAN                         IsValidFindBuf;\r
+  WIN32_FIND_DATA                 FindBuf;\r
+} WIN_NT_EFI_FILE_PRIVATE;\r
+\r
+#define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \\r
+  CR (a, \\r
+      WIN_NT_EFI_FILE_PRIVATE, \\r
+      EfiFile, \\r
+      WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \\r
+      )\r
+\r
+//\r
+// Global Protocol Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtSimpleFileSystemDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtSimpleFileSystemComponentName;\r
+\r
+//\r
+// Driver Binding protocol member functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check to see if the driver supports a given controller.\r
+\r
+Arguments:\r
+\r
+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle    - EFI handle of the controller to test.\r
+\r
+  RemainingDevicePath - Pointer to remaining portion of a device path.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS         - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver\r
+                        specified by This.\r
+\r
+  EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
+                        the driver specified by This.\r
+\r
+  EFI_ACCESS_DENIED   - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
+                        a different driver or an application that requires exclusive access.\r
+\r
+  EFI_UNSUPPORTED     - The device specified by ControllerHandle and RemainingDevicePath is not supported by the\r
+                        driver specified by This.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
+  IN  EFI_HANDLE                    ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Starts a device controller or a bus controller.\r
+\r
+Arguments:\r
+\r
+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle    - EFI handle of the controller to start.\r
+\r
+  RemainingDevicePath - Pointer to remaining portion of a device path.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The device or bus controller has been started.\r
+\r
+  EFI_DEVICE_ERROR      - The device could not be started due to a device failure.\r
+\r
+  EFI_OUT_OF_RESOURCES  - The request could not be completed due to lack of resources.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This              - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
+\r
+  ControllerHandle  - A handle to the device to be stopped.\r
+\r
+  NumberOfChildren  - The number of child device handles in ChildHandleBuffer.\r
+\r
+  ChildHandleBuffer - An array of child device handles to be freed.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - The device has been stopped.\r
+\r
+  EFI_DEVICE_ERROR  - The device could not be stopped due to a device failure.\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Simple File System protocol member functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemOpenVolume (\r
+  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
+  OUT EFI_FILE                        **Root\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Open the root directory on a volume.\r
+\r
+Arguments:\r
+\r
+  This  - A pointer to the volume to open.\r
+\r
+  Root  - A pointer to storage for the returned opened file handle of the root directory.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The volume was opened.\r
+\r
+  EFI_UNSUPPORTED       - The volume does not support the requested file system type.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_ACCESS_DENIED     - The service denied access to the file.\r
+\r
+  EFI_OUT_OF_RESOURCES  - The file volume could not be opened due to lack of resources.\r
+\r
+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemOpen (\r
+  IN  EFI_FILE  *This,\r
+  OUT EFI_FILE  **NewHandle,\r
+  IN  CHAR16    *FileName,\r
+  IN  UINT64    OpenMode,\r
+  IN  UINT64    Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Open a file relative to the source file location.\r
+\r
+Arguments:\r
+\r
+  This        - A pointer to the source file location.\r
+\r
+  NewHandle   - Pointer to storage for the new file handle.\r
+\r
+  FileName    - Pointer to the file name to be opened.\r
+\r
+  OpenMode    - File open mode information.\r
+\r
+  Attributes  - File creation attributes.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The file was opened.\r
+\r
+  EFI_NOT_FOUND         - The file could not be found in the volume.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_WRITE_PROTECTED   - The volume or file is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The service denied access to the file.\r
+\r
+  EFI_OUT_OF_RESOURCES  - Not enough resources were available to open the file.\r
+\r
+  EFI_VOLUME_FULL       - There is not enough space left to create the new file.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemClose (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Close the specified file handle.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to a returned opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - The file handle has been closed.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemDelete (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Close and delete a file.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to a returned opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             - The file handle was closed and deleted.\r
+\r
+  EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemRead (\r
+  IN     EFI_FILE  *This,\r
+  IN OUT UINTN     *BufferSize,\r
+  OUT    VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read data from a file.\r
+\r
+Arguments:\r
+\r
+  This        - Pointer to a returned open file handle.\r
+\r
+  BufferSize  - On input, the size of the Buffer.  On output, the number of bytes stored in the Buffer.\r
+\r
+  Buffer      - Pointer to the first byte of the read Buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data was read.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The supplied buffer size was too small to store the current directory entry.\r
+                          *BufferSize has been updated with the size needed to complete the request.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemWrite (\r
+  IN     EFI_FILE  *This,\r
+  IN OUT UINTN     *BufferSize,\r
+  IN     VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write data to a file.\r
+\r
+Arguments:\r
+\r
+  This        - Pointer to an opened file handle.\r
+\r
+  BufferSize  - On input, the number of bytes in the Buffer to write to the file.  On output, the number of bytes\r
+                of data written to the file.\r
+\r
+  Buffer      - Pointer to the first by of data in the buffer to write to the file.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data was written to the file.\r
+\r
+  EFI_UNSUPPORTED       - Writes to an open directory are not supported.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemSetPosition (\r
+  IN EFI_FILE  *This,\r
+  IN UINT64    Position\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set a file's current position.\r
+\r
+Arguments:\r
+\r
+  This      - Pointer to an opened file handle.\r
+\r
+  Position  - The byte position from the start of the file to set.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS     - The file position has been changed.\r
+\r
+  EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemGetPosition (\r
+  IN  EFI_FILE  *This,\r
+  OUT UINT64    *Position\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get a file's current position.\r
+\r
+Arguments:\r
+\r
+  This      - Pointer to an opened file handle.\r
+\r
+  Position  - Pointer to storage for the current position.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS     - The file position has been reported.\r
+\r
+  EFI_UNSUPPORTED - Not valid for directories.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemGetInfo (\r
+  IN     EFI_FILE  *This,\r
+  IN     EFI_GUID  *InformationType,\r
+  IN OUT UINTN     *BufferSize,\r
+  OUT    VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return information about a file or volume.\r
+\r
+Arguments:\r
+\r
+  This            - Pointer to an opened file handle.\r
+\r
+  InformationType - GUID describing the type of information to be returned.\r
+\r
+  BufferSize      - On input, the size of the information buffer.  On output, the number of bytes written to the\r
+                    information buffer.\r
+\r
+  Buffer          - Pointer to the first byte of the information buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The requested information has been written into the buffer.\r
+\r
+  EFI_UNSUPPORTED       - The InformationType is not known.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The buffer size was too small to contain the requested information.  The buffer size has\r
+                          been updated with the size needed to complete the requested operation.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemSetInfo (\r
+  IN EFI_FILE  *This,\r
+  IN EFI_GUID  *InformationType,\r
+  IN UINTN     BufferSize,\r
+  IN VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set information about a file or volume.\r
+\r
+Arguments:\r
+\r
+  This            - Pointer to an opened file handle.\r
+\r
+  InformationType - GUID identifying the type of information to set.\r
+\r
+  BufferSize      - Number of bytes of data in the information buffer.\r
+\r
+  Buffer          - Pointer to the first byte of data in the information buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The file or volume information has been updated.\r
+\r
+  EFI_UNSUPPORTED       - The information identifier is not recognised.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+  EFI_BAD_BUFFER_SIZE   - The buffer size is smaller than the type indicated by InformationType.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtSimpleFileSystemFlush (\r
+  IN EFI_FILE  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Flush all modified data to the media.\r
+\r
+Arguments:\r
+\r
+  This  - Pointer to an opened file handle.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The data has been flushed.\r
+\r
+  EFI_NO_MEDIA          - The device has no media.\r
+\r
+  EFI_DEVICE_ERROR      - The device reported an error.\r
+\r
+  EFI_VOLUME_CORRUPTED  - The file system structures have been corrupted.\r
+\r
+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.\r
+\r
+  EFI_ACCESS_DENIED     - The file was opened read-only.\r
+\r
+  EFI_VOLUME_FULL       - The volume is full.\r
+\r
+--*/\r
+;\r
+\r
+#endif /* _WIN_NT_SIMPLE_FILE_SYSTEM_H_ */\r
+\r
+/* eof - WinNtSimpleFileSystem.h */\r
diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.inf
new file mode 100644 (file)
index 0000000..625a5fd
--- /dev/null
@@ -0,0 +1,118 @@
+#/** @file\r
+# Simple filesystem driver\r
+#\r
+# Produce Simple File System abstractions for directories on your PC using Win32 APIs.\r
+#  The configuration of what devices to mount or emulate comes from NT\r
+#  environment variables. The variables must be visible to the Microsoft*\r
+#  Developer Studio for them to work.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = WinNtSimpleFileSystem\r
+  FILE_GUID                      = 9C25E18B-76BA-43da-A132-DBB0997CEFEF\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializeWinNtSimpleFileSystem\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+#  DRIVER_BINDING                =  gWinNtSimpleFileSystemDriverBinding          \r
+#  COMPONENT_NAME                =  gWinNtSimpleFileSystemComponentName          \r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  ComponentName.c\r
+  WinNtSimpleFileSystem.c\r
+  WinNtSimpleFileSystem.h\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg/Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  Nt32Pkg/Nt32Pkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  BaseLib\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiFileSystemVolumeLabelInfoIdGuid           # SOMETIMES_CONSUMED\r
+  gEfiFileInfoGuid                              # SOMETIMES_CONSUMED\r
+  gEfiFileSystemInfoGuid                        # SOMETIMES_CONSUMED\r
+  gEfiWinNtFileSystemGuid                       # ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiSimpleFileSystemProtocolGuid              # PROTOCOL BY_START\r
+  gEfiWinNtIoProtocolGuid                       # PROTOCOL TO_START\r
+\r
diff --git a/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa b/Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.msa
new file mode 100644 (file)
index 0000000..c60e293
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>WinNtSimpleFileSystem</ModuleName>\r
+    <ModuleType>UEFI_DRIVER</ModuleType>\r
+    <GuidValue>9C25E18B-76BA-43da-A132-DBB0997CEFEF</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Simple filesystem driver</Abstract>\r
+    <Description>Produce Simple File System abstractions for directories on your PC using Win32 APIs.\r
+      The configuration of what devices to mount or emulate comes from NT\r
+      environment variables. The variables must be visible to the Microsoft*\r
+      Developer Studio for them to work.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>WinNtSimpleFileSystem</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverModelLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>WinNtSimpleFileSystem.h</Filename>\r
+    <Filename>WinNtSimpleFileSystem.c</Filename>\r
+    <Filename>ComponentName.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="0fb2aa2d-10d5-40a5-a9dc-060c12a4a3f3"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiWinNtIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiWinNtFileSystemGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+      <GuidCName>gEfiFileSystemInfoGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+      <GuidCName>gEfiFileInfoGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+      <GuidCName>gEfiFileSystemVolumeLabelInfoIdGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <DriverBinding>gWinNtSimpleFileSystemDriverBinding</DriverBinding>\r
+      <ComponentName>gWinNtSimpleFileSystemComponentName</ComponentName>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file