REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the OvmfPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			872 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			872 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Serialize Variables Library implementation
 | 
						|
 | 
						|
  Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "SerializeVariablesLib.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Serialization format:
 | 
						|
 | 
						|
  The SerializeVariablesLib interface does not specify a format
 | 
						|
  for the serialization of the variable data.  This library uses
 | 
						|
  a packed array of a non-uniformly sized data structure elements.
 | 
						|
 | 
						|
  Each variable is stored (packed) as:
 | 
						|
    UINT32   VendorNameSize;  // Name size in bytes
 | 
						|
    CHAR16   VendorName[?];   // The variable unicode name including the
 | 
						|
                              // null terminating character.
 | 
						|
    EFI_GUID VendorGuid;      // The variable GUID
 | 
						|
    UINT32   DataSize;        // The size of variable data in bytes
 | 
						|
    UINT8    Data[?];         // The variable data
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
/**
 | 
						|
  Unpacks the next variable from the buffer
 | 
						|
 | 
						|
  @param[in]  Buffer - Buffer pointing to the next variable instance
 | 
						|
                On subsequent calls, the pointer should be incremented
 | 
						|
                by the returned SizeUsed value.
 | 
						|
  @param[in]  MaxSize - Max allowable size for the variable data
 | 
						|
                On subsequent calls, this should be decremented
 | 
						|
                by the returned SizeUsed value.
 | 
						|
  @param[out] Name - Variable name string (address in Buffer)
 | 
						|
  @param[out] NameSize - Size of Name in bytes
 | 
						|
  @param[out] Guid - GUID of variable (address in Buffer)
 | 
						|
  @param[out] Attributes - Attributes of variable
 | 
						|
  @param[out] Data - Buffer containing Data for variable (address in Buffer)
 | 
						|
  @param[out] DataSize - Size of Data in bytes
 | 
						|
  @param[out] SizeUsed - Total size used for this variable instance in Buffer
 | 
						|
 | 
						|
  @return     EFI_STATUS based on the success or failure of the operation
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
UnpackVariableFromBuffer (
 | 
						|
  IN  VOID      *Buffer,
 | 
						|
  IN  UINTN     MaxSize,
 | 
						|
  OUT CHAR16    **Name,
 | 
						|
  OUT UINT32    *NameSize,
 | 
						|
  OUT EFI_GUID  **Guid,
 | 
						|
  OUT UINT32    *Attributes,
 | 
						|
  OUT UINT32    *DataSize,
 | 
						|
  OUT VOID      **Data,
 | 
						|
  OUT UINTN     *SizeUsed
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8  *BytePtr;
 | 
						|
  UINTN  Offset;
 | 
						|
 | 
						|
  BytePtr = (UINT8 *)Buffer;
 | 
						|
  Offset  = 0;
 | 
						|
 | 
						|
  *NameSize = *(UINT32 *)(BytePtr + Offset);
 | 
						|
  Offset    = Offset + sizeof (UINT32);
 | 
						|
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Name  = (CHAR16 *)(BytePtr + Offset);
 | 
						|
  Offset = Offset + *(UINT32 *)BytePtr;
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Guid  = (EFI_GUID *)(BytePtr + Offset);
 | 
						|
  Offset = Offset + sizeof (EFI_GUID);
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Attributes = *(UINT32 *)(BytePtr + Offset);
 | 
						|
  Offset      = Offset + sizeof (UINT32);
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *DataSize = *(UINT32 *)(BytePtr + Offset);
 | 
						|
  Offset    = Offset + sizeof (UINT32);
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Data  = (VOID *)(BytePtr + Offset);
 | 
						|
  Offset = Offset + *DataSize;
 | 
						|
  if (Offset > MaxSize) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *SizeUsed = Offset;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Iterates through the variables in the buffer, and calls a callback
 | 
						|
  function for each variable found.
 | 
						|
 | 
						|
  @param[in]  CallbackFunction - Function called for each variable instance
 | 
						|
  @param[in]  Context - Passed to each call of CallbackFunction
 | 
						|
  @param[in]  Buffer - Buffer containing serialized variables
 | 
						|
  @param[in]  MaxSize - Size of Buffer in bytes
 | 
						|
 | 
						|
  @return     EFI_STATUS based on the success or failure of the operation
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
IterateVariablesInBuffer (
 | 
						|
  IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK  CallbackFunction,
 | 
						|
  IN VOID                                       *CallbackContext,
 | 
						|
  IN VOID                                       *Buffer,
 | 
						|
  IN UINTN                                      MaxSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  RETURN_STATUS  Status;
 | 
						|
  UINTN          TotalSizeUsed;
 | 
						|
  UINTN          SizeUsed;
 | 
						|
 | 
						|
  CHAR16    *Name;
 | 
						|
  UINT32    NameSize;
 | 
						|
  CHAR16    *AlignedName;
 | 
						|
  UINT32    AlignedNameMaxSize;
 | 
						|
  EFI_GUID  *Guid;
 | 
						|
  UINT32    Attributes;
 | 
						|
  UINT32    DataSize;
 | 
						|
  VOID      *Data;
 | 
						|
 | 
						|
  SizeUsed           = 0;
 | 
						|
  AlignedName        = NULL;
 | 
						|
  AlignedNameMaxSize = 0;
 | 
						|
  Name               = NULL;
 | 
						|
  Guid               = NULL;
 | 
						|
  Attributes         = 0;
 | 
						|
  DataSize           = 0;
 | 
						|
  Data               = NULL;
 | 
						|
 | 
						|
  for (
 | 
						|
       Status = EFI_SUCCESS, TotalSizeUsed = 0;
 | 
						|
       !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
 | 
						|
       )
 | 
						|
  {
 | 
						|
    Status = UnpackVariableFromBuffer (
 | 
						|
               (VOID *)((UINT8 *)Buffer + TotalSizeUsed),
 | 
						|
               (MaxSize - TotalSizeUsed),
 | 
						|
               &Name,
 | 
						|
               &NameSize,
 | 
						|
               &Guid,
 | 
						|
               &Attributes,
 | 
						|
               &DataSize,
 | 
						|
               &Data,
 | 
						|
               &SizeUsed
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // We copy the name to a separately allocated buffer,
 | 
						|
    // to be sure it is 16-bit aligned.
 | 
						|
    //
 | 
						|
    if (NameSize > AlignedNameMaxSize) {
 | 
						|
      if (AlignedName != NULL) {
 | 
						|
        FreePool (AlignedName);
 | 
						|
      }
 | 
						|
 | 
						|
      AlignedName = AllocatePool (NameSize);
 | 
						|
    }
 | 
						|
 | 
						|
    if (AlignedName == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    CopyMem (AlignedName, Name, NameSize);
 | 
						|
 | 
						|
    TotalSizeUsed = TotalSizeUsed + SizeUsed;
 | 
						|
 | 
						|
    //
 | 
						|
    // Run the callback function
 | 
						|
    //
 | 
						|
    Status = (*CallbackFunction)(
 | 
						|
  CallbackContext,
 | 
						|
  AlignedName,
 | 
						|
  Guid,
 | 
						|
  Attributes,
 | 
						|
  DataSize,
 | 
						|
  Data
 | 
						|
  );
 | 
						|
  }
 | 
						|
 | 
						|
  if (AlignedName != NULL) {
 | 
						|
    FreePool (AlignedName);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure the entire buffer was used, or else return an error
 | 
						|
  //
 | 
						|
  if (TotalSizeUsed != MaxSize) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_ERROR,
 | 
						|
      "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
 | 
						|
      (UINT64)TotalSizeUsed,
 | 
						|
      (UINT64)MaxSize
 | 
						|
      ));
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
IterateVariablesCallbackNop (
 | 
						|
  IN  VOID      *Context,
 | 
						|
  IN  CHAR16    *VariableName,
 | 
						|
  IN  EFI_GUID  *VendorGuid,
 | 
						|
  IN  UINT32    Attributes,
 | 
						|
  IN  UINTN     DataSize,
 | 
						|
  IN  VOID      *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
IterateVariablesCallbackSetInInstance (
 | 
						|
  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;
 | 
						|
 | 
						|
  return SerializeVariablesAddVariable (
 | 
						|
           Instance,
 | 
						|
           VariableName,
 | 
						|
           VendorGuid,
 | 
						|
           Attributes,
 | 
						|
           DataSize,
 | 
						|
           Data
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
IterateVariablesCallbackSetSystemVariable (
 | 
						|
  IN  VOID      *Context,
 | 
						|
  IN  CHAR16    *VariableName,
 | 
						|
  IN  EFI_GUID  *VendorGuid,
 | 
						|
  IN  UINT32    Attributes,
 | 
						|
  IN  UINTN     DataSize,
 | 
						|
  IN  VOID      *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS           Status;
 | 
						|
  STATIC CONST UINT32  AuthMask =
 | 
						|
    EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
 | 
						|
    EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
 | 
						|
 | 
						|
  Status = gRT->SetVariable (
 | 
						|
                  VariableName,
 | 
						|
                  VendorGuid,
 | 
						|
                  Attributes,
 | 
						|
                  DataSize,
 | 
						|
                  Data
 | 
						|
                  );
 | 
						|
 | 
						|
  if ((Status == EFI_SECURITY_VIOLATION) && ((Attributes & AuthMask) != 0)) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_WARN,
 | 
						|
      "%a: setting authenticated variable \"%s\" "
 | 
						|
      "failed with EFI_SECURITY_VIOLATION, ignoring\n",
 | 
						|
      __FUNCTION__,
 | 
						|
      VariableName
 | 
						|
      ));
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
  } else if (Status == EFI_WRITE_PROTECTED) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_WARN,
 | 
						|
      "%a: setting ReadOnly variable \"%s\" "
 | 
						|
      "failed with EFI_WRITE_PROTECTED, ignoring\n",
 | 
						|
      __FUNCTION__,
 | 
						|
      VariableName
 | 
						|
      ));
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EnsureExtraBufferSpace (
 | 
						|
  IN  SV_INSTANCE  *Instance,
 | 
						|
  IN  UINTN        Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  VOID   *NewBuffer;
 | 
						|
  UINTN  NewSize;
 | 
						|
 | 
						|
  NewSize = Instance->DataSize + Size;
 | 
						|
  if (NewSize <= Instance->BufferSize) {
 | 
						|
    return RETURN_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Double the required size to lessen the need to re-allocate in the future
 | 
						|
  //
 | 
						|
  NewSize = 2 * NewSize;
 | 
						|
 | 
						|
  NewBuffer = AllocatePool (NewSize);
 | 
						|
  if (NewBuffer == NULL) {
 | 
						|
    return RETURN_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Instance->BufferPtr != NULL) {
 | 
						|
    CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
 | 
						|
    FreePool (Instance->BufferPtr);
 | 
						|
  }
 | 
						|
 | 
						|
  Instance->BufferPtr  = NewBuffer;
 | 
						|
  Instance->BufferSize = NewSize;
 | 
						|
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
AppendToBuffer (
 | 
						|
  IN  SV_INSTANCE  *Instance,
 | 
						|
  IN  VOID         *Data,
 | 
						|
  IN  UINTN        Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  NewSize;
 | 
						|
 | 
						|
  ASSERT (Instance != NULL);
 | 
						|
  ASSERT (Data != NULL);
 | 
						|
 | 
						|
  NewSize = Instance->DataSize + Size;
 | 
						|
  ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
 | 
						|
 | 
						|
  CopyMem (
 | 
						|
    (VOID *)(((UINT8 *)(Instance->BufferPtr)) + Instance->DataSize),
 | 
						|
    Data,
 | 
						|
    Size
 | 
						|
    );
 | 
						|
 | 
						|
  Instance->DataSize = NewSize;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Creates a new variable serialization instance
 | 
						|
 | 
						|
  @param[out]  Handle - Handle for a variable serialization instance
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - The variable serialization instance was
 | 
						|
                 successfully created.
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 create the variable serialization instance.
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesNewInstance (
 | 
						|
  OUT EFI_HANDLE  *Handle
 | 
						|
  )
 | 
						|
{
 | 
						|
  SV_INSTANCE  *New;
 | 
						|
 | 
						|
  New = AllocateZeroPool (sizeof (*New));
 | 
						|
  if (New == NULL) {
 | 
						|
    return RETURN_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  New->Signature = SV_SIGNATURE;
 | 
						|
 | 
						|
  *Handle = (EFI_HANDLE)New;
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Free memory associated with a variable serialization instance
 | 
						|
 | 
						|
  @param[in]  Handle - Handle for a variable serialization instance
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - The variable serialization instance was
 | 
						|
                 successfully freed.
 | 
						|
  @retval      RETURN_INVALID_PARAMETER - Handle was not a valid
 | 
						|
                 variable serialization instance.
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesFreeInstance (
 | 
						|
  IN EFI_HANDLE  Handle
 | 
						|
  )
 | 
						|
{
 | 
						|
  SV_INSTANCE  *Instance;
 | 
						|
 | 
						|
  Instance = SV_FROM_HANDLE (Handle);
 | 
						|
 | 
						|
  if (Instance->Signature != SV_SIGNATURE) {
 | 
						|
    return RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Instance->Signature = 0;
 | 
						|
 | 
						|
  if (Instance->BufferPtr != NULL) {
 | 
						|
    FreePool (Instance->BufferPtr);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Instance);
 | 
						|
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Creates a new variable serialization instance using the given
 | 
						|
  binary representation of the variables to fill the new instance
 | 
						|
 | 
						|
  @param[out] Handle - Handle for a variable serialization instance
 | 
						|
  @param[in]  Buffer - A buffer with the serialized representation
 | 
						|
                of the variables.  Must be the same format as produced
 | 
						|
                by SerializeVariablesToBuffer.
 | 
						|
  @param[in]  Size - This is the size of the binary representation
 | 
						|
                of the variables.
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - The binary representation was successfully
 | 
						|
                 imported into a new variable serialization instance
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 create the new variable serialization instance
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesNewInstanceFromBuffer (
 | 
						|
  OUT EFI_HANDLE  *Handle,
 | 
						|
  IN  VOID        *Buffer,
 | 
						|
  IN  UINTN       Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  RETURN_STATUS  Status;
 | 
						|
 | 
						|
  Status = SerializeVariablesNewInstance (Handle);
 | 
						|
  if (RETURN_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = IterateVariablesInBuffer (
 | 
						|
             IterateVariablesCallbackNop,
 | 
						|
             NULL,
 | 
						|
             Buffer,
 | 
						|
             Size
 | 
						|
             );
 | 
						|
  if (RETURN_ERROR (Status)) {
 | 
						|
    SerializeVariablesFreeInstance (*Handle);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = IterateVariablesInBuffer (
 | 
						|
             IterateVariablesCallbackSetInInstance,
 | 
						|
             (VOID *)*Handle,
 | 
						|
             Buffer,
 | 
						|
             Size
 | 
						|
             );
 | 
						|
  if (RETURN_ERROR (Status)) {
 | 
						|
    SerializeVariablesFreeInstance (*Handle);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Iterates all variables found with RuntimeServices GetNextVariableName
 | 
						|
 | 
						|
  @param[in]   CallbackFunction - Function called for each variable instance
 | 
						|
  @param[in]   Context - Passed to each call of CallbackFunction
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - All variables were iterated without the
 | 
						|
                 CallbackFunction returning an error
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 iterate through the variables
 | 
						|
  @return      Any of RETURN_ERROR indicates an error reading the variable
 | 
						|
                 or an error was returned from CallbackFunction
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesIterateSystemVariables (
 | 
						|
  IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK  CallbackFunction,
 | 
						|
  IN VOID                                       *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  RETURN_STATUS  Status;
 | 
						|
  UINTN          VariableNameBufferSize;
 | 
						|
  UINTN          VariableNameSize;
 | 
						|
  CHAR16         *VariableName;
 | 
						|
  EFI_GUID       VendorGuid;
 | 
						|
  UINTN          VariableDataBufferSize;
 | 
						|
  UINTN          VariableDataSize;
 | 
						|
  VOID           *VariableData;
 | 
						|
  UINT32         VariableAttributes;
 | 
						|
  VOID           *NewBuffer;
 | 
						|
 | 
						|
  //
 | 
						|
  // 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;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Run the callback function
 | 
						|
    //
 | 
						|
    Status = (*CallbackFunction)(
 | 
						|
  Context,
 | 
						|
  VariableName,
 | 
						|
  &VendorGuid,
 | 
						|
  VariableAttributes,
 | 
						|
  VariableDataSize,
 | 
						|
  VariableData
 | 
						|
  );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableName != NULL) {
 | 
						|
    FreePool (VariableName);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableData != NULL) {
 | 
						|
    FreePool (VariableData);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Iterates all variables found in the variable serialization instance
 | 
						|
 | 
						|
  @param[in]   Handle - Handle for a variable serialization instance
 | 
						|
  @param[in]   CallbackFunction - Function called for each variable instance
 | 
						|
  @param[in]   Context - Passed to each call of CallbackFunction
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - All variables were iterated without the
 | 
						|
                 CallbackFunction returning an error
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 iterate through the variables
 | 
						|
  @return      Any of RETURN_ERROR indicates an error reading the variable
 | 
						|
                 or an error was returned from CallbackFunction
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesIterateInstanceVariables (
 | 
						|
  IN EFI_HANDLE                                 Handle,
 | 
						|
  IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK  CallbackFunction,
 | 
						|
  IN VOID                                       *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  SV_INSTANCE  *Instance;
 | 
						|
 | 
						|
  Instance = SV_FROM_HANDLE (Handle);
 | 
						|
 | 
						|
  if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
 | 
						|
    return IterateVariablesInBuffer (
 | 
						|
             CallbackFunction,
 | 
						|
             Context,
 | 
						|
             Instance->BufferPtr,
 | 
						|
             Instance->DataSize
 | 
						|
             );
 | 
						|
  } else {
 | 
						|
    return RETURN_SUCCESS;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Sets all variables found in the variable serialization instance
 | 
						|
 | 
						|
  @param[in]   Handle - Handle for a variable serialization instance
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - All variables were set successfully
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 set all the variables
 | 
						|
  @return      Any of RETURN_ERROR indicates an error reading the variables
 | 
						|
                 or in attempting to set a variable
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesSetSerializedVariables (
 | 
						|
  IN EFI_HANDLE  Handle
 | 
						|
  )
 | 
						|
{
 | 
						|
  return SerializeVariablesIterateInstanceVariables (
 | 
						|
           Handle,
 | 
						|
           IterateVariablesCallbackSetSystemVariable,
 | 
						|
           NULL
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Adds a variable to the variable serialization instance
 | 
						|
 | 
						|
  @param[in] Handle - Handle for a variable serialization instance
 | 
						|
  @param[in] VariableName - Refer to RuntimeServices GetVariable
 | 
						|
  @param[in] VendorGuid - Refer to RuntimeServices GetVariable
 | 
						|
  @param[in] Attributes - Refer to RuntimeServices GetVariable
 | 
						|
  @param[in] DataSize - Refer to RuntimeServices GetVariable
 | 
						|
  @param[in] Data - Refer to RuntimeServices GetVariable
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - All variables were set successfully
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 add the variable
 | 
						|
  @retval      RETURN_INVALID_PARAMETER - Handle was not a valid
 | 
						|
                 variable serialization instance or
 | 
						|
                 VariableName, VariableGuid or Data are NULL.
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesAddVariable (
 | 
						|
  IN EFI_HANDLE  Handle,
 | 
						|
  IN CHAR16      *VariableName,
 | 
						|
  IN EFI_GUID    *VendorGuid,
 | 
						|
  IN UINT32      Attributes,
 | 
						|
  IN UINTN       DataSize,
 | 
						|
  IN VOID        *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  RETURN_STATUS  Status;
 | 
						|
  SV_INSTANCE    *Instance;
 | 
						|
  UINT32         SerializedNameSize;
 | 
						|
  UINT32         SerializedDataSize;
 | 
						|
  UINTN          SerializedSize;
 | 
						|
 | 
						|
  Instance = SV_FROM_HANDLE (Handle);
 | 
						|
 | 
						|
  if ((Instance->Signature != SV_SIGNATURE) ||
 | 
						|
      (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL))
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  SerializedNameSize = (UINT32)StrSize (VariableName);
 | 
						|
 | 
						|
  SerializedSize =
 | 
						|
    sizeof (SerializedNameSize) +
 | 
						|
    SerializedNameSize +
 | 
						|
    sizeof (*VendorGuid) +
 | 
						|
    sizeof (Attributes) +
 | 
						|
    sizeof (SerializedDataSize) +
 | 
						|
    DataSize;
 | 
						|
 | 
						|
  Status = EnsureExtraBufferSpace (
 | 
						|
             Instance,
 | 
						|
             SerializedSize
 | 
						|
             );
 | 
						|
  if (RETURN_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add name size (UINT32)
 | 
						|
  //
 | 
						|
  AppendToBuffer (Instance, (VOID *)&SerializedNameSize, sizeof (SerializedNameSize));
 | 
						|
 | 
						|
  //
 | 
						|
  // Add variable unicode name string
 | 
						|
  //
 | 
						|
  AppendToBuffer (Instance, (VOID *)VariableName, SerializedNameSize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Add variable GUID
 | 
						|
  //
 | 
						|
  AppendToBuffer (Instance, (VOID *)VendorGuid, sizeof (*VendorGuid));
 | 
						|
 | 
						|
  //
 | 
						|
  // Add variable attributes
 | 
						|
  //
 | 
						|
  AppendToBuffer (Instance, (VOID *)&Attributes, sizeof (Attributes));
 | 
						|
 | 
						|
  //
 | 
						|
  // Add variable data size (UINT32)
 | 
						|
  //
 | 
						|
  SerializedDataSize = (UINT32)DataSize;
 | 
						|
  AppendToBuffer (Instance, (VOID *)&SerializedDataSize, sizeof (SerializedDataSize));
 | 
						|
 | 
						|
  //
 | 
						|
  // Add variable data
 | 
						|
  //
 | 
						|
  AppendToBuffer (Instance, Data, DataSize);
 | 
						|
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Serializes the variables known to this instance into the
 | 
						|
  provided buffer.
 | 
						|
 | 
						|
  @param[in]     Handle - Handle for a variable serialization instance
 | 
						|
  @param[out]    Buffer - A buffer to store the binary representation
 | 
						|
                   of the variables.
 | 
						|
  @param[in,out] Size - On input this is the size of the buffer.
 | 
						|
                   On output this is the size of the binary representation
 | 
						|
                   of the variables.
 | 
						|
 | 
						|
  @retval      RETURN_SUCCESS - The binary representation was successfully
 | 
						|
                 completed and returned in the buffer.
 | 
						|
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
 | 
						|
                 save the variables to the buffer.
 | 
						|
  @retval      RETURN_INVALID_PARAMETER - Handle was not a valid
 | 
						|
                 variable serialization instance or
 | 
						|
                 Size or Buffer were NULL.
 | 
						|
  @retval      RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
 | 
						|
                 the Size parameter was too small for the serialized
 | 
						|
                 variable data.  Size is returned with the required size.
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SerializeVariablesToBuffer (
 | 
						|
  IN     EFI_HANDLE  Handle,
 | 
						|
  OUT    VOID        *Buffer,
 | 
						|
  IN OUT UINTN       *Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  SV_INSTANCE  *Instance;
 | 
						|
 | 
						|
  Instance = SV_FROM_HANDLE (Handle);
 | 
						|
 | 
						|
  if (Size == NULL) {
 | 
						|
    return RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (*Size < Instance->DataSize) {
 | 
						|
    *Size = Instance->DataSize;
 | 
						|
    return RETURN_BUFFER_TOO_SMALL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Size = Instance->DataSize;
 | 
						|
  CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
 | 
						|
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 |