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