/** @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;
}

