]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
OvmfPkg/SerializeVariablesLib: Relax check for the read-only variable
[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
db827286
GL
305 } else if (Status == EFI_WRITE_PROTECTED) {\r
306 DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" "\r
307 "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__,\r
308 VariableName));\r
309 Status = EFI_SUCCESS;\r
e678f9db 310 }\r
311 return Status;\r
251ca604
LE
312}\r
313\r
314\r
315STATIC\r
316RETURN_STATUS\r
317EnsureExtraBufferSpace (\r
318 IN SV_INSTANCE *Instance,\r
319 IN UINTN Size\r
320 )\r
321{\r
322 VOID *NewBuffer;\r
323 UINTN NewSize;\r
324\r
325 NewSize = Instance->DataSize + Size;\r
326 if (NewSize <= Instance->BufferSize) {\r
327 return RETURN_SUCCESS;\r
328 }\r
329\r
330 //\r
331 // Double the required size to lessen the need to re-allocate in the future\r
332 //\r
333 NewSize = 2 * NewSize;\r
334\r
335 NewBuffer = AllocatePool (NewSize);\r
336 if (NewBuffer == NULL) {\r
337 return RETURN_OUT_OF_RESOURCES;\r
338 }\r
339\r
340 if (Instance->BufferPtr != NULL) {\r
341 CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);\r
342 FreePool (Instance->BufferPtr);\r
343 }\r
344\r
345 Instance->BufferPtr = NewBuffer;\r
346 Instance->BufferSize = NewSize;\r
347\r
348 return RETURN_SUCCESS;\r
349}\r
350\r
351\r
352STATIC\r
353VOID\r
354AppendToBuffer (\r
355 IN SV_INSTANCE *Instance,\r
356 IN VOID *Data,\r
357 IN UINTN Size\r
358 )\r
359{\r
360 UINTN NewSize;\r
361\r
362 ASSERT (Instance != NULL);\r
363 ASSERT (Data != NULL);\r
364\r
365 NewSize = Instance->DataSize + Size;\r
366 ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);\r
367\r
368 CopyMem (\r
369 (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize),\r
370 Data,\r
371 Size\r
372 );\r
373\r
374 Instance->DataSize = NewSize;\r
375}\r
376\r
377\r
378/**\r
379 Creates a new variable serialization instance\r
380\r
381 @param[out] Handle - Handle for a variable serialization instance\r
382\r
383 @retval RETURN_SUCCESS - The variable serialization instance was\r
384 successfully created.\r
385 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
386 create the variable serialization instance.\r
387\r
388**/\r
389RETURN_STATUS\r
390EFIAPI\r
391SerializeVariablesNewInstance (\r
392 OUT EFI_HANDLE *Handle\r
393 )\r
394{\r
395 SV_INSTANCE *New;\r
396\r
397 New = AllocateZeroPool (sizeof (*New));\r
398 if (New == NULL) {\r
399 return RETURN_OUT_OF_RESOURCES;\r
400 }\r
401\r
402 New->Signature = SV_SIGNATURE;\r
403\r
404 *Handle = (EFI_HANDLE) New;\r
405 return RETURN_SUCCESS;\r
406}\r
407\r
408\r
409/**\r
410 Free memory associated with a variable serialization instance\r
411\r
412 @param[in] Handle - Handle for a variable serialization instance\r
413\r
414 @retval RETURN_SUCCESS - The variable serialization instance was\r
415 successfully freed.\r
416 @retval RETURN_INVALID_PARAMETER - Handle was not a valid\r
417 variable serialization instance.\r
418\r
419**/\r
420RETURN_STATUS\r
421EFIAPI\r
422SerializeVariablesFreeInstance (\r
423 IN EFI_HANDLE Handle\r
424 )\r
425{\r
426 SV_INSTANCE *Instance;\r
427\r
428 Instance = SV_FROM_HANDLE (Handle);\r
429\r
430 if (Instance->Signature != SV_SIGNATURE) {\r
431 return RETURN_INVALID_PARAMETER;\r
432 }\r
433\r
434 Instance->Signature = 0;\r
435\r
436 if (Instance->BufferPtr != NULL) {\r
437 FreePool (Instance->BufferPtr);\r
438 }\r
439\r
440 FreePool (Instance);\r
441\r
442 return RETURN_SUCCESS;\r
443}\r
444\r
445\r
446/**\r
447 Creates a new variable serialization instance using the given\r
448 binary representation of the variables to fill the new instance\r
449\r
450 @param[out] Handle - Handle for a variable serialization instance\r
451 @param[in] Buffer - A buffer with the serialized representation\r
452 of the variables. Must be the same format as produced\r
453 by SerializeVariablesToBuffer.\r
454 @param[in] Size - This is the size of the binary representation\r
455 of the variables.\r
456\r
457 @retval RETURN_SUCCESS - The binary representation was successfully\r
458 imported into a new variable serialization instance\r
459 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
460 create the new variable serialization instance\r
461\r
462**/\r
463RETURN_STATUS\r
464EFIAPI\r
465SerializeVariablesNewInstanceFromBuffer (\r
466 OUT EFI_HANDLE *Handle,\r
467 IN VOID *Buffer,\r
468 IN UINTN Size\r
469 )\r
470{\r
471 RETURN_STATUS Status;\r
472\r
473 Status = SerializeVariablesNewInstance (Handle);\r
474 if (RETURN_ERROR (Status)) {\r
475 return Status;\r
476 }\r
477\r
478 Status = IterateVariablesInBuffer (\r
479 IterateVariablesCallbackNop,\r
480 NULL,\r
481 Buffer,\r
482 Size\r
483 );\r
484 if (RETURN_ERROR (Status)) {\r
485 SerializeVariablesFreeInstance (*Handle);\r
486 return Status;\r
487 }\r
488\r
489 Status = IterateVariablesInBuffer (\r
490 IterateVariablesCallbackSetInInstance,\r
491 (VOID*) *Handle,\r
492 Buffer,\r
493 Size\r
494 );\r
495 if (RETURN_ERROR (Status)) {\r
496 SerializeVariablesFreeInstance (*Handle);\r
497 return Status;\r
498 }\r
499\r
500 return Status;\r
501}\r
502\r
503\r
504/**\r
505 Iterates all variables found with RuntimeServices GetNextVariableName\r
506\r
507 @param[in] CallbackFunction - Function called for each variable instance\r
508 @param[in] Context - Passed to each call of CallbackFunction\r
509\r
510 @retval RETURN_SUCCESS - All variables were iterated without the\r
511 CallbackFunction returning an error\r
512 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
513 iterate through the variables\r
514 @return Any of RETURN_ERROR indicates an error reading the variable\r
515 or an error was returned from CallbackFunction\r
516\r
517**/\r
518RETURN_STATUS\r
519EFIAPI\r
520SerializeVariablesIterateSystemVariables (\r
521 IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,\r
522 IN VOID *Context\r
523 )\r
524{\r
525 RETURN_STATUS Status;\r
526 UINTN VariableNameBufferSize;\r
527 UINTN VariableNameSize;\r
528 CHAR16 *VariableName;\r
529 EFI_GUID VendorGuid;\r
530 UINTN VariableDataBufferSize;\r
531 UINTN VariableDataSize;\r
532 VOID *VariableData;\r
533 UINT32 VariableAttributes;\r
534 VOID *NewBuffer;\r
535\r
536 //\r
537 // Initialize the variable name and data buffer variables.\r
538 //\r
539 VariableNameBufferSize = sizeof (CHAR16);\r
540 VariableName = AllocateZeroPool (VariableNameBufferSize);\r
541\r
542 VariableDataBufferSize = 0;\r
543 VariableData = NULL;\r
544\r
545 for (;;) {\r
546 //\r
547 // Get the next variable name and guid\r
548 //\r
549 VariableNameSize = VariableNameBufferSize;\r
550 Status = gRT->GetNextVariableName (\r
551 &VariableNameSize,\r
552 VariableName,\r
553 &VendorGuid\r
554 );\r
555 if (Status == EFI_BUFFER_TOO_SMALL) {\r
556 //\r
557 // The currently allocated VariableName buffer is too small,\r
558 // so we allocate a larger buffer, and copy the old buffer\r
559 // to it.\r
560 //\r
561 NewBuffer = AllocatePool (VariableNameSize);\r
562 if (NewBuffer == NULL) {\r
563 Status = EFI_OUT_OF_RESOURCES;\r
564 break;\r
565 }\r
566 CopyMem (NewBuffer, VariableName, VariableNameBufferSize);\r
567 if (VariableName != NULL) {\r
568 FreePool (VariableName);\r
569 }\r
570 VariableName = NewBuffer;\r
571 VariableNameBufferSize = VariableNameSize;\r
572\r
573 //\r
574 // Try to get the next variable name again with the larger buffer.\r
575 //\r
576 Status = gRT->GetNextVariableName (\r
577 &VariableNameSize,\r
578 VariableName,\r
579 &VendorGuid\r
580 );\r
581 }\r
582\r
583 if (EFI_ERROR (Status)) {\r
584 if (Status == EFI_NOT_FOUND) {\r
585 Status = EFI_SUCCESS;\r
586 }\r
587 break;\r
588 }\r
589\r
590 //\r
591 // Get the variable data and attributes\r
592 //\r
593 VariableDataSize = VariableDataBufferSize;\r
594 Status = gRT->GetVariable (\r
595 VariableName,\r
596 &VendorGuid,\r
597 &VariableAttributes,\r
598 &VariableDataSize,\r
599 VariableData\r
600 );\r
601 if (Status == EFI_BUFFER_TOO_SMALL) {\r
602 //\r
603 // The currently allocated VariableData buffer is too small,\r
604 // so we allocate a larger buffer.\r
605 //\r
606 if (VariableDataBufferSize != 0) {\r
607 FreePool (VariableData);\r
608 VariableData = NULL;\r
609 VariableDataBufferSize = 0;\r
610 }\r
611 VariableData = AllocatePool (VariableDataSize);\r
612 if (VariableData == NULL) {\r
613 Status = EFI_OUT_OF_RESOURCES;\r
614 break;\r
615 }\r
616 VariableDataBufferSize = VariableDataSize;\r
617\r
618 //\r
619 // Try to read the variable again with the larger buffer.\r
620 //\r
621 Status = gRT->GetVariable (\r
622 VariableName,\r
623 &VendorGuid,\r
624 &VariableAttributes,\r
625 &VariableDataSize,\r
626 VariableData\r
627 );\r
628 }\r
629 if (EFI_ERROR (Status)) {\r
630 break;\r
631 }\r
632\r
633 //\r
634 // Run the callback function\r
635 //\r
636 Status = (*CallbackFunction) (\r
637 Context,\r
638 VariableName,\r
639 &VendorGuid,\r
640 VariableAttributes,\r
641 VariableDataSize,\r
642 VariableData\r
643 );\r
644 if (EFI_ERROR (Status)) {\r
645 break;\r
646 }\r
647\r
648 }\r
649\r
650 if (VariableName != NULL) {\r
651 FreePool (VariableName);\r
652 }\r
653\r
654 if (VariableData != NULL) {\r
655 FreePool (VariableData);\r
656 }\r
657\r
658 return Status;\r
659}\r
660\r
661\r
662/**\r
663 Iterates all variables found in the variable serialization instance\r
664\r
665 @param[in] Handle - Handle for a variable serialization instance\r
666 @param[in] CallbackFunction - Function called for each variable instance\r
667 @param[in] Context - Passed to each call of CallbackFunction\r
668\r
669 @retval RETURN_SUCCESS - All variables were iterated without the\r
670 CallbackFunction returning an error\r
671 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
672 iterate through the variables\r
673 @return Any of RETURN_ERROR indicates an error reading the variable\r
674 or an error was returned from CallbackFunction\r
675\r
676**/\r
677RETURN_STATUS\r
678EFIAPI\r
679SerializeVariablesIterateInstanceVariables (\r
680 IN EFI_HANDLE Handle,\r
681 IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,\r
682 IN VOID *Context\r
683 )\r
684{\r
685 SV_INSTANCE *Instance;\r
686\r
687 Instance = SV_FROM_HANDLE (Handle);\r
688\r
689 if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {\r
690 return IterateVariablesInBuffer (\r
691 CallbackFunction,\r
692 Context,\r
693 Instance->BufferPtr,\r
694 Instance->DataSize\r
695 );\r
696 } else {\r
697 return RETURN_SUCCESS;\r
698 }\r
699}\r
700\r
701\r
702/**\r
703 Sets all variables found in the variable serialization instance\r
704\r
705 @param[in] Handle - Handle for a variable serialization instance\r
706\r
707 @retval RETURN_SUCCESS - All variables were set successfully\r
708 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
709 set all the variables\r
710 @return Any of RETURN_ERROR indicates an error reading the variables\r
711 or in attempting to set a variable\r
712\r
713**/\r
714RETURN_STATUS\r
715EFIAPI\r
716SerializeVariablesSetSerializedVariables (\r
717 IN EFI_HANDLE Handle\r
718 )\r
719{\r
720 return SerializeVariablesIterateInstanceVariables (\r
721 Handle,\r
722 IterateVariablesCallbackSetSystemVariable,\r
723 NULL\r
724 );\r
725}\r
726\r
727\r
728/**\r
729 Adds a variable to the variable serialization instance\r
730\r
731 @param[in] Handle - Handle for a variable serialization instance\r
732 @param[in] VariableName - Refer to RuntimeServices GetVariable\r
733 @param[in] VendorGuid - Refer to RuntimeServices GetVariable\r
734 @param[in] Attributes - Refer to RuntimeServices GetVariable\r
735 @param[in] DataSize - Refer to RuntimeServices GetVariable\r
736 @param[in] Data - Refer to RuntimeServices GetVariable\r
737\r
738 @retval RETURN_SUCCESS - All variables were set successfully\r
739 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
740 add the variable\r
741 @retval RETURN_INVALID_PARAMETER - Handle was not a valid\r
742 variable serialization instance or\r
743 VariableName, VariableGuid or Data are NULL.\r
744\r
745**/\r
746RETURN_STATUS\r
747EFIAPI\r
748SerializeVariablesAddVariable (\r
749 IN EFI_HANDLE Handle,\r
750 IN CHAR16 *VariableName,\r
751 IN EFI_GUID *VendorGuid,\r
752 IN UINT32 Attributes,\r
753 IN UINTN DataSize,\r
754 IN VOID *Data\r
755 )\r
756{\r
757 RETURN_STATUS Status;\r
758 SV_INSTANCE *Instance;\r
759 UINT32 SerializedNameSize;\r
760 UINT32 SerializedDataSize;\r
761 UINTN SerializedSize;\r
762\r
763 Instance = SV_FROM_HANDLE (Handle);\r
764\r
765 if ((Instance->Signature != SV_SIGNATURE) ||\r
766 (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {\r
767 }\r
768\r
769 SerializedNameSize = (UINT32) StrSize (VariableName);\r
770\r
771 SerializedSize =\r
772 sizeof (SerializedNameSize) +\r
773 SerializedNameSize +\r
774 sizeof (*VendorGuid) +\r
775 sizeof (Attributes) +\r
776 sizeof (SerializedDataSize) +\r
777 DataSize;\r
778\r
779 Status = EnsureExtraBufferSpace (\r
780 Instance,\r
781 SerializedSize\r
782 );\r
783 if (RETURN_ERROR (Status)) {\r
784 return Status;\r
785 }\r
786\r
787 //\r
788 // Add name size (UINT32)\r
789 //\r
790 AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (SerializedNameSize));\r
791\r
792 //\r
793 // Add variable unicode name string\r
794 //\r
795 AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize);\r
796\r
797 //\r
798 // Add variable GUID\r
799 //\r
800 AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid));\r
801\r
802 //\r
803 // Add variable attributes\r
804 //\r
805 AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes));\r
806\r
807 //\r
808 // Add variable data size (UINT32)\r
809 //\r
810 SerializedDataSize = (UINT32) DataSize;\r
811 AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (SerializedDataSize));\r
812\r
813 //\r
814 // Add variable data\r
815 //\r
816 AppendToBuffer (Instance, Data, DataSize);\r
817\r
818 return RETURN_SUCCESS;\r
819}\r
820\r
821\r
822/**\r
823 Serializes the variables known to this instance into the\r
824 provided buffer.\r
825\r
826 @param[in] Handle - Handle for a variable serialization instance\r
827 @param[out] Buffer - A buffer to store the binary representation\r
828 of the variables.\r
829 @param[in,out] Size - On input this is the size of the buffer.\r
830 On output this is the size of the binary representation\r
831 of the variables.\r
832\r
833 @retval RETURN_SUCCESS - The binary representation was successfully\r
834 completed and returned in the buffer.\r
835 @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to\r
836 save the variables to the buffer.\r
837 @retval RETURN_INVALID_PARAMETER - Handle was not a valid\r
838 variable serialization instance or\r
839 Size or Buffer were NULL.\r
840 @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by\r
841 the Size parameter was too small for the serialized\r
842 variable data. Size is returned with the required size.\r
843\r
844**/\r
845RETURN_STATUS\r
846EFIAPI\r
847SerializeVariablesToBuffer (\r
848 IN EFI_HANDLE Handle,\r
849 OUT VOID *Buffer,\r
850 IN OUT UINTN *Size\r
851 )\r
852{\r
853 SV_INSTANCE *Instance;\r
854\r
855 Instance = SV_FROM_HANDLE (Handle);\r
856\r
857 if (Size == NULL) {\r
858 return RETURN_INVALID_PARAMETER;\r
859 }\r
860\r
861 if (*Size < Instance->DataSize) {\r
862 *Size = Instance->DataSize;\r
863 return RETURN_BUFFER_TOO_SMALL;\r
864 }\r
865\r
866 if (Buffer == NULL) {\r
867 return RETURN_INVALID_PARAMETER;\r
868 }\r
869\r
870 *Size = Instance->DataSize;\r
871 CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);\r
872\r
873 return RETURN_SUCCESS;\r
874}\r
875\r