3 Read and edit the time-base authenticated variables.
5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "TimeBasedVariable.h"
13 extern LIST_ENTRY mAllVarListEntry
;
14 extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam
;
15 extern G_EFI_FD_INFO gEfiFdInfo
;
17 EFI_GUID gEfiAuthenticatedVariableBasedTimeGuid
= EFI_AUTHENTICATED_VARIABLE_BASED_TIME_GUID
;
20 Gets the pointer to the first variable header in given variable store area.
22 @param VarStoreHeader Pointer to the Variable Store Header.
24 @return Pointer to the first variable header.
30 IN VARIABLE_STORE_HEADER
*VarStoreHeader
34 // The end of variable store.
36 return (VARIABLE_HEADER
*) HEADER_ALIGN (VarStoreHeader
+ 1);
41 Gets the pointer to the end of the variable storage area.
43 This function gets pointer to the end of the variable storage
44 area, according to the input variable store header.
46 @param VarStoreHeader Pointer to the Variable Store Header.
48 @return Pointer to the end of the variable storage area.
54 IN VARIABLE_STORE_HEADER
*VarStoreHeader
58 // The end of variable store
60 return (VARIABLE_HEADER
*) HEADER_ALIGN ((UINTN
) VarStoreHeader
+ VarStoreHeader
->Size
);
66 This code checks if variable header is valid or not.
68 @param Variable Pointer to the Variable Header.
70 @retval TRUE Variable header is valid.
71 @retval FALSE Variable header is not valid.
76 IsValidVariableHeader (
77 IN VARIABLE_HEADER
*Variable
80 if ((Variable
== NULL
) || (Variable
->StartId
!= VARIABLE_DATA
)) {
89 This code gets the size of name of variable.
91 @param Variable Pointer to the Variable Header.
93 @return UINTN Size of variable in bytes.
99 IN VARIABLE_HEADER
*Variable
102 if ((Variable
->State
== (UINT8
) (-1)) ||
103 (Variable
->DataSize
== (UINT32
) (-1)) ||
104 (Variable
->NameSize
== (UINT32
) (-1)) ||
105 (Variable
->Attributes
== (UINT32
) (-1))
109 return (UINTN
) Variable
->NameSize
;
114 This code gets the size of variable data.
116 @param Variable Pointer to the Variable Header.
118 @return Size of variable in bytes.
124 IN VARIABLE_HEADER
*Variable
127 if ((Variable
->State
== (UINT8
) (-1)) ||
128 (Variable
->DataSize
== (UINT32
) (-1)) ||
129 (Variable
->NameSize
== (UINT32
) (-1)) ||
130 (Variable
->Attributes
== (UINT32
) (-1))
134 return (UINTN
) Variable
->DataSize
;
139 This code gets the pointer to the variable name.
141 @param Variable Pointer to the Variable Header.
143 @return Pointer to Variable Name which is Unicode encoding.
149 IN VARIABLE_HEADER
*Variable
152 return (CHAR16
*) (Variable
+ 1);
157 This code gets the pointer to the variable data.
159 @param Variable Pointer to the Variable Header.
161 @return Pointer to Variable Data.
167 IN VARIABLE_HEADER
*Variable
173 // Be careful about pad size for alignment.
175 Value
= (UINTN
) GetVariableNamePtr (Variable
);
176 Value
+= NameSizeOfVariable (Variable
);
177 Value
+= GET_PAD_SIZE (NameSizeOfVariable (Variable
));
179 return (UINT8
*) Value
;
184 This code gets the pointer to the next variable header.
186 @param Variable Pointer to the Variable Header.
188 @return Pointer to next variable header.
194 IN VARIABLE_HEADER
*Variable
199 if (!IsValidVariableHeader (Variable
)) {
203 Value
= (UINTN
) GetVariableDataPtr (Variable
);
204 Value
+= DataSizeOfVariable (Variable
);
205 Value
+= GET_PAD_SIZE (DataSizeOfVariable (Variable
));
208 // Be careful about pad size for alignment.
210 return (VARIABLE_HEADER
*) HEADER_ALIGN (Value
);
214 Search and get a free space in the EFI variable zone
216 @param VariableStoreHeader The start of a EFI variable zone.
217 @param VarListSize The size of a variables needs to be allocated.
218 @param FreeBeginVar The dual pointer to the free NV space.
220 @retval EFI_SUCCESS Return the beginning of a free variable space.
221 @retval RETURN_BUFFER_TOO_SMALL Failed.
226 IN VARIABLE_STORE_HEADER
*VariableStoreHeader
,
227 IN UINT32 VarListSize
,
228 IN OUT CHAR8
**FreeBeginVar
232 VARIABLE_HEADER
*Variable
;
233 VARIABLE_HEADER
*EndOfVariable
;
239 EndOfVariable
= NULL
;
240 *FreeBeginVar
= NULL
;
242 if (VariableStoreHeader
== NULL
) {
243 *FreeBeginVar
= NULL
;
244 return RETURN_INVALID_PARAMETER
;
246 Variable
= GetStartPointer (VariableStoreHeader
);
247 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
249 //Search the beginning of free NV
251 while (Variable
!= EndOfVariable
) {
252 BeginVar
= (CHAR8
*)Variable
;
253 Variable
= GetNextVariablePtr (Variable
);
254 if (Variable
== NULL
) {
260 // Check whether the free space is more than what we want
262 if ((CHAR8
*)BeginVar
+ VarListSize
> (CHAR8
*)EndOfVariable
) {
263 return RETURN_BUFFER_TOO_SMALL
;
266 // If not find the available space, return NULL
269 return RETURN_BUFFER_TOO_SMALL
;
271 *FreeBeginVar
= BeginVar
;
277 Search whether the variable in VarList has existed in current NV.
279 Parse the FFS or Fd image, and find the valid variable pointer.
281 @param VariableStoreHeader The start of a EFI variable zone.
282 @param VarList The pointer to the VarList
284 @retval address If the variable existed in current NV, return address
285 @return NULL Otherwise, return NULL
290 IN VARIABLE_STORE_HEADER
*VariableStoreHeader
,
291 IN FORMSET_STORAGE
*Storage
295 VARIABLE_HEADER
*Variable
;
296 VARIABLE_HEADER
*EndOfVariable
;
297 CHAR16
*VariableName
;
301 EndOfVariable
= NULL
;
304 if ((VariableStoreHeader
== NULL
) || (Storage
== NULL
) || (Storage
->Name
== NULL
)) {
307 Variable
= GetStartPointer (VariableStoreHeader
);
308 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
310 // Parse and compare the variable in the NV space one by one
312 while ((Variable
!= EndOfVariable
) && (Variable
!= NULL
)) {
313 VariableName
= (CHAR16
*)((CHAR8
*)Variable
+ sizeof (VARIABLE_HEADER
));
314 if (!CompareGuid (&Variable
->VendorGuid
, &Storage
->Guid
) \
315 && !FceStrCmp (Storage
->Name
, VariableName
) \
316 && (Variable
->State
== VAR_ADDED
)
321 Variable
= GetNextVariablePtr (Variable
);
329 Exchange the data between Efi variable and the data of VarList when the
330 variable use the time stamp authenticated variable header
332 If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
333 update the data from varlist to efi variable.
335 @param VarToList The flag to control the direction of exchange.
336 @param StorageListHead Decide which variale list be updated
338 @retval EFI_SUCCESS Get the address successfully.
339 @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
340 @retval EFI_INVALID_PARAMETER Invalid variable name.
344 SynAuthEfiVariableBasedTime (
345 IN BOOLEAN VarToList
,
346 IN LIST_ENTRY
*StorageListHead
349 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
350 LIST_ENTRY
*StorageLink
;
351 FORMSET_STORAGE
*Storage
;
353 CHAR8
*NewAvailableAddr
;
355 VARIABLE_HEADER
*VariableHeader
;
356 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
359 Status
= EFI_SUCCESS
;
361 NewAvailableAddr
= NULL
;
363 VariableHeader
= NULL
;
364 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
365 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
367 //Parse the variable range, and check whether there is some existed ones.
369 StorageLink
= GetFirstNode (StorageListHead
);
370 while (!IsNull (StorageListHead
, StorageLink
)) {
371 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
373 // Ignore the invalid varlist node
375 if (Storage
->Buffer
== NULL
) {
376 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
380 // Report error, if the variable name is invalid.
382 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
383 printf ("Error. One variable name is NULL. Its GUID is: ");
384 PrintGuid(&(Storage
->Guid
));
385 return EFI_INVALID_PARAMETER
;
387 VariableHeader
= FindVariableInNv (
394 //Copy the data from NV to the VarList.
396 if (VariableHeader
!= NULL
) {
397 if (Storage
->Buffer
== NULL
) {
398 Storage
->Buffer
= calloc (Storage
->Size
, sizeof (CHAR8
));
399 ASSERT (Storage
->Buffer
!= NULL
);
402 // The variable in VarList is CHAR8, but in the EFI variable is CHAR16.
404 DataBase
= (CHAR8
*)GetVariableDataPtr (VariableHeader
);
413 //If existed, copy the List data to the variable in NV directly. If not found, create a new one.
415 VarNameSize
= 2 * (FceStrLen (Storage
->Name
) + 1);
417 //If this variable has existed in current FD, the data in VarList has
418 // been updated, and this variable is not authenticated type, then
419 // update it from VarList to the FD.
421 if ((VariableHeader
!= NULL
) \
422 && (Storage
->Buffer
!= NULL
)
424 if (!(VariableHeader
->Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
)) {
425 DataBase
= (CHAR8
*)GetVariableDataPtr (VariableHeader
);
432 printf ("Error. Not support to update authenticated variables.\n");
433 return EFI_INVALID_PARAMETER
;
435 } else if ((VariableHeader
== NULL
) && (Storage
->Buffer
!= NULL
)){
437 //If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.
439 if (Storage
->NewEfiVarstore
440 && ((Storage
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)
442 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
446 // Try to get the available zone from the efi variables
448 Status
= GetVariableVar (
450 Storage
->Size
+ sizeof (VARIABLE_HEADER
),
454 if (!EFI_ERROR (Status
)) {
456 // Create the authenticated variable header
458 VariableHeader
= (VARIABLE_HEADER
*) NewAvailableAddr
;
459 VariableHeader
->StartId
= VARIABLE_DATA
;
460 VariableHeader
->State
= VAR_ADDED
;
461 VariableHeader
->Reserved
= 0x0;
462 VariableHeader
->MonotonicCount
= 0x0;
463 memset (&(VariableHeader
->TimeStamp
), 0, sizeof (EFI_TIME
));
464 VariableHeader
->PubKeyIndex
= 0x0;
465 if (Storage
->NewEfiVarstore
) {
466 VariableHeader
->Attributes
= Storage
->Attributes
;
468 VariableHeader
->Attributes
= EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
;
470 VariableHeader
->NameSize
= VarNameSize
;
471 VariableHeader
->DataSize
= Storage
->Size
;
473 //Copy the Guid, variable name, and data in sequence.
476 (VOID
*)&(VariableHeader
->VendorGuid
),
480 NewAvailableAddr
= NewAvailableAddr
+ sizeof (VARIABLE_HEADER
);
482 (VOID
*) NewAvailableAddr
,
487 NewAvailableAddr
= NewAvailableAddr
+ VarNameSize
+ GET_PAD_SIZE (VarNameSize
);
489 (VOID
*) NewAvailableAddr
,
491 Storage
->Size
* sizeof (CHAR8
)
494 printf ("Error. No available space in NV ram.\n");
495 return EFI_OUT_OF_RESOURCES
;
499 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
505 Remove the variable from Efi variable
507 Found the variable with the same name in StorageListHead and remove it.
509 @param StorageListHead Decide which variale list be removed.
511 @retval EFI_SUCCESS Remove the variables successfully.
514 RemoveAuthEfiVariableBasedTime (
515 IN LIST_ENTRY
*StorageListHead
518 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
519 LIST_ENTRY
*StorageLink
;
520 FORMSET_STORAGE
*Storage
;
521 VARIABLE_HEADER
*VariableHeader
;
522 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
524 VariableHeader
= NULL
;
525 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
526 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
528 //Parse the variable range, and check whether there is some existed ones.
530 StorageLink
= GetFirstNode (StorageListHead
);
531 while (!IsNull (StorageListHead
, StorageLink
)) {
532 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
534 // Ignore the invalid varlist node
536 if (Storage
->Buffer
== NULL
) {
537 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
541 // Report error, if the variable name is invalid.
543 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
544 printf ("Error. One variable name is NULL. Its GUID is: ");
545 PrintGuid(&(Storage
->Guid
));
546 return EFI_INVALID_PARAMETER
;
548 VariableHeader
= FindVariableInNv (
552 if (VariableHeader
!= NULL
) {
553 VariableHeader
->State
= VAR_DELETED
;
555 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
561 Check the store variable is Time stamp authenticated or not
563 @param VarToList The pointer to the header of Variable Store.
565 @retval TRUE If authenticated, return TRUE.
566 @retval FALSE Otherwise, return FALSE.
570 CheckTimeBasedVarStoreOrNot (
571 IN VOID
*VariableStoreHeader
575 &gEfiAuthenticatedVariableBasedTimeGuid
,
576 &((VARIABLE_STORE_HEADER
*)VariableStoreHeader
)->Signature
)
585 Copy time-based authenticated variable to binary in multi-platform mode
587 @param Storage The pointer to a storage in storage list.
588 @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
589 @param Index The number of the storage. If the Index is 0, record the variable header to
590 the binary. Or else, only record the storage.
592 @return length The length of storage
595 CopyTimeBasedVariableToBinary (
596 IN FORMSET_STORAGE
*Storage
,
597 IN OUT UINT8
*StorageBeginning
,
602 CHAR8
*NewAvailableAddr
;
603 VARIABLE_HEADER
*VariableHeader
;
604 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
608 Status
= EFI_SUCCESS
;
609 NewAvailableAddr
= NULL
;
612 VariableHeader
= NULL
;
613 VariableStoreHeader
= NULL
;
615 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
616 printf ("Error. One variable name is NULL. Its GUID is: ");
617 PrintGuid(&(Storage
->Guid
));
621 // If the first storage under one specified platformId and defaultId, create the variable header
624 HeaderLength
= WriteDefaultAndPlatformId (StorageBeginning
, Storage
);
625 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ HeaderLength
);
627 //Create the Variable Storage header
629 memcpy (&(VariableStoreHeader
->Signature
), &gEfiAuthenticatedVariableBasedTimeGuid
, sizeof (EFI_GUID
));
630 VariableStoreHeader
->Format
= 0x5A;
631 VariableStoreHeader
->State
= 0xFE;
633 //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.
635 VariableStoreHeader
->Size
= gEfiFdInfo
.FdSize
;
638 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ *(UINT16
*)StorageBeginning
);
640 Status
= GetVariableVar (
642 Storage
->Size
+ sizeof (VARIABLE_HEADER
),
646 if (EFI_ERROR (Status
)) {
650 // Create the variable header
652 VarNameSize
= 2 * (FceStrLen (Storage
->Name
) + 1);
653 VariableHeader
= (VARIABLE_HEADER
*) NewAvailableAddr
;
654 VariableHeader
->StartId
= VARIABLE_DATA
;
655 VariableHeader
->State
= VAR_ADDED
;
656 VariableHeader
->Reserved
= 0x0;
657 VariableHeader
->MonotonicCount
= 0x0;
658 memset (&(VariableHeader
->TimeStamp
), 0, sizeof (EFI_TIME
));
659 VariableHeader
->PubKeyIndex
= 0x0;
661 if (Storage
->NewEfiVarstore
) {
662 VariableHeader
->Attributes
= Storage
->Attributes
;
664 VariableHeader
->Attributes
= EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
;
666 VariableHeader
->NameSize
= VarNameSize
;
667 VariableHeader
->DataSize
= Storage
->Size
;
669 //Copy the Guid, variable name, and data in sequence.
672 (VOID
*)&(VariableHeader
->VendorGuid
),
676 NewAvailableAddr
= NewAvailableAddr
+ sizeof (VARIABLE_HEADER
);
678 (VOID
*) NewAvailableAddr
,
683 NewAvailableAddr
= NewAvailableAddr
+ VarNameSize
+ GET_PAD_SIZE (VarNameSize
);
685 (VOID
*) NewAvailableAddr
,
687 Storage
->Size
* sizeof (CHAR8
)
690 // Return the length which is from the beginning of Binary
692 return ((UINT32
) ((UINT8
*)NewAvailableAddr
- StorageBeginning
) + Storage
->Size
);
696 Read time-based authenticated variable to storage list in multi-platform mode
698 @param Binary The pointer to the header of storage under specifed platformId and defaultId
699 @param StorageListEntry The pointer to the storage list.
701 @return length The length of storage
704 ReadTimeBasedVariableToList (
706 IN LIST_ENTRY
*StorageListEntry
709 VARIABLE_HEADER
*EndOfVariable
;
710 VARIABLE_HEADER
*Variable
;
711 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
712 FORMSET_STORAGE
*Storage
;
713 BOOLEAN ReadIdHeaderFlag
;
715 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
717 static UINT16 PreDefaultId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
718 static UINT64 PrePlatformId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
720 VariableStoreHeader
= NULL
;
722 ReadIdHeaderFlag
= TRUE
;
724 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)Binary
;
725 DataBase
= Binary
+ sizeof (EFI_COMMON_SECTION_HEADER
);
726 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (DataBase
+ *(UINT16
*)DataBase
);
727 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
729 for (Variable
= GetStartPointer (VariableStoreHeader
);
730 Length
< VariableStoreHeader
->Size
;
731 Length
+= sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ Variable
->DataSize
734 // Create the storage
737 Storage
= calloc (sizeof (FORMSET_STORAGE
), sizeof (CHAR8
));
738 if (Storage
== NULL
) {
739 printf ("Allocate memory failed.\n");
743 // If access the first storage, read the platformId and defaultId
745 if (ReadIdHeaderFlag
) {
746 ReadDefaultAndPlatformIdFromBfv (DataBase
, Storage
);
747 Length
+= sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ Variable
->DataSize
;
748 ReadIdHeaderFlag
= FALSE
;
749 memcpy (PreDefaultId
, Storage
->DefaultId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT16
));
750 memcpy (PrePlatformId
, Storage
->PlatformId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
753 // Store the DefaultId and PlatformId collected from the header to Storage.
755 memcpy (Storage
->DefaultId
, PreDefaultId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT16
));
756 memcpy (Storage
->PlatformId
, PrePlatformId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
758 Storage
->Attributes
= Variable
->Attributes
;
759 Storage
->Size
= (UINT16
)Variable
->DataSize
;
760 Storage
->Name
= calloc (Variable
->NameSize
, sizeof (UINT8
));
761 ASSERT (Storage
->Name
!= NULL
);
762 Storage
->Buffer
= calloc (Variable
->DataSize
, sizeof (UINT8
));
763 ASSERT (Storage
->Buffer
!= NULL
);
766 &(Variable
->VendorGuid
),
771 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
),
776 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ GET_PAD_SIZE (Variable
->NameSize
),
777 Storage
->Size
* sizeof (CHAR8
)
780 // Assigned the value for comparison in verify mode
782 Storage
->Type
= EFI_IFR_VARSTORE_EFI_OP
;
783 Storage
->NewEfiVarstore
= TRUE
;
784 InitializeListHead (&Storage
->NameValueListHead
);
786 InsertTailList(StorageListEntry
, &Storage
->Link
);
788 // If the last variable, exit.
790 if (Variable
== EndOfVariable
) {
794 Variable
= GetNextVariablePtr (Variable
);
795 assert (Variable
!= NULL
);
798 // Return the length which is from the beginning of Binary
800 Length
= FvBufExpand3ByteSize (SectionHeader
->Size
);
806 Check whether exists the valid time-based variables in NvStorage or not.
808 @retval TRUE If existed, return TRUE.
812 ExistTimeBasedEfiVarOrNot (
813 IN LIST_ENTRY
*StorageListHead
816 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
817 LIST_ENTRY
*StorageLink
;
818 FORMSET_STORAGE
*Storage
;
819 VARIABLE_HEADER
*VariableHeader
;
820 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
822 VariableHeader
= NULL
;
823 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
824 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
826 //Parse the variable range, and check whether there is some existed ones.
828 StorageLink
= GetFirstNode (StorageListHead
);
829 while (!IsNull (StorageListHead
, StorageLink
)) {
830 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
832 // Ignore the invalid varlist node
834 if ((Storage
->Buffer
== NULL
)
835 || (Storage
->Name
== NULL
)
836 || (FceStrLen(Storage
->Name
) == 0)
838 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
842 // Report error, if the variable name is invalid.
844 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
845 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
848 VariableHeader
= FindVariableInNv (
853 if ((VariableHeader
!= NULL
)) {
856 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
862 Fix the size of time-based variable header.
864 @param Binary The pointer to the header of storage under specifed platformId and defaultId
865 @param Length The length of binary.
869 FixBasedTimeVariableHeaderSize (
870 IN UINT8
*BinaryBeginning
,
874 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
876 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (BinaryBeginning
+ *(UINT16
*)BinaryBeginning
);
877 VariableStoreHeader
->Size
= Length
- *(UINT16
*)BinaryBeginning
;