]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Add SerializeVariablesLib library instance
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 30 Jan 2011 19:49:54 +0000 (19:49 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 30 Jan 2011 19:49:54 +0000 (19:49 +0000)
This library implements the library class interface defined at:
OvmfPkg/Include/Library/SerializeVariablesLib.h

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11285 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c [new file with mode: 0644]
OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h [new file with mode: 0644]
OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf [new file with mode: 0644]
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgX64.dsc

diff --git a/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c b/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644 (file)
index 0000000..a2276bf
--- /dev/null
@@ -0,0 +1,858 @@
+/** @file
+  Serialize Variables Library implementation
+
+  Copyright (c) 2004 - 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 "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         Count;
+  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, Count = 0, 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 ((
+      EFI_D_ERROR,
+      "Deserialize variables error: TotalSizeUsed(%d) != MaxSize(%d)\n",
+      TotalSizeUsed,
+      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
+  )
+{
+  return gRT->SetVariable (
+           VariableName,
+           VendorGuid,
+           Attributes,
+           DataSize,
+           Data
+           );
+}
+
+
+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;
+}
+
diff --git a/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h b/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644 (file)
index 0000000..4d01fd6
--- /dev/null
@@ -0,0 +1,39 @@
+/** @file
+  Serialize Variables Library implementation
+
+  Copyright (c) 2009 - 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.
+
+**/
+
+#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__
+#define __SERIALIZE_VARIABLES_LIB_INSTANCE__
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SerializeVariablesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#define SV_FROM_HANDLE(a)       CR (a, SV_INSTANCE, Signature, SV_SIGNATURE)
+#define SV_SIGNATURE            SIGNATURE_32 ('S', 'V', 'A', 'R')
+
+typedef struct {
+  UINT32                              Signature;
+  VOID                                *BufferPtr;
+  UINTN                               BufferSize;
+  UINTN                               DataSize;
+} SV_INSTANCE;
+
+#endif
+
diff --git a/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf b/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
new file mode 100644 (file)
index 0000000..b0c12b0
--- /dev/null
@@ -0,0 +1,41 @@
+## @file\r
+#  Serialize Variables Library implementation\r
+#\r
+#  This library serializes and deserializes UEFI variables\r
+#\r
+#  Copyright (c) 2006 - 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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeSerializeVariablesLib\r
+  FILE_GUID                      = 9515f92a-83ae-45fd-9d2e-e3dc15df52d0\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = SerializeVariablesLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_DRIVER\r
+\r
+[Sources]\r
+  SerializeVariablesLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+\r
index f08c8b312e84b76e623b205996beb633ca7ff986..59045a82407503637436c5b4dea3532a4bbe8309 100644 (file)
@@ -87,6 +87,7 @@
   UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
+  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
index 628375024055314884ec19c32a895663d52b680d..9c11a74812e3aa9c1ca641d78c2acd16289d7669 100644 (file)
@@ -87,6 +87,7 @@
   UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
+  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
index 3aa0f5167fb8f0916c7c85b5660a0b76278282b6..f2ccf590c576e377f8e2874d8839e66f4aeb26eb 100644 (file)
@@ -87,6 +87,7 @@
   UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
+  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r