]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / SerializeVariablesLib / SerializeVariablesLib.c
1 /** @file
2 Serialize Variables Library implementation
3
4 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "SerializeVariablesLib.h"
10
11 /**
12 Serialization format:
13
14 The SerializeVariablesLib interface does not specify a format
15 for the serialization of the variable data. This library uses
16 a packed array of a non-uniformly sized data structure elements.
17
18 Each variable is stored (packed) as:
19 UINT32 VendorNameSize; // Name size in bytes
20 CHAR16 VendorName[?]; // The variable unicode name including the
21 // null terminating character.
22 EFI_GUID VendorGuid; // The variable GUID
23 UINT32 DataSize; // The size of variable data in bytes
24 UINT8 Data[?]; // The variable data
25
26 **/
27
28 /**
29 Unpacks the next variable from the buffer
30
31 @param[in] Buffer - Buffer pointing to the next variable instance
32 On subsequent calls, the pointer should be incremented
33 by the returned SizeUsed value.
34 @param[in] MaxSize - Max allowable size for the variable data
35 On subsequent calls, this should be decremented
36 by the returned SizeUsed value.
37 @param[out] Name - Variable name string (address in Buffer)
38 @param[out] NameSize - Size of Name in bytes
39 @param[out] Guid - GUID of variable (address in Buffer)
40 @param[out] Attributes - Attributes of variable
41 @param[out] Data - Buffer containing Data for variable (address in Buffer)
42 @param[out] DataSize - Size of Data in bytes
43 @param[out] SizeUsed - Total size used for this variable instance in Buffer
44
45 @return EFI_STATUS based on the success or failure of the operation
46
47 **/
48 STATIC
49 EFI_STATUS
50 UnpackVariableFromBuffer (
51 IN VOID *Buffer,
52 IN UINTN MaxSize,
53 OUT CHAR16 **Name,
54 OUT UINT32 *NameSize,
55 OUT EFI_GUID **Guid,
56 OUT UINT32 *Attributes,
57 OUT UINT32 *DataSize,
58 OUT VOID **Data,
59 OUT UINTN *SizeUsed
60 )
61 {
62 UINT8 *BytePtr;
63 UINTN Offset;
64
65 BytePtr = (UINT8 *)Buffer;
66 Offset = 0;
67
68 *NameSize = *(UINT32 *)(BytePtr + Offset);
69 Offset = Offset + sizeof (UINT32);
70
71 if (Offset > MaxSize) {
72 return EFI_INVALID_PARAMETER;
73 }
74
75 *Name = (CHAR16 *)(BytePtr + Offset);
76 Offset = Offset + *(UINT32 *)BytePtr;
77 if (Offset > MaxSize) {
78 return EFI_INVALID_PARAMETER;
79 }
80
81 *Guid = (EFI_GUID *)(BytePtr + Offset);
82 Offset = Offset + sizeof (EFI_GUID);
83 if (Offset > MaxSize) {
84 return EFI_INVALID_PARAMETER;
85 }
86
87 *Attributes = *(UINT32 *)(BytePtr + Offset);
88 Offset = Offset + sizeof (UINT32);
89 if (Offset > MaxSize) {
90 return EFI_INVALID_PARAMETER;
91 }
92
93 *DataSize = *(UINT32 *)(BytePtr + Offset);
94 Offset = Offset + sizeof (UINT32);
95 if (Offset > MaxSize) {
96 return EFI_INVALID_PARAMETER;
97 }
98
99 *Data = (VOID *)(BytePtr + Offset);
100 Offset = Offset + *DataSize;
101 if (Offset > MaxSize) {
102 return EFI_INVALID_PARAMETER;
103 }
104
105 *SizeUsed = Offset;
106
107 return EFI_SUCCESS;
108 }
109
110 /**
111 Iterates through the variables in the buffer, and calls a callback
112 function for each variable found.
113
114 @param[in] CallbackFunction - Function called for each variable instance
115 @param[in] Context - Passed to each call of CallbackFunction
116 @param[in] Buffer - Buffer containing serialized variables
117 @param[in] MaxSize - Size of Buffer in bytes
118
119 @return EFI_STATUS based on the success or failure of the operation
120
121 **/
122 STATIC
123 EFI_STATUS
124 IterateVariablesInBuffer (
125 IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
126 IN VOID *CallbackContext,
127 IN VOID *Buffer,
128 IN UINTN MaxSize
129 )
130 {
131 RETURN_STATUS Status;
132 UINTN TotalSizeUsed;
133 UINTN SizeUsed;
134
135 CHAR16 *Name;
136 UINT32 NameSize;
137 CHAR16 *AlignedName;
138 UINT32 AlignedNameMaxSize;
139 EFI_GUID *Guid;
140 UINT32 Attributes;
141 UINT32 DataSize;
142 VOID *Data;
143
144 SizeUsed = 0;
145 AlignedName = NULL;
146 AlignedNameMaxSize = 0;
147 Name = NULL;
148 Guid = NULL;
149 Attributes = 0;
150 DataSize = 0;
151 Data = NULL;
152
153 for (
154 Status = EFI_SUCCESS, TotalSizeUsed = 0;
155 !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
156 )
157 {
158 Status = UnpackVariableFromBuffer (
159 (VOID *)((UINT8 *)Buffer + TotalSizeUsed),
160 (MaxSize - TotalSizeUsed),
161 &Name,
162 &NameSize,
163 &Guid,
164 &Attributes,
165 &DataSize,
166 &Data,
167 &SizeUsed
168 );
169 if (EFI_ERROR (Status)) {
170 return Status;
171 }
172
173 //
174 // We copy the name to a separately allocated buffer,
175 // to be sure it is 16-bit aligned.
176 //
177 if (NameSize > AlignedNameMaxSize) {
178 if (AlignedName != NULL) {
179 FreePool (AlignedName);
180 }
181
182 AlignedName = AllocatePool (NameSize);
183 }
184
185 if (AlignedName == NULL) {
186 return EFI_OUT_OF_RESOURCES;
187 }
188
189 CopyMem (AlignedName, Name, NameSize);
190
191 TotalSizeUsed = TotalSizeUsed + SizeUsed;
192
193 //
194 // Run the callback function
195 //
196 Status = (*CallbackFunction)(
197 CallbackContext,
198 AlignedName,
199 Guid,
200 Attributes,
201 DataSize,
202 Data
203 );
204 }
205
206 if (AlignedName != NULL) {
207 FreePool (AlignedName);
208 }
209
210 //
211 // Make sure the entire buffer was used, or else return an error
212 //
213 if (TotalSizeUsed != MaxSize) {
214 DEBUG ((
215 DEBUG_ERROR,
216 "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
217 (UINT64)TotalSizeUsed,
218 (UINT64)MaxSize
219 ));
220 return EFI_INVALID_PARAMETER;
221 }
222
223 return EFI_SUCCESS;
224 }
225
226 STATIC
227 RETURN_STATUS
228 EFIAPI
229 IterateVariablesCallbackNop (
230 IN VOID *Context,
231 IN CHAR16 *VariableName,
232 IN EFI_GUID *VendorGuid,
233 IN UINT32 Attributes,
234 IN UINTN DataSize,
235 IN VOID *Data
236 )
237 {
238 return RETURN_SUCCESS;
239 }
240
241 STATIC
242 RETURN_STATUS
243 EFIAPI
244 IterateVariablesCallbackSetInInstance (
245 IN VOID *Context,
246 IN CHAR16 *VariableName,
247 IN EFI_GUID *VendorGuid,
248 IN UINT32 Attributes,
249 IN UINTN DataSize,
250 IN VOID *Data
251 )
252 {
253 EFI_HANDLE Instance;
254
255 Instance = (EFI_HANDLE)Context;
256
257 return SerializeVariablesAddVariable (
258 Instance,
259 VariableName,
260 VendorGuid,
261 Attributes,
262 DataSize,
263 Data
264 );
265 }
266
267 STATIC
268 RETURN_STATUS
269 EFIAPI
270 IterateVariablesCallbackSetSystemVariable (
271 IN VOID *Context,
272 IN CHAR16 *VariableName,
273 IN EFI_GUID *VendorGuid,
274 IN UINT32 Attributes,
275 IN UINTN DataSize,
276 IN VOID *Data
277 )
278 {
279 EFI_STATUS Status;
280 STATIC CONST UINT32 AuthMask =
281 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
282 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
283
284 Status = gRT->SetVariable (
285 VariableName,
286 VendorGuid,
287 Attributes,
288 DataSize,
289 Data
290 );
291
292 if ((Status == EFI_SECURITY_VIOLATION) && ((Attributes & AuthMask) != 0)) {
293 DEBUG ((
294 DEBUG_WARN,
295 "%a: setting authenticated variable \"%s\" "
296 "failed with EFI_SECURITY_VIOLATION, ignoring\n",
297 __FUNCTION__,
298 VariableName
299 ));
300 Status = EFI_SUCCESS;
301 } else if (Status == EFI_WRITE_PROTECTED) {
302 DEBUG ((
303 DEBUG_WARN,
304 "%a: setting ReadOnly variable \"%s\" "
305 "failed with EFI_WRITE_PROTECTED, ignoring\n",
306 __FUNCTION__,
307 VariableName
308 ));
309 Status = EFI_SUCCESS;
310 }
311
312 return Status;
313 }
314
315 STATIC
316 RETURN_STATUS
317 EnsureExtraBufferSpace (
318 IN SV_INSTANCE *Instance,
319 IN UINTN Size
320 )
321 {
322 VOID *NewBuffer;
323 UINTN NewSize;
324
325 NewSize = Instance->DataSize + Size;
326 if (NewSize <= Instance->BufferSize) {
327 return RETURN_SUCCESS;
328 }
329
330 //
331 // Double the required size to lessen the need to re-allocate in the future
332 //
333 NewSize = 2 * NewSize;
334
335 NewBuffer = AllocatePool (NewSize);
336 if (NewBuffer == NULL) {
337 return RETURN_OUT_OF_RESOURCES;
338 }
339
340 if (Instance->BufferPtr != NULL) {
341 CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
342 FreePool (Instance->BufferPtr);
343 }
344
345 Instance->BufferPtr = NewBuffer;
346 Instance->BufferSize = NewSize;
347
348 return RETURN_SUCCESS;
349 }
350
351 STATIC
352 VOID
353 AppendToBuffer (
354 IN SV_INSTANCE *Instance,
355 IN VOID *Data,
356 IN UINTN Size
357 )
358 {
359 UINTN NewSize;
360
361 ASSERT (Instance != NULL);
362 ASSERT (Data != NULL);
363
364 NewSize = Instance->DataSize + Size;
365 ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
366
367 CopyMem (
368 (VOID *)(((UINT8 *)(Instance->BufferPtr)) + Instance->DataSize),
369 Data,
370 Size
371 );
372
373 Instance->DataSize = NewSize;
374 }
375
376 /**
377 Creates a new variable serialization instance
378
379 @param[out] Handle - Handle for a variable serialization instance
380
381 @retval RETURN_SUCCESS - The variable serialization instance was
382 successfully created.
383 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
384 create the variable serialization instance.
385
386 **/
387 RETURN_STATUS
388 EFIAPI
389 SerializeVariablesNewInstance (
390 OUT EFI_HANDLE *Handle
391 )
392 {
393 SV_INSTANCE *New;
394
395 New = AllocateZeroPool (sizeof (*New));
396 if (New == NULL) {
397 return RETURN_OUT_OF_RESOURCES;
398 }
399
400 New->Signature = SV_SIGNATURE;
401
402 *Handle = (EFI_HANDLE)New;
403 return RETURN_SUCCESS;
404 }
405
406 /**
407 Free memory associated with a variable serialization instance
408
409 @param[in] Handle - Handle for a variable serialization instance
410
411 @retval RETURN_SUCCESS - The variable serialization instance was
412 successfully freed.
413 @retval RETURN_INVALID_PARAMETER - Handle was not a valid
414 variable serialization instance.
415
416 **/
417 RETURN_STATUS
418 EFIAPI
419 SerializeVariablesFreeInstance (
420 IN EFI_HANDLE Handle
421 )
422 {
423 SV_INSTANCE *Instance;
424
425 Instance = SV_FROM_HANDLE (Handle);
426
427 if (Instance->Signature != SV_SIGNATURE) {
428 return RETURN_INVALID_PARAMETER;
429 }
430
431 Instance->Signature = 0;
432
433 if (Instance->BufferPtr != NULL) {
434 FreePool (Instance->BufferPtr);
435 }
436
437 FreePool (Instance);
438
439 return RETURN_SUCCESS;
440 }
441
442 /**
443 Creates a new variable serialization instance using the given
444 binary representation of the variables to fill the new instance
445
446 @param[out] Handle - Handle for a variable serialization instance
447 @param[in] Buffer - A buffer with the serialized representation
448 of the variables. Must be the same format as produced
449 by SerializeVariablesToBuffer.
450 @param[in] Size - This is the size of the binary representation
451 of the variables.
452
453 @retval RETURN_SUCCESS - The binary representation was successfully
454 imported into a new variable serialization instance
455 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
456 create the new variable serialization instance
457
458 **/
459 RETURN_STATUS
460 EFIAPI
461 SerializeVariablesNewInstanceFromBuffer (
462 OUT EFI_HANDLE *Handle,
463 IN VOID *Buffer,
464 IN UINTN Size
465 )
466 {
467 RETURN_STATUS Status;
468
469 Status = SerializeVariablesNewInstance (Handle);
470 if (RETURN_ERROR (Status)) {
471 return Status;
472 }
473
474 Status = IterateVariablesInBuffer (
475 IterateVariablesCallbackNop,
476 NULL,
477 Buffer,
478 Size
479 );
480 if (RETURN_ERROR (Status)) {
481 SerializeVariablesFreeInstance (*Handle);
482 return Status;
483 }
484
485 Status = IterateVariablesInBuffer (
486 IterateVariablesCallbackSetInInstance,
487 (VOID *)*Handle,
488 Buffer,
489 Size
490 );
491 if (RETURN_ERROR (Status)) {
492 SerializeVariablesFreeInstance (*Handle);
493 return Status;
494 }
495
496 return Status;
497 }
498
499 /**
500 Iterates all variables found with RuntimeServices GetNextVariableName
501
502 @param[in] CallbackFunction - Function called for each variable instance
503 @param[in] Context - Passed to each call of CallbackFunction
504
505 @retval RETURN_SUCCESS - All variables were iterated without the
506 CallbackFunction returning an error
507 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
508 iterate through the variables
509 @return Any of RETURN_ERROR indicates an error reading the variable
510 or an error was returned from CallbackFunction
511
512 **/
513 RETURN_STATUS
514 EFIAPI
515 SerializeVariablesIterateSystemVariables (
516 IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
517 IN VOID *Context
518 )
519 {
520 RETURN_STATUS Status;
521 UINTN VariableNameBufferSize;
522 UINTN VariableNameSize;
523 CHAR16 *VariableName;
524 EFI_GUID VendorGuid;
525 UINTN VariableDataBufferSize;
526 UINTN VariableDataSize;
527 VOID *VariableData;
528 UINT32 VariableAttributes;
529 VOID *NewBuffer;
530
531 //
532 // Initialize the variable name and data buffer variables.
533 //
534 VariableNameBufferSize = sizeof (CHAR16);
535 VariableName = AllocateZeroPool (VariableNameBufferSize);
536
537 VariableDataBufferSize = 0;
538 VariableData = NULL;
539
540 for ( ; ;) {
541 //
542 // Get the next variable name and guid
543 //
544 VariableNameSize = VariableNameBufferSize;
545 Status = gRT->GetNextVariableName (
546 &VariableNameSize,
547 VariableName,
548 &VendorGuid
549 );
550 if (Status == EFI_BUFFER_TOO_SMALL) {
551 //
552 // The currently allocated VariableName buffer is too small,
553 // so we allocate a larger buffer, and copy the old buffer
554 // to it.
555 //
556 NewBuffer = AllocatePool (VariableNameSize);
557 if (NewBuffer == NULL) {
558 Status = EFI_OUT_OF_RESOURCES;
559 break;
560 }
561
562 CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
563 if (VariableName != NULL) {
564 FreePool (VariableName);
565 }
566
567 VariableName = NewBuffer;
568 VariableNameBufferSize = VariableNameSize;
569
570 //
571 // Try to get the next variable name again with the larger buffer.
572 //
573 Status = gRT->GetNextVariableName (
574 &VariableNameSize,
575 VariableName,
576 &VendorGuid
577 );
578 }
579
580 if (EFI_ERROR (Status)) {
581 if (Status == EFI_NOT_FOUND) {
582 Status = EFI_SUCCESS;
583 }
584
585 break;
586 }
587
588 //
589 // Get the variable data and attributes
590 //
591 VariableDataSize = VariableDataBufferSize;
592 Status = gRT->GetVariable (
593 VariableName,
594 &VendorGuid,
595 &VariableAttributes,
596 &VariableDataSize,
597 VariableData
598 );
599 if (Status == EFI_BUFFER_TOO_SMALL) {
600 //
601 // The currently allocated VariableData buffer is too small,
602 // so we allocate a larger buffer.
603 //
604 if (VariableDataBufferSize != 0) {
605 FreePool (VariableData);
606 VariableData = NULL;
607 VariableDataBufferSize = 0;
608 }
609
610 VariableData = AllocatePool (VariableDataSize);
611 if (VariableData == NULL) {
612 Status = EFI_OUT_OF_RESOURCES;
613 break;
614 }
615
616 VariableDataBufferSize = VariableDataSize;
617
618 //
619 // Try to read the variable again with the larger buffer.
620 //
621 Status = gRT->GetVariable (
622 VariableName,
623 &VendorGuid,
624 &VariableAttributes,
625 &VariableDataSize,
626 VariableData
627 );
628 }
629
630 if (EFI_ERROR (Status)) {
631 break;
632 }
633
634 //
635 // Run the callback function
636 //
637 Status = (*CallbackFunction)(
638 Context,
639 VariableName,
640 &VendorGuid,
641 VariableAttributes,
642 VariableDataSize,
643 VariableData
644 );
645 if (EFI_ERROR (Status)) {
646 break;
647 }
648 }
649
650 if (VariableName != NULL) {
651 FreePool (VariableName);
652 }
653
654 if (VariableData != NULL) {
655 FreePool (VariableData);
656 }
657
658 return Status;
659 }
660
661 /**
662 Iterates all variables found in the variable serialization instance
663
664 @param[in] Handle - Handle for a variable serialization instance
665 @param[in] CallbackFunction - Function called for each variable instance
666 @param[in] Context - Passed to each call of CallbackFunction
667
668 @retval RETURN_SUCCESS - All variables were iterated without the
669 CallbackFunction returning an error
670 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
671 iterate through the variables
672 @return Any of RETURN_ERROR indicates an error reading the variable
673 or an error was returned from CallbackFunction
674
675 **/
676 RETURN_STATUS
677 EFIAPI
678 SerializeVariablesIterateInstanceVariables (
679 IN EFI_HANDLE Handle,
680 IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
681 IN VOID *Context
682 )
683 {
684 SV_INSTANCE *Instance;
685
686 Instance = SV_FROM_HANDLE (Handle);
687
688 if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
689 return IterateVariablesInBuffer (
690 CallbackFunction,
691 Context,
692 Instance->BufferPtr,
693 Instance->DataSize
694 );
695 } else {
696 return RETURN_SUCCESS;
697 }
698 }
699
700 /**
701 Sets all variables found in the variable serialization instance
702
703 @param[in] Handle - Handle for a variable serialization instance
704
705 @retval RETURN_SUCCESS - All variables were set successfully
706 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
707 set all the variables
708 @return Any of RETURN_ERROR indicates an error reading the variables
709 or in attempting to set a variable
710
711 **/
712 RETURN_STATUS
713 EFIAPI
714 SerializeVariablesSetSerializedVariables (
715 IN EFI_HANDLE Handle
716 )
717 {
718 return SerializeVariablesIterateInstanceVariables (
719 Handle,
720 IterateVariablesCallbackSetSystemVariable,
721 NULL
722 );
723 }
724
725 /**
726 Adds a variable to the variable serialization instance
727
728 @param[in] Handle - Handle for a variable serialization instance
729 @param[in] VariableName - Refer to RuntimeServices GetVariable
730 @param[in] VendorGuid - Refer to RuntimeServices GetVariable
731 @param[in] Attributes - Refer to RuntimeServices GetVariable
732 @param[in] DataSize - Refer to RuntimeServices GetVariable
733 @param[in] Data - Refer to RuntimeServices GetVariable
734
735 @retval RETURN_SUCCESS - All variables were set successfully
736 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
737 add the variable
738 @retval RETURN_INVALID_PARAMETER - Handle was not a valid
739 variable serialization instance or
740 VariableName, VariableGuid or Data are NULL.
741
742 **/
743 RETURN_STATUS
744 EFIAPI
745 SerializeVariablesAddVariable (
746 IN EFI_HANDLE Handle,
747 IN CHAR16 *VariableName,
748 IN EFI_GUID *VendorGuid,
749 IN UINT32 Attributes,
750 IN UINTN DataSize,
751 IN VOID *Data
752 )
753 {
754 RETURN_STATUS Status;
755 SV_INSTANCE *Instance;
756 UINT32 SerializedNameSize;
757 UINT32 SerializedDataSize;
758 UINTN SerializedSize;
759
760 Instance = SV_FROM_HANDLE (Handle);
761
762 if ((Instance->Signature != SV_SIGNATURE) ||
763 (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL))
764 {
765 }
766
767 SerializedNameSize = (UINT32)StrSize (VariableName);
768
769 SerializedSize =
770 sizeof (SerializedNameSize) +
771 SerializedNameSize +
772 sizeof (*VendorGuid) +
773 sizeof (Attributes) +
774 sizeof (SerializedDataSize) +
775 DataSize;
776
777 Status = EnsureExtraBufferSpace (
778 Instance,
779 SerializedSize
780 );
781 if (RETURN_ERROR (Status)) {
782 return Status;
783 }
784
785 //
786 // Add name size (UINT32)
787 //
788 AppendToBuffer (Instance, (VOID *)&SerializedNameSize, sizeof (SerializedNameSize));
789
790 //
791 // Add variable unicode name string
792 //
793 AppendToBuffer (Instance, (VOID *)VariableName, SerializedNameSize);
794
795 //
796 // Add variable GUID
797 //
798 AppendToBuffer (Instance, (VOID *)VendorGuid, sizeof (*VendorGuid));
799
800 //
801 // Add variable attributes
802 //
803 AppendToBuffer (Instance, (VOID *)&Attributes, sizeof (Attributes));
804
805 //
806 // Add variable data size (UINT32)
807 //
808 SerializedDataSize = (UINT32)DataSize;
809 AppendToBuffer (Instance, (VOID *)&SerializedDataSize, sizeof (SerializedDataSize));
810
811 //
812 // Add variable data
813 //
814 AppendToBuffer (Instance, Data, DataSize);
815
816 return RETURN_SUCCESS;
817 }
818
819 /**
820 Serializes the variables known to this instance into the
821 provided buffer.
822
823 @param[in] Handle - Handle for a variable serialization instance
824 @param[out] Buffer - A buffer to store the binary representation
825 of the variables.
826 @param[in,out] Size - On input this is the size of the buffer.
827 On output this is the size of the binary representation
828 of the variables.
829
830 @retval RETURN_SUCCESS - The binary representation was successfully
831 completed and returned in the buffer.
832 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
833 save the variables to the buffer.
834 @retval RETURN_INVALID_PARAMETER - Handle was not a valid
835 variable serialization instance or
836 Size or Buffer were NULL.
837 @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
838 the Size parameter was too small for the serialized
839 variable data. Size is returned with the required size.
840
841 **/
842 RETURN_STATUS
843 EFIAPI
844 SerializeVariablesToBuffer (
845 IN EFI_HANDLE Handle,
846 OUT VOID *Buffer,
847 IN OUT UINTN *Size
848 )
849 {
850 SV_INSTANCE *Instance;
851
852 Instance = SV_FROM_HANDLE (Handle);
853
854 if (Size == NULL) {
855 return RETURN_INVALID_PARAMETER;
856 }
857
858 if (*Size < Instance->DataSize) {
859 *Size = Instance->DataSize;
860 return RETURN_BUFFER_TOO_SMALL;
861 }
862
863 if (Buffer == NULL) {
864 return RETURN_INVALID_PARAMETER;
865 }
866
867 *Size = Instance->DataSize;
868 CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
869
870 return RETURN_SUCCESS;
871 }