OvmfPkg: Add SerializeVariablesLib library instance
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
This commit is contained in:
858
OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
Normal file
858
OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
## @file
|
||||||
|
# Serialize Variables Library implementation
|
||||||
|
#
|
||||||
|
# This library serializes and deserializes UEFI variables
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 - 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.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = DxeSerializeVariablesLib
|
||||||
|
FILE_GUID = 9515f92a-83ae-45fd-9d2e-e3dc15df52d0
|
||||||
|
MODULE_TYPE = UEFI_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_DRIVER
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
SerializeVariablesLib.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
OvmfPkg/OvmfPkg.dec
|
||||||
|
ShellPkg/ShellPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
BaseMemoryLib
|
||||||
|
DebugLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
|
@ -87,6 +87,7 @@
|
|||||||
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
||||||
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
||||||
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
||||||
|
SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
|
||||||
|
|
||||||
!ifdef $(SOURCE_DEBUG_ENABLE)
|
!ifdef $(SOURCE_DEBUG_ENABLE)
|
||||||
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
||||||
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
||||||
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
||||||
|
SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
|
||||||
|
|
||||||
!ifdef $(SOURCE_DEBUG_ENABLE)
|
!ifdef $(SOURCE_DEBUG_ENABLE)
|
||||||
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
||||||
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
|
||||||
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
||||||
|
SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
|
||||||
|
|
||||||
!ifdef $(SOURCE_DEBUG_ENABLE)
|
!ifdef $(SOURCE_DEBUG_ENABLE)
|
||||||
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
||||||
|
Reference in New Issue
Block a user