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