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