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