-/** @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 %Lu bytes from NV Variables file\n",
- (UINT64)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=%Lu)\n",
- (UINT64)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
+ 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 occured.\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 relevent 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
-/** @file
- Save Non-Volatile Variables to a file system.
-
- Copyright (c) 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/DebugLib.h>
-#include <Library/NvVarsFileLib.h>
-
-EFI_HANDLE mNvVarsFileLibFsHandle = NULL;
-
-
-/**
- Attempts to connect the NvVarsFileLib to the specified file system.
-
- @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
-
- @return The EFI_STATUS while attempting to connect the NvVarsFileLib
- to the file system instance.
- @retval EFI_SUCCESS - The given file system was connected successfully
-
-**/
-EFI_STATUS
-EFIAPI
-ConnectNvVarsToFileSystem (
- IN EFI_HANDLE FsHandle
- )
-{
- EFI_STATUS Status;
-
- //
- // We might fail to load the variable, since the file system initially
- // will not have the NvVars file.
- //
- LoadNvVarsFromFs (FsHandle);
-
- //
- // We must be able to save the variables successfully to the file system
- // to have connected successfully.
- //
- Status = SaveNvVarsToFs (FsHandle);
- if (!EFI_ERROR (Status)) {
- mNvVarsFileLibFsHandle = FsHandle;
- }
-
- return Status;
-}
-
-
-/**
- Update non-volatile variables stored on the file system.
-
- @return The EFI_STATUS while attempting to update the variable on
- the connected file system.
- @retval EFI_SUCCESS - The non-volatile variables were saved to the disk
- @retval EFI_NOT_STARTED - A file system has not been connected
-
-**/
-EFI_STATUS
-EFIAPI
-UpdateNvVarsOnFileSystem (
- )
-{
- if (mNvVarsFileLibFsHandle == NULL) {
- //
- // A file system had not been connected to the library.
- //
- return EFI_NOT_STARTED;
- } else {
- return SaveNvVarsToFs (mNvVarsFileLibFsHandle);
- }
-}
-
-
+/** @file\r
+ Save Non-Volatile Variables to a file system.\r
+\r
+ Copyright (c) 2009, 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
+#include <Library/DebugLib.h>\r
+#include <Library/NvVarsFileLib.h>\r
+\r
+EFI_HANDLE mNvVarsFileLibFsHandle = NULL;\r
+\r
+\r
+/**\r
+ Attempts to connect the NvVarsFileLib to the specified file system.\r
+\r
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance\r
+\r
+ @return The EFI_STATUS while attempting to connect the NvVarsFileLib\r
+ to the file system instance.\r
+ @retval EFI_SUCCESS - The given file system was connected successfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectNvVarsToFileSystem (\r
+ IN EFI_HANDLE FsHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // We might fail to load the variable, since the file system initially\r
+ // will not have the NvVars file.\r
+ //\r
+ LoadNvVarsFromFs (FsHandle);\r
+\r
+ //\r
+ // We must be able to save the variables successfully to the file system\r
+ // to have connected successfully.\r
+ //\r
+ Status = SaveNvVarsToFs (FsHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ mNvVarsFileLibFsHandle = FsHandle;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Update non-volatile variables stored on the file system.\r
+\r
+ @return The EFI_STATUS while attempting to update the variable on\r
+ the connected file system.\r
+ @retval EFI_SUCCESS - The non-volatile variables were saved to the disk\r
+ @retval EFI_NOT_STARTED - A file system has not been connected\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateNvVarsOnFileSystem (\r
+ )\r
+{\r
+ if (mNvVarsFileLibFsHandle == NULL) {\r
+ //\r
+ // A file system had not been connected to the library.\r
+ //\r
+ return EFI_NOT_STARTED;\r
+ } else {\r
+ return SaveNvVarsToFs (mNvVarsFileLibFsHandle);\r
+ }\r
+}\r
+\r
+\r
-/** @file
- Detect Xen hvmloader SMBIOS data for usage by OVMF.
-
- Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
- Copyright (c) 2011, 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 "SmbiosPlatformDxe.h"
-#include <Library/HobLib.h>
-#include <Guid/XenInfo.h>
-
-#define XEN_SMBIOS_PHYSICAL_ADDRESS 0x000EB000
-#define XEN_SMBIOS_PHYSICAL_END 0x000F0000
-
-/**
- Validates the SMBIOS entry point structure
-
- @param EntryPointStructure SMBIOS entry point structure
-
- @retval TRUE The entry point structure is valid
- @retval FALSE The entry point structure is not valid
-
-**/
-STATIC
-BOOLEAN
-IsEntryPointStructureValid (
- IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
- )
-{
- UINTN Index;
- UINT8 Length;
- UINT8 Checksum;
- UINT8 *BytePtr;
-
- BytePtr = (UINT8*) EntryPointStructure;
- Length = EntryPointStructure->EntryPointLength;
- Checksum = 0;
-
- for (Index = 0; Index < Length; Index++) {
- Checksum = Checksum + (UINT8) BytePtr[Index];
- }
-
- if (Checksum != 0) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-/**
- Locates the Xen SMBIOS data if it exists
-
- @return SMBIOS_TABLE_ENTRY_POINT Address of Xen SMBIOS data
-
-**/
-SMBIOS_TABLE_ENTRY_POINT *
-GetXenSmbiosTables (
- VOID
- )
-{
- UINT8 *XenSmbiosPtr;
- SMBIOS_TABLE_ENTRY_POINT *XenSmbiosEntryPointStructure;
- EFI_HOB_GUID_TYPE *GuidHob;
-
- //
- // See if a XenInfo HOB is available
- //
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
- if (GuidHob == NULL) {
- return NULL;
- }
-
- for (XenSmbiosPtr = (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_ADDRESS;
- XenSmbiosPtr < (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_END;
- XenSmbiosPtr += 0x10) {
-
- XenSmbiosEntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) XenSmbiosPtr;
-
- if (!AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->AnchorString, "_SM_", 4) &&
- !AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->IntermediateAnchorString, "_DMI_", 5) &&
- IsEntryPointStructureValid (XenSmbiosEntryPointStructure)) {
-
- return XenSmbiosEntryPointStructure;
-
- }
- }
-
- return NULL;
-}
+/** @file\r
+ Detect Xen hvmloader SMBIOS data for usage by OVMF.\r
+\r
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+\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 "SmbiosPlatformDxe.h"\r
+#include <Library/HobLib.h>\r
+#include <Guid/XenInfo.h>\r
+\r
+#define XEN_SMBIOS_PHYSICAL_ADDRESS 0x000EB000\r
+#define XEN_SMBIOS_PHYSICAL_END 0x000F0000\r
+\r
+/**\r
+ Validates the SMBIOS entry point structure\r
+\r
+ @param EntryPointStructure SMBIOS entry point structure\r
+\r
+ @retval TRUE The entry point structure is valid\r
+ @retval FALSE The entry point structure is not valid\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+IsEntryPointStructureValid (\r
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINT8 Length;\r
+ UINT8 Checksum;\r
+ UINT8 *BytePtr;\r
+\r
+ BytePtr = (UINT8*) EntryPointStructure;\r
+ Length = EntryPointStructure->EntryPointLength;\r
+ Checksum = 0;\r
+\r
+ for (Index = 0; Index < Length; Index++) {\r
+ Checksum = Checksum + (UINT8) BytePtr[Index];\r
+ }\r
+\r
+ if (Checksum != 0) {\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
+/**\r
+ Locates the Xen SMBIOS data if it exists\r
+\r
+ @return SMBIOS_TABLE_ENTRY_POINT Address of Xen SMBIOS data\r
+\r
+**/\r
+SMBIOS_TABLE_ENTRY_POINT *\r
+GetXenSmbiosTables (\r
+ VOID\r
+ )\r
+{\r
+ UINT8 *XenSmbiosPtr;\r
+ SMBIOS_TABLE_ENTRY_POINT *XenSmbiosEntryPointStructure;\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+\r
+ //\r
+ // See if a XenInfo HOB is available\r
+ //\r
+ GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);\r
+ if (GuidHob == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ for (XenSmbiosPtr = (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_ADDRESS;\r
+ XenSmbiosPtr < (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_END;\r
+ XenSmbiosPtr += 0x10) {\r
+\r
+ XenSmbiosEntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) XenSmbiosPtr;\r
+\r
+ if (!AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->AnchorString, "_SM_", 4) &&\r
+ !AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->IntermediateAnchorString, "_DMI_", 5) &&\r
+ IsEntryPointStructureValid (XenSmbiosEntryPointStructure)) {\r
+\r
+ return XenSmbiosEntryPointStructure;\r
+\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r