]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/NvVarsFileLib/FsAccess.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / NvVarsFileLib / FsAccess.c
index 66b5566c7518f5b09b6d464d6bfec403253e2845..3f515bd0340e250b999cbf4aebf022f8496e6434 100644 (file)
-/** @file
-  File System Access for NvVarsFileLib
-
-  Copyright (c) 2004 - 2014, 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;
-  EFI_HANDLE                  SerializedVariables;
-
-  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 = SerializeVariablesNewInstanceFromBuffer (
-             &SerializedVariables,
-             FileContents,
-             FileSize
-             );
-  if (!RETURN_ERROR (Status)) {
-    Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
-  }
-
-  FreePool (FileContents);
-  FileHandleClose (File);
-
-  return Status;
-}
-
-
-/**
-  Writes a variable to indicate that the NV variables
-  have been loaded from the file system.
-
-**/
-STATIC
-VOID
-SetNvVarsVariable (
-  VOID
-  )
-{
-  BOOLEAN                        VarData;
-  UINTN                          Size;
-
-  //
-  // 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
-         );
-}
-
-
-/**
-  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.
-  //
-  SetNvVarsVariable();
-
-  DEBUG ((
-    EFI_D_INFO,
-    "FsAccess.c: Read NV Variables file (size=%d)\n",
-    Size
-    ));
-
-  return Status;
-}
-
-
-STATIC
-RETURN_STATUS
-EFIAPI
-IterateVariablesCallbackAddAllNvVariables (
-  IN  VOID                         *Context,
-  IN  CHAR16                       *VariableName,
-  IN  EFI_GUID                     *VendorGuid,
-  IN  UINT32                       Attributes,
-  IN  UINTN                        DataSize,
-  IN  VOID                         *Data
-  )
-{
-  EFI_HANDLE  Instance;
-
-  Instance = (EFI_HANDLE) Context;
-
-  //
-  // Only save non-volatile variables
-  //
-  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
-    return RETURN_SUCCESS;
-  }
-
-  return SerializeVariablesAddVariable (
-           Instance,
-           VariableName,
-           VendorGuid,
-           Attributes,
-           DataSize,
-           Data
-           );
-}
-
-
-/**
-  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                       WriteSize;
-  UINTN                       VariableDataSize;
-  VOID                        *VariableData;
-  EFI_HANDLE                  SerializedVariables;
-
-  SerializedVariables = NULL;
-
-  Status = SerializeVariablesNewInstance (&SerializedVariables);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = SerializeVariablesIterateSystemVariables (
-             IterateVariablesCallbackAddAllNvVariables,
-             (VOID*) SerializedVariables
-             );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  VariableData = NULL;
-  VariableDataSize = 0;
-  Status = SerializeVariablesToBuffer (
-             SerializedVariables,
-             NULL,
-             &VariableDataSize
-             );
-  if (Status == RETURN_BUFFER_TOO_SMALL) {
-    VariableData = AllocatePool (VariableDataSize);
-    if (VariableData == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-    } else {
-      Status = SerializeVariablesToBuffer (
-                 SerializedVariables,
-                 VariableData,
-                 &VariableDataSize
-                 );
-    }
-  }
-
-  SerializeVariablesFreeInstance (SerializedVariables);
-
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // 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;
-  }
-
-  WriteSize = VariableDataSize;
-  Status = FileHandleWrite (File, &WriteSize, VariableData);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  FileHandleClose (File);
-
-  if (!EFI_ERROR (Status)) {
-    //
-    // Write a variable to indicate we've already loaded the
-    // variable data.  If it is found, we skip the loading on
-    // subsequent attempts.
-    //
-    SetNvVarsVariable();
-
-    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
+  SPDX-License-Identifier: BSD-2-Clause-Patent\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
+  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
+\r
+  return Status;\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
+  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
+  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
+  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 ((DEBUG_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
+    DEBUG_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
+  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
+  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 ((DEBUG_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 ((DEBUG_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 ((DEBUG_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
+    DEBUG_INFO,\r
+    "FsAccess.c: Read NV Variables file (size=%Lu)\n",\r
+    (UINT64)Size\r
+    ));\r
+\r
+  return Status;\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
+  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 ((DEBUG_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 ((DEBUG_INFO, "Saved NV Variables to NvVars file\n"));\r
+  }\r
+\r
+  return Status;\r
+}\r