Beispiel #1
0
/**
  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;

}
Beispiel #2
0
/**
  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;

}