]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/NvVarsFileLib/FsAccess.c
OvmfPkg: Fix typing errors
[mirror_edk2.git] / OvmfPkg / Library / NvVarsFileLib / FsAccess.c
index f1694051ab770348b093f54db8167b567a0de3bd..826901fc6b7546c22fd5002bb87873329db19010 100644 (file)
-/** @file
-  File System Access for NvVarsFileLib
-
-  Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "NvVarsFileLib.h"
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-
-
-/**
-  Open the NvVars file for reading or writing
-
-  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
-  @param[in]  ReadingFile - TRUE: open the file for reading.  FALSE: writing
-  @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
-                           with the opened NvVars file.
-
-  @return     EFI_SUCCESS if the file was opened
-
-**/
-EFI_STATUS
-GetNvVarsFile (
-  IN  EFI_HANDLE            FsHandle,
-  IN  BOOLEAN               ReadingFile,
-  OUT EFI_FILE_HANDLE       *NvVarsFile
-  )
-{
-  EFI_STATUS                            Status;
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL       *Fs;
-  EFI_FILE_HANDLE                       Root;
-
-  //
-  // Get the FileSystem protocol on that handle
-  //
-  Status = gBS->HandleProtocol (
-                  FsHandle,
-                  &gEfiSimpleFileSystemProtocolGuid,
-                  (VOID **)&Fs
-                  );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Get the volume (the root directory)
-  //
-  Status = Fs->OpenVolume (Fs, &Root);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Attempt to open the NvVars file in the root directory
-  //
-  Status = Root->Open (
-                   Root,
-                   NvVarsFile,
-                   L"NvVars",
-                   ReadingFile ?
-                     EFI_FILE_MODE_READ :
-                     (
-                       EFI_FILE_MODE_CREATE |
-                       EFI_FILE_MODE_READ |
-                       EFI_FILE_MODE_WRITE
-                     ),
-                   0
-                   );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  return Status;
-}
-
-
-/**
-  Open the NvVars file for reading or writing
-
-  @param[in]  File - The file to inspect
-  @param[out] Exists - Returns whether the file exists
-  @param[out] Size - Returns the size of the file
-                     (0 if the file does not exist)
-
-**/
-VOID
-NvVarsFileReadCheckup (
-  IN  EFI_FILE_HANDLE        File,
-  OUT BOOLEAN                *Exists,
-  OUT UINTN                  *Size
-  )
-{
-  EFI_FILE_INFO               *FileInfo;
-
-  *Exists = FALSE;
-  *Size = 0;
-
-  FileInfo = FileHandleGetInfo (File);
-  if (FileInfo == NULL) {
-    return;
-  }
-
-  if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
-    FreePool (FileInfo);
-    return;
-  }
-
-  *Exists = TRUE;
-  *Size = (UINTN) FileInfo->FileSize;
-
-  FreePool (FileInfo);
-}
-
-
-/**
-  Open the NvVars file for reading or writing
-
-  @param[in]  File - The file to inspect
-  @param[out] Exists - Returns whether the file exists
-  @param[out] Size - Returns the size of the file
-                     (0 if the file does not exist)
-
-**/
-EFI_STATUS
-FileHandleEmpty (
-  IN  EFI_FILE_HANDLE        File
-  )
-{
-  EFI_STATUS                  Status;
-  EFI_FILE_INFO               *FileInfo;
-
-  //
-  // Retrieve the FileInfo structure
-  //
-  FileInfo = FileHandleGetInfo (File);
-  if (FileInfo == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // If the path is a directory, then return an error
-  //
-  if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
-    FreePool (FileInfo);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // If the file size is already 0, then it is empty, so
-  // we can return success.
-  //
-  if (FileInfo->FileSize == 0) {
-    FreePool (FileInfo);
-    return EFI_SUCCESS;
-  }
-
-  //
-  // Set the file size to 0.
-  //
-  FileInfo->FileSize = 0;
-  Status = FileHandleSetInfo (File, FileInfo);
-
-  FreePool (FileInfo);
-
-  return Status;
-}
-
-
-/**
-  Reads a file to a newly allocated buffer
-
-  @param[in]  File - The file to read
-  @param[in]  ReadSize - The size of data to read from the file
-
-  @return     Pointer to buffer allocated to hold the file
-              contents.  NULL if an error occured.
-
-**/
-VOID*
-FileHandleReadToNewBuffer (
-  IN EFI_FILE_HANDLE            FileHandle,
-  IN UINTN                      ReadSize
-  )
-{
-  EFI_STATUS                  Status;
-  UINTN                       ActualReadSize;
-  VOID                        *FileContents;
-
-  ActualReadSize = ReadSize;
-  FileContents = AllocatePool (ReadSize);
-  if (FileContents != NULL) {
-    Status = FileHandleRead (
-               FileHandle,
-               &ReadSize,
-               FileContents
-               );
-    if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
-      FreePool (FileContents);
-      return NULL;
-    }
-  }
-
-  return FileContents;
-}
-
-
-/**
-  Reads the contents of the NvVars file on the file system
-
-  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
-
-  @return     EFI_STATUS based on the success or failure of the file read
-
-**/
-EFI_STATUS
-ReadNvVarsFile (
-  IN  EFI_HANDLE            FsHandle
-  )
-{
-  EFI_STATUS                  Status;
-  EFI_FILE_HANDLE             File;
-  UINTN                       FileSize;
-  BOOLEAN                     FileExists;
-  VOID                        *FileContents;
-
-  Status = GetNvVarsFile (FsHandle, TRUE, &File);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n"));
-    return Status;
-  }
-
-  NvVarsFileReadCheckup (File, &FileExists, &FileSize);
-  if (FileSize == 0) {
-    FileHandleClose (File);
-    return EFI_UNSUPPORTED;
-  }
-
-  FileContents = FileHandleReadToNewBuffer (File, FileSize);
-  if (FileContents == NULL) {
-    FileHandleClose (File);
-    return EFI_UNSUPPORTED;
-  }
-
-  DEBUG ((
-    EFI_D_INFO,
-    "FsAccess.c: Read %d bytes from NV Variables file\n",
-    FileSize
-    ));
-
-  Status = SetVariablesFromBuffer (FileContents, FileSize);
-
-  FreePool (FileContents);
-  FileHandleClose (File);
-
-  return Status;
-}
-
-
-/**
-  Loads the non-volatile variables from the NvVars file on the
-  given file system.
-
-  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
-
-  @return     EFI_STATUS based on the success or failure of load operation
-
-**/
-EFI_STATUS
-LoadNvVarsFromFs (
-  EFI_HANDLE                            FsHandle
-  )
-{
-  EFI_STATUS                     Status;
-  BOOLEAN                        VarData;
-  UINTN                          Size;
-
-  DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
-
-  //
-  // We write a variable to indicate we've already loaded the
-  // variable data.  If it is found, we skip the loading.
-  //
-  // This is relevent if the non-volatile variable have been
-  // able to survive a reboot operation.  In that case, we don't
-  // want to re-load the file as it would overwrite newer changes
-  // made to the variables.
-  //
-  Size = sizeof (VarData);
-  VarData = TRUE;
-  Status = gRT->GetVariable (
-                  L"NvVars",
-                  &gEfiSimpleFileSystemProtocolGuid,
-                  NULL,
-                  &Size,
-                  (VOID*) &VarData
-                  );
-  if (Status == EFI_SUCCESS) {
-    DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));
-    return EFI_ALREADY_STARTED;
-  }
-
-  //
-  // Attempt to restore the variables from the NvVars file.
-  //
-  Status = ReadNvVarsFile (FsHandle);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));
-    return Status;
-  }
-
-  //
-  // Write a variable to indicate we've already loaded the
-  // variable data.  If it is found, we skip the loading on
-  // subsequent attempts.
-  //
-  Size = sizeof (VarData);
-  VarData = TRUE;
-  gRT->SetVariable (
-         L"NvVars",
-         &gEfiSimpleFileSystemProtocolGuid,
-         EFI_VARIABLE_NON_VOLATILE |
-           EFI_VARIABLE_BOOTSERVICE_ACCESS |
-           EFI_VARIABLE_RUNTIME_ACCESS,
-         Size,
-         (VOID*) &VarData
-         );
-
-  DEBUG ((
-    EFI_D_INFO,
-    "FsAccess.c: Read NV Variables file (size=%d)\n",
-    Size
-    ));
-
-  return Status;
-}
-
-
-/**
-  Saves the non-volatile variables into the NvVars file on the
-  given file system.
-
-  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
-
-  @return     EFI_STATUS based on the success or failure of load operation
-
-**/
-EFI_STATUS
-SaveNvVarsToFs (
-  EFI_HANDLE                            FsHandle
-  )
-{
-  EFI_STATUS                  Status;
-  EFI_FILE_HANDLE             File;
-  UINTN                       VariableNameBufferSize;
-  UINTN                       VariableNameSize;
-  CHAR16                      *VariableName;
-  EFI_GUID                    VendorGuid;
-  UINTN                       VariableDataBufferSize;
-  UINTN                       VariableDataSize;
-  VOID                        *VariableData;
-  UINT32                      VariableAttributes;
-  VOID                        *NewBuffer;
-
-  //
-  // Open the NvVars file for writing.
-  //
-  Status = GetNvVarsFile (FsHandle, FALSE, &File);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n"));
-    return Status;
-  }
-
-  //
-  // Empty the starting file contents.
-  //
-  Status = FileHandleEmpty (File);
-  if (EFI_ERROR (Status)) {
-    FileHandleClose (File);
-    return Status;
-  }
-
-  //
-  // Initialize the variable name and data buffer variables.
-  //
-  VariableNameBufferSize = sizeof (CHAR16);
-  VariableName = AllocateZeroPool (VariableNameBufferSize);
-
-  VariableDataBufferSize = 0;
-  VariableData = NULL;
-
-  for (;;) {
-    //
-    // Get the next variable name and guid
-    //
-    VariableNameSize = VariableNameBufferSize;
-    Status = gRT->GetNextVariableName (
-                    &VariableNameSize,
-                    VariableName,
-                    &VendorGuid
-                    );
-    if (Status == EFI_BUFFER_TOO_SMALL) {
-      //
-      // The currently allocated VariableName buffer is too small,
-      // so we allocate a larger buffer, and copy the old buffer
-      // to it.
-      //
-      NewBuffer = AllocatePool (VariableNameSize);
-      if (NewBuffer == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        break;
-      }
-      CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
-      if (VariableName != NULL) {
-        FreePool (VariableName);
-      }
-      VariableName = NewBuffer;
-      VariableNameBufferSize = VariableNameSize;
-
-      //
-      // Try to get the next variable name again with the larger buffer.
-      //
-      Status = gRT->GetNextVariableName (
-                      &VariableNameSize,
-                      VariableName,
-                      &VendorGuid
-                      );
-    }
-
-    if (EFI_ERROR (Status)) {
-      if (Status == EFI_NOT_FOUND) {
-        Status = EFI_SUCCESS;
-      }
-      break;
-    }
-
-    //
-    // Get the variable data and attributes
-    //
-    VariableDataSize = VariableDataBufferSize;
-    Status = gRT->GetVariable (
-                    VariableName,
-                    &VendorGuid,
-                    &VariableAttributes,
-                    &VariableDataSize,
-                    VariableData
-                    );
-    if (Status == EFI_BUFFER_TOO_SMALL) {
-      //
-      // The currently allocated VariableData buffer is too small,
-      // so we allocate a larger buffer.
-      //
-      if (VariableDataBufferSize != 0) {
-        FreePool (VariableData);
-        VariableData = NULL;
-        VariableDataBufferSize = 0;
-      }
-      VariableData = AllocatePool (VariableDataSize);
-      if (VariableData == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        break;
-      }
-      VariableDataBufferSize = VariableDataSize;
-
-      //
-      // Try to read the variable again with the larger buffer.
-      //
-      Status = gRT->GetVariable (
-                      VariableName,
-                      &VendorGuid,
-                      &VariableAttributes,
-                      &VariableDataSize,
-                      VariableData
-                      );
-    }
-    if (EFI_ERROR (Status)) {
-      break;
-    }
-
-    //
-    // Skip volatile variables.  We only preserve non-volatile variables.
-    //
-    if ((VariableAttributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
-      continue;
-    }
-
-    DEBUG ((
-      EFI_D_INFO,
-      "Saving variable %g:%s to file\n",
-      &VendorGuid,
-      VariableName
-      ));
-
-    //
-    // Write the variable information out to the file
-    //
-    Status = PackVariableIntoFile (
-               File,
-               VariableName,
-               (UINT32) VariableNameSize,
-               &VendorGuid,
-               VariableAttributes,
-               VariableData,
-               (UINT32) VariableDataSize
-               );
-    if (EFI_ERROR (Status)) {
-      break;
-    }
-
-  }
-
-  if (VariableName != NULL) {
-    FreePool (VariableName);
-  }
-
-  if (VariableData != NULL) {
-    FreePool (VariableData);
-  }
-
-  FileHandleClose (File);
-
-  if (!EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));
-  }
-
-  return Status;
-
-}
-
-
+/** @file\r
+  File System Access for NvVarsFileLib\r
+\r
+  Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  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
+**/\r
+\r
+#include "NvVarsFileLib.h"\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+\r
+/**\r
+  Open the NvVars file for reading or writing\r
+\r
+  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance\r
+  @param[in]  ReadingFile - TRUE: open the file for reading.  FALSE: writing\r
+  @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated\r
+                           with the opened NvVars file.\r
+\r
+  @return     EFI_SUCCESS if the file was opened\r
+\r
+**/\r
+EFI_STATUS\r
+GetNvVarsFile (\r
+  IN  EFI_HANDLE            FsHandle,\r
+  IN  BOOLEAN               ReadingFile,\r
+  OUT EFI_FILE_HANDLE       *NvVarsFile\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL       *Fs;\r
+  EFI_FILE_HANDLE                       Root;\r
+\r
+  //\r
+  // Get the FileSystem protocol on that handle\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  FsHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  (VOID **)&Fs\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the volume (the root directory)\r
+  //\r
+  Status = Fs->OpenVolume (Fs, &Root);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Attempt to open the NvVars file in the root directory\r
+  //\r
+  Status = Root->Open (\r
+                   Root,\r
+                   NvVarsFile,\r
+                   L"NvVars",\r
+                   ReadingFile ?\r
+                     EFI_FILE_MODE_READ :\r
+                     (\r
+                       EFI_FILE_MODE_CREATE |\r
+                       EFI_FILE_MODE_READ |\r
+                       EFI_FILE_MODE_WRITE\r
+                     ),\r
+                   0\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Open the NvVars file for reading or writing\r
+\r
+  @param[in]  File - The file to inspect\r
+  @param[out] Exists - Returns whether the file exists\r
+  @param[out] Size - Returns the size of the file\r
+                     (0 if the file does not exist)\r
+\r
+**/\r
+VOID\r
+NvVarsFileReadCheckup (\r
+  IN  EFI_FILE_HANDLE        File,\r
+  OUT BOOLEAN                *Exists,\r
+  OUT UINTN                  *Size\r
+  )\r
+{\r
+  EFI_FILE_INFO               *FileInfo;\r
+\r
+  *Exists = FALSE;\r
+  *Size = 0;\r
+\r
+  FileInfo = FileHandleGetInfo (File);\r
+  if (FileInfo == NULL) {\r
+    return;\r
+  }\r
+\r
+  if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {\r
+    FreePool (FileInfo);\r
+    return;\r
+  }\r
+\r
+  *Exists = TRUE;\r
+  *Size = (UINTN) FileInfo->FileSize;\r
+\r
+  FreePool (FileInfo);\r
+}\r
+\r
+\r
+/**\r
+  Open the NvVars file for reading or writing\r
+\r
+  @param[in]  File - The file to inspect\r
+  @param[out] Exists - Returns whether the file exists\r
+  @param[out] Size - Returns the size of the file\r
+                     (0 if the file does not exist)\r
+\r
+**/\r
+EFI_STATUS\r
+FileHandleEmpty (\r
+  IN  EFI_FILE_HANDLE        File\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_FILE_INFO               *FileInfo;\r
+\r
+  //\r
+  // Retrieve the FileInfo structure\r
+  //\r
+  FileInfo = FileHandleGetInfo (File);\r
+  if (FileInfo == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If the path is a directory, then return an error\r
+  //\r
+  if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {\r
+    FreePool (FileInfo);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If the file size is already 0, then it is empty, so\r
+  // we can return success.\r
+  //\r
+  if (FileInfo->FileSize == 0) {\r
+    FreePool (FileInfo);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Set the file size to 0.\r
+  //\r
+  FileInfo->FileSize = 0;\r
+  Status = FileHandleSetInfo (File, FileInfo);\r
+\r
+  FreePool (FileInfo);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Reads a file to a newly allocated buffer\r
+\r
+  @param[in]  File - The file to read\r
+  @param[in]  ReadSize - The size of data to read from the file\r
+\r
+  @return     Pointer to buffer allocated to hold the file\r
+              contents.  NULL if an error occurred.\r
+\r
+**/\r
+VOID*\r
+FileHandleReadToNewBuffer (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN UINTN                      ReadSize\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINTN                       ActualReadSize;\r
+  VOID                        *FileContents;\r
+\r
+  ActualReadSize = ReadSize;\r
+  FileContents = AllocatePool (ReadSize);\r
+  if (FileContents != NULL) {\r
+    Status = FileHandleRead (\r
+               FileHandle,\r
+               &ReadSize,\r
+               FileContents\r
+               );\r
+    if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {\r
+      FreePool (FileContents);\r
+      return NULL;\r
+    }\r
+  }\r
+\r
+  return FileContents;\r
+}\r
+\r
+\r
+/**\r
+  Reads the contents of the NvVars file on the file system\r
+\r
+  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance\r
+\r
+  @return     EFI_STATUS based on the success or failure of the file read\r
+\r
+**/\r
+EFI_STATUS\r
+ReadNvVarsFile (\r
+  IN  EFI_HANDLE            FsHandle\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_FILE_HANDLE             File;\r
+  UINTN                       FileSize;\r
+  BOOLEAN                     FileExists;\r
+  VOID                        *FileContents;\r
+  EFI_HANDLE                  SerializedVariables;\r
+\r
+  Status = GetNvVarsFile (FsHandle, TRUE, &File);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n"));\r
+    return Status;\r
+  }\r
+\r
+  NvVarsFileReadCheckup (File, &FileExists, &FileSize);\r
+  if (FileSize == 0) {\r
+    FileHandleClose (File);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  FileContents = FileHandleReadToNewBuffer (File, FileSize);\r
+  if (FileContents == NULL) {\r
+    FileHandleClose (File);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  DEBUG ((\r
+    EFI_D_INFO,\r
+    "FsAccess.c: Read %Lu bytes from NV Variables file\n",\r
+    (UINT64)FileSize\r
+    ));\r
+\r
+  Status = SerializeVariablesNewInstanceFromBuffer (\r
+             &SerializedVariables,\r
+             FileContents,\r
+             FileSize\r
+             );\r
+  if (!RETURN_ERROR (Status)) {\r
+    Status = SerializeVariablesSetSerializedVariables (SerializedVariables);\r
+  }\r
+\r
+  FreePool (FileContents);\r
+  FileHandleClose (File);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Writes a variable to indicate that the NV variables\r
+  have been loaded from the file system.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+SetNvVarsVariable (\r
+  VOID\r
+  )\r
+{\r
+  BOOLEAN                        VarData;\r
+  UINTN                          Size;\r
+\r
+  //\r
+  // Write a variable to indicate we've already loaded the\r
+  // variable data.  If it is found, we skip the loading on\r
+  // subsequent attempts.\r
+  //\r
+  Size = sizeof (VarData);\r
+  VarData = TRUE;\r
+  gRT->SetVariable (\r
+         L"NvVars",\r
+         &gEfiSimpleFileSystemProtocolGuid,\r
+         EFI_VARIABLE_NON_VOLATILE |\r
+           EFI_VARIABLE_BOOTSERVICE_ACCESS |\r
+           EFI_VARIABLE_RUNTIME_ACCESS,\r
+         Size,\r
+         (VOID*) &VarData\r
+         );\r
+}\r
+\r
+\r
+/**\r
+  Loads the non-volatile variables from the NvVars file on the\r
+  given file system.\r
+\r
+  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance\r
+\r
+  @return     EFI_STATUS based on the success or failure of load operation\r
+\r
+**/\r
+EFI_STATUS\r
+LoadNvVarsFromFs (\r
+  EFI_HANDLE                            FsHandle\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  BOOLEAN                        VarData;\r
+  UINTN                          Size;\r
+\r
+  DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));\r
+\r
+  //\r
+  // We write a variable to indicate we've already loaded the\r
+  // variable data.  If it is found, we skip the loading.\r
+  //\r
+  // This is relevant if the non-volatile variable have been\r
+  // able to survive a reboot operation.  In that case, we don't\r
+  // want to re-load the file as it would overwrite newer changes\r
+  // made to the variables.\r
+  //\r
+  Size = sizeof (VarData);\r
+  VarData = TRUE;\r
+  Status = gRT->GetVariable (\r
+                  L"NvVars",\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  (VOID*) &VarData\r
+                  );\r
+  if (Status == EFI_SUCCESS) {\r
+    DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  //\r
+  // Attempt to restore the variables from the NvVars file.\r
+  //\r
+  Status = ReadNvVarsFile (FsHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Write a variable to indicate we've already loaded the\r
+  // variable data.  If it is found, we skip the loading on\r
+  // subsequent attempts.\r
+  //\r
+  SetNvVarsVariable();\r
+\r
+  DEBUG ((\r
+    EFI_D_INFO,\r
+    "FsAccess.c: Read NV Variables file (size=%Lu)\n",\r
+    (UINT64)Size\r
+    ));\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+IterateVariablesCallbackAddAllNvVariables (\r
+  IN  VOID                         *Context,\r
+  IN  CHAR16                       *VariableName,\r
+  IN  EFI_GUID                     *VendorGuid,\r
+  IN  UINT32                       Attributes,\r
+  IN  UINTN                        DataSize,\r
+  IN  VOID                         *Data\r
+  )\r
+{\r
+  EFI_HANDLE  Instance;\r
+\r
+  Instance = (EFI_HANDLE) Context;\r
+\r
+  //\r
+  // Only save non-volatile variables\r
+  //\r
+  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  return SerializeVariablesAddVariable (\r
+           Instance,\r
+           VariableName,\r
+           VendorGuid,\r
+           Attributes,\r
+           DataSize,\r
+           Data\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Saves the non-volatile variables into the NvVars file on the\r
+  given file system.\r
+\r
+  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance\r
+\r
+  @return     EFI_STATUS based on the success or failure of load operation\r
+\r
+**/\r
+EFI_STATUS\r
+SaveNvVarsToFs (\r
+  EFI_HANDLE                            FsHandle\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_FILE_HANDLE             File;\r
+  UINTN                       WriteSize;\r
+  UINTN                       VariableDataSize;\r
+  VOID                        *VariableData;\r
+  EFI_HANDLE                  SerializedVariables;\r
+\r
+  SerializedVariables = NULL;\r
+\r
+  Status = SerializeVariablesNewInstance (&SerializedVariables);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = SerializeVariablesIterateSystemVariables (\r
+             IterateVariablesCallbackAddAllNvVariables,\r
+             (VOID*) SerializedVariables\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  VariableData = NULL;\r
+  VariableDataSize = 0;\r
+  Status = SerializeVariablesToBuffer (\r
+             SerializedVariables,\r
+             NULL,\r
+             &VariableDataSize\r
+             );\r
+  if (Status == RETURN_BUFFER_TOO_SMALL) {\r
+    VariableData = AllocatePool (VariableDataSize);\r
+    if (VariableData == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+    } else {\r
+      Status = SerializeVariablesToBuffer (\r
+                 SerializedVariables,\r
+                 VariableData,\r
+                 &VariableDataSize\r
+                 );\r
+    }\r
+  }\r
+\r
+  SerializeVariablesFreeInstance (SerializedVariables);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Open the NvVars file for writing.\r
+  //\r
+  Status = GetNvVarsFile (FsHandle, FALSE, &File);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n"));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Empty the starting file contents.\r
+  //\r
+  Status = FileHandleEmpty (File);\r
+  if (EFI_ERROR (Status)) {\r
+    FileHandleClose (File);\r
+    return Status;\r
+  }\r
+\r
+  WriteSize = VariableDataSize;\r
+  Status = FileHandleWrite (File, &WriteSize, VariableData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  FileHandleClose (File);\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Write a variable to indicate we've already loaded the\r
+    // variable data.  If it is found, we skip the loading on\r
+    // subsequent attempts.\r
+    //\r
+    SetNvVarsVariable();\r
+\r
+    DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));\r
+  }\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+\r