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