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