| /** @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(%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 |
| ) |
| { |
| EFI_STATUS Status;
|
| STATIC CONST UINT32 AuthMask =
|
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
|
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
|
|
| Status = gRT->SetVariable (
|
| VariableName,
|
| VendorGuid,
|
| Attributes,
|
| DataSize,
|
| Data
|
| );
|
|
|
| if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
|
| DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
|
| "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
|
| VariableName));
|
| Status = EFI_SUCCESS;
|
| }
|
| return Status;
|
| } |
| |
| |
| STATIC |
| RETURN_STATUS |
| EnsureExtraBufferSpace ( |
| IN SV_INSTANCE *Instance, |
| IN UINTN Size |
| ) |
| { |
| VOID *NewBuffer; |
| UINTN NewSize; |
| |
| NewSize = Instance->DataSize + Size; |
| if (NewSize <= Instance->BufferSize) { |
| return RETURN_SUCCESS; |
| } |
| |
| // |
| // Double the required size to lessen the need to re-allocate in the future |
| // |
| NewSize = 2 * NewSize; |
| |
| NewBuffer = AllocatePool (NewSize); |
| if (NewBuffer == NULL) { |
| return RETURN_OUT_OF_RESOURCES; |
| } |
| |
| if (Instance->BufferPtr != NULL) { |
| CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize); |
| FreePool (Instance->BufferPtr); |
| } |
| |
| Instance->BufferPtr = NewBuffer; |
| Instance->BufferSize = NewSize; |
| |
| return RETURN_SUCCESS; |
| } |
| |
| |
| STATIC |
| VOID |
| AppendToBuffer ( |
| IN SV_INSTANCE *Instance, |
| IN VOID *Data, |
| IN UINTN Size |
| ) |
| { |
| UINTN NewSize; |
| |
| ASSERT (Instance != NULL); |
| ASSERT (Data != NULL); |
| |
| NewSize = Instance->DataSize + Size; |
| ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize); |
| |
| CopyMem ( |
| (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize), |
| Data, |
| Size |
| ); |
| |
| Instance->DataSize = NewSize; |
| } |
| |
| |
| /** |
| Creates a new variable serialization instance |
| |
| @param[out] Handle - Handle for a variable serialization instance |
| |
| @retval RETURN_SUCCESS - The variable serialization instance was |
| successfully created. |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| create the variable serialization instance. |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesNewInstance ( |
| OUT EFI_HANDLE *Handle |
| ) |
| { |
| SV_INSTANCE *New; |
| |
| New = AllocateZeroPool (sizeof (*New)); |
| if (New == NULL) { |
| return RETURN_OUT_OF_RESOURCES; |
| } |
| |
| New->Signature = SV_SIGNATURE; |
| |
| *Handle = (EFI_HANDLE) New; |
| return RETURN_SUCCESS; |
| } |
| |
| |
| /** |
| Free memory associated with a variable serialization instance |
| |
| @param[in] Handle - Handle for a variable serialization instance |
| |
| @retval RETURN_SUCCESS - The variable serialization instance was |
| successfully freed. |
| @retval RETURN_INVALID_PARAMETER - Handle was not a valid |
| variable serialization instance. |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesFreeInstance ( |
| IN EFI_HANDLE Handle |
| ) |
| { |
| SV_INSTANCE *Instance; |
| |
| Instance = SV_FROM_HANDLE (Handle); |
| |
| if (Instance->Signature != SV_SIGNATURE) { |
| return RETURN_INVALID_PARAMETER; |
| } |
| |
| Instance->Signature = 0; |
| |
| if (Instance->BufferPtr != NULL) { |
| FreePool (Instance->BufferPtr); |
| } |
| |
| FreePool (Instance); |
| |
| return RETURN_SUCCESS; |
| } |
| |
| |
| /** |
| Creates a new variable serialization instance using the given |
| binary representation of the variables to fill the new instance |
| |
| @param[out] Handle - Handle for a variable serialization instance |
| @param[in] Buffer - A buffer with the serialized representation |
| of the variables. Must be the same format as produced |
| by SerializeVariablesToBuffer. |
| @param[in] Size - This is the size of the binary representation |
| of the variables. |
| |
| @retval RETURN_SUCCESS - The binary representation was successfully |
| imported into a new variable serialization instance |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| create the new variable serialization instance |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesNewInstanceFromBuffer ( |
| OUT EFI_HANDLE *Handle, |
| IN VOID *Buffer, |
| IN UINTN Size |
| ) |
| { |
| RETURN_STATUS Status; |
| |
| Status = SerializeVariablesNewInstance (Handle); |
| if (RETURN_ERROR (Status)) { |
| return Status; |
| } |
| |
| Status = IterateVariablesInBuffer ( |
| IterateVariablesCallbackNop, |
| NULL, |
| Buffer, |
| Size |
| ); |
| if (RETURN_ERROR (Status)) { |
| SerializeVariablesFreeInstance (*Handle); |
| return Status; |
| } |
| |
| Status = IterateVariablesInBuffer ( |
| IterateVariablesCallbackSetInInstance, |
| (VOID*) *Handle, |
| Buffer, |
| Size |
| ); |
| if (RETURN_ERROR (Status)) { |
| SerializeVariablesFreeInstance (*Handle); |
| return Status; |
| } |
| |
| return Status; |
| } |
| |
| |
| /** |
| Iterates all variables found with RuntimeServices GetNextVariableName |
| |
| @param[in] CallbackFunction - Function called for each variable instance |
| @param[in] Context - Passed to each call of CallbackFunction |
| |
| @retval RETURN_SUCCESS - All variables were iterated without the |
| CallbackFunction returning an error |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| iterate through the variables |
| @return Any of RETURN_ERROR indicates an error reading the variable |
| or an error was returned from CallbackFunction |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesIterateSystemVariables ( |
| IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, |
| IN VOID *Context |
| ) |
| { |
| RETURN_STATUS Status; |
| UINTN VariableNameBufferSize; |
| UINTN VariableNameSize; |
| CHAR16 *VariableName; |
| EFI_GUID VendorGuid; |
| UINTN VariableDataBufferSize; |
| UINTN VariableDataSize; |
| VOID *VariableData; |
| UINT32 VariableAttributes; |
| VOID *NewBuffer; |
| |
| // |
| // Initialize the variable name and data buffer variables. |
| // |
| VariableNameBufferSize = sizeof (CHAR16); |
| VariableName = AllocateZeroPool (VariableNameBufferSize); |
| |
| VariableDataBufferSize = 0; |
| VariableData = NULL; |
| |
| for (;;) { |
| // |
| // Get the next variable name and guid |
| // |
| VariableNameSize = VariableNameBufferSize; |
| Status = gRT->GetNextVariableName ( |
| &VariableNameSize, |
| VariableName, |
| &VendorGuid |
| ); |
| if (Status == EFI_BUFFER_TOO_SMALL) { |
| // |
| // The currently allocated VariableName buffer is too small, |
| // so we allocate a larger buffer, and copy the old buffer |
| // to it. |
| // |
| NewBuffer = AllocatePool (VariableNameSize); |
| if (NewBuffer == NULL) { |
| Status = EFI_OUT_OF_RESOURCES; |
| break; |
| } |
| CopyMem (NewBuffer, VariableName, VariableNameBufferSize); |
| if (VariableName != NULL) { |
| FreePool (VariableName); |
| } |
| VariableName = NewBuffer; |
| VariableNameBufferSize = VariableNameSize; |
| |
| // |
| // Try to get the next variable name again with the larger buffer. |
| // |
| Status = gRT->GetNextVariableName ( |
| &VariableNameSize, |
| VariableName, |
| &VendorGuid |
| ); |
| } |
| |
| if (EFI_ERROR (Status)) { |
| if (Status == EFI_NOT_FOUND) { |
| Status = EFI_SUCCESS; |
| } |
| break; |
| } |
| |
| // |
| // Get the variable data and attributes |
| // |
| VariableDataSize = VariableDataBufferSize; |
| Status = gRT->GetVariable ( |
| VariableName, |
| &VendorGuid, |
| &VariableAttributes, |
| &VariableDataSize, |
| VariableData |
| ); |
| if (Status == EFI_BUFFER_TOO_SMALL) { |
| // |
| // The currently allocated VariableData buffer is too small, |
| // so we allocate a larger buffer. |
| // |
| if (VariableDataBufferSize != 0) { |
| FreePool (VariableData); |
| VariableData = NULL; |
| VariableDataBufferSize = 0; |
| } |
| VariableData = AllocatePool (VariableDataSize); |
| if (VariableData == NULL) { |
| Status = EFI_OUT_OF_RESOURCES; |
| break; |
| } |
| VariableDataBufferSize = VariableDataSize; |
| |
| // |
| // Try to read the variable again with the larger buffer. |
| // |
| Status = gRT->GetVariable ( |
| VariableName, |
| &VendorGuid, |
| &VariableAttributes, |
| &VariableDataSize, |
| VariableData |
| ); |
| } |
| if (EFI_ERROR (Status)) { |
| break; |
| } |
| |
| // |
| // Run the callback function |
| // |
| Status = (*CallbackFunction) ( |
| Context, |
| VariableName, |
| &VendorGuid, |
| VariableAttributes, |
| VariableDataSize, |
| VariableData |
| ); |
| if (EFI_ERROR (Status)) { |
| break; |
| } |
| |
| } |
| |
| if (VariableName != NULL) { |
| FreePool (VariableName); |
| } |
| |
| if (VariableData != NULL) { |
| FreePool (VariableData); |
| } |
| |
| return Status; |
| } |
| |
| |
| /** |
| Iterates all variables found in the variable serialization instance |
| |
| @param[in] Handle - Handle for a variable serialization instance |
| @param[in] CallbackFunction - Function called for each variable instance |
| @param[in] Context - Passed to each call of CallbackFunction |
| |
| @retval RETURN_SUCCESS - All variables were iterated without the |
| CallbackFunction returning an error |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| iterate through the variables |
| @return Any of RETURN_ERROR indicates an error reading the variable |
| or an error was returned from CallbackFunction |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesIterateInstanceVariables ( |
| IN EFI_HANDLE Handle, |
| IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, |
| IN VOID *Context |
| ) |
| { |
| SV_INSTANCE *Instance; |
| |
| Instance = SV_FROM_HANDLE (Handle); |
| |
| if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) { |
| return IterateVariablesInBuffer ( |
| CallbackFunction, |
| Context, |
| Instance->BufferPtr, |
| Instance->DataSize |
| ); |
| } else { |
| return RETURN_SUCCESS; |
| } |
| } |
| |
| |
| /** |
| Sets all variables found in the variable serialization instance |
| |
| @param[in] Handle - Handle for a variable serialization instance |
| |
| @retval RETURN_SUCCESS - All variables were set successfully |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| set all the variables |
| @return Any of RETURN_ERROR indicates an error reading the variables |
| or in attempting to set a variable |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesSetSerializedVariables ( |
| IN EFI_HANDLE Handle |
| ) |
| { |
| return SerializeVariablesIterateInstanceVariables ( |
| Handle, |
| IterateVariablesCallbackSetSystemVariable, |
| NULL |
| ); |
| } |
| |
| |
| /** |
| Adds a variable to the variable serialization instance |
| |
| @param[in] Handle - Handle for a variable serialization instance |
| @param[in] VariableName - Refer to RuntimeServices GetVariable |
| @param[in] VendorGuid - Refer to RuntimeServices GetVariable |
| @param[in] Attributes - Refer to RuntimeServices GetVariable |
| @param[in] DataSize - Refer to RuntimeServices GetVariable |
| @param[in] Data - Refer to RuntimeServices GetVariable |
| |
| @retval RETURN_SUCCESS - All variables were set successfully |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| add the variable |
| @retval RETURN_INVALID_PARAMETER - Handle was not a valid |
| variable serialization instance or |
| VariableName, VariableGuid or Data are NULL. |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesAddVariable ( |
| IN EFI_HANDLE Handle, |
| IN CHAR16 *VariableName, |
| IN EFI_GUID *VendorGuid, |
| IN UINT32 Attributes, |
| IN UINTN DataSize, |
| IN VOID *Data |
| ) |
| { |
| RETURN_STATUS Status; |
| SV_INSTANCE *Instance; |
| UINT32 SerializedNameSize; |
| UINT32 SerializedDataSize; |
| UINTN SerializedSize; |
| |
| Instance = SV_FROM_HANDLE (Handle); |
| |
| if ((Instance->Signature != SV_SIGNATURE) || |
| (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) { |
| } |
| |
| SerializedNameSize = (UINT32) StrSize (VariableName); |
| |
| SerializedSize = |
| sizeof (SerializedNameSize) + |
| SerializedNameSize + |
| sizeof (*VendorGuid) + |
| sizeof (Attributes) + |
| sizeof (SerializedDataSize) + |
| DataSize; |
| |
| Status = EnsureExtraBufferSpace ( |
| Instance, |
| SerializedSize |
| ); |
| if (RETURN_ERROR (Status)) { |
| return Status; |
| } |
| |
| // |
| // Add name size (UINT32) |
| // |
| AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (SerializedNameSize)); |
| |
| // |
| // Add variable unicode name string |
| // |
| AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize); |
| |
| // |
| // Add variable GUID |
| // |
| AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid)); |
| |
| // |
| // Add variable attributes |
| // |
| AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes)); |
| |
| // |
| // Add variable data size (UINT32) |
| // |
| SerializedDataSize = (UINT32) DataSize; |
| AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (SerializedDataSize)); |
| |
| // |
| // Add variable data |
| // |
| AppendToBuffer (Instance, Data, DataSize); |
| |
| return RETURN_SUCCESS; |
| } |
| |
| |
| /** |
| Serializes the variables known to this instance into the |
| provided buffer. |
| |
| @param[in] Handle - Handle for a variable serialization instance |
| @param[out] Buffer - A buffer to store the binary representation |
| of the variables. |
| @param[in,out] Size - On input this is the size of the buffer. |
| On output this is the size of the binary representation |
| of the variables. |
| |
| @retval RETURN_SUCCESS - The binary representation was successfully |
| completed and returned in the buffer. |
| @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to |
| save the variables to the buffer. |
| @retval RETURN_INVALID_PARAMETER - Handle was not a valid |
| variable serialization instance or |
| Size or Buffer were NULL. |
| @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by |
| the Size parameter was too small for the serialized |
| variable data. Size is returned with the required size. |
| |
| **/ |
| RETURN_STATUS |
| EFIAPI |
| SerializeVariablesToBuffer ( |
| IN EFI_HANDLE Handle, |
| OUT VOID *Buffer, |
| IN OUT UINTN *Size |
| ) |
| { |
| SV_INSTANCE *Instance; |
| |
| Instance = SV_FROM_HANDLE (Handle); |
| |
| if (Size == NULL) { |
| return RETURN_INVALID_PARAMETER; |
| } |
| |
| if (*Size < Instance->DataSize) { |
| *Size = Instance->DataSize; |
| return RETURN_BUFFER_TOO_SMALL; |
| } |
| |
| if (Buffer == NULL) { |
| return RETURN_INVALID_PARAMETER; |
| } |
| |
| *Size = Instance->DataSize; |
| CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize); |
| |
| return RETURN_SUCCESS; |
| } |
| |