3 FCE is a tool which enables developers to retrieve and change HII configuration ("Setup")
4 data in Firmware Device files (".fd" files).
6 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #define COPY_STR "copy \"%s\" \"%s\" > NUL"
15 #define RMDIR_STR "rmdir /S /Q \"%s\" > NUL"
16 #define DEL_STR "del \"%s\" > NUL"
18 #define COPY_STR "cp \"%s\" \"%s\" > /dev/null"
19 #define RMDIR_STR "rm -r \"%s\" > /dev/null"
20 #define DEL_STR "rm \"%s\" > /dev/null"
24 // Utility global variables
26 OPERATION_TYPE Operations
;
28 CHAR8 mInputFdName
[MAX_FILENAME_LEN
];
29 CHAR8 mOutputFdName
[MAX_FILENAME_LEN
];
30 CHAR8 mOutTxtName
[MAX_FILENAME_LEN
];
31 CHAR8 mSetupTxtName
[MAX_FILENAME_LEN
];
33 CHAR8
* mUtilityFilename
= NULL
;
34 UINT32 mEfiVariableAddr
= 0;
36 UQI_PARAM_LIST
*mUqiList
= NULL
;
37 UQI_PARAM_LIST
*mLastUqiList
= NULL
;
38 LIST_ENTRY mVarListEntry
;
39 LIST_ENTRY mBfvVarListEntry
;
40 LIST_ENTRY mAllVarListEntry
;
41 LIST_ENTRY mFormSetListEntry
;
44 // Store GUIDed Section guid->tool mapping
46 EFI_HANDLE mParsedGuidedSectionTools
= NULL
;
48 CHAR8
* mGuidToolDefinition
= "GuidToolDefinitionConf.ini";
51 //gFfsArray is used to store all the FFS informations of Fd
53 G_EFI_FD_INFO gEfiFdInfo
;
55 //mMultiPlatformParam is used to store the structures about multi-platform support
57 MULTI_PLATFORM_PARAMETERS mMultiPlatformParam
;
59 UINT32 mFormSetOrderRead
;
60 UINT32 mFormSetOrderParse
;
62 CHAR8 mFullGuidToolDefinitionDir
[_MAX_PATH
];
64 CHAR8
*mFvNameGuidString
= NULL
;
67 Check the revision of BfmLib. If not matched, return an error.
69 @retval EFI_SUCCESS If revision matched, return EFI_SUCCESS.
70 @retval EFI_UNSUPPORTED Other cases.
78 CHAR8
*SystemCommandFormatString
;
80 CHAR8
*TempSystemCommand
;
83 CHAR8 RevisionStr
[_MAX_BUILD_VERSION
];
86 SystemCommandFormatString
= NULL
;
88 TempSystemCommand
= NULL
;
89 Revision
= "Revision.txt";
91 memset (RevisionStr
, 0, _MAX_BUILD_VERSION
);
94 // Construction 'system' command string
96 SystemCommandFormatString
= "BfmLib -v > %s";
97 SystemCommand
= malloc (
98 strlen (SystemCommandFormatString
) + strlen (Revision
) + 1
100 if (SystemCommand
== NULL
) {
101 return EFI_UNSUPPORTED
;
109 if (mFullGuidToolDefinitionDir
[0] != 0) {
110 TempSystemCommand
= SystemCommand
;
111 SystemCommand
= malloc (
112 strlen (mFullGuidToolDefinitionDir
) + strlen (OS_SEP_STR
) + strlen (SystemCommandFormatString
) + strlen (Revision
) + 1
115 if (SystemCommand
== NULL
) {
116 free (TempSystemCommand
);
117 return EFI_UNSUPPORTED
;
119 strcpy (SystemCommand
, mFullGuidToolDefinitionDir
);
120 strcat (SystemCommand
, OS_SEP_STR
);
121 strcat (SystemCommand
, TempSystemCommand
);
122 free (TempSystemCommand
);
125 system (SystemCommand
);
126 free (SystemCommand
);
127 FileHandle
= fopen (Revision
, "r");
128 if (FileHandle
== NULL
) {
129 printf ("Error. Read the revision file of BfmLib failed.\n");
132 fgets(RevisionStr
, _MAX_BUILD_VERSION
, FileHandle
);
133 Len
= strlen(RevisionStr
);
134 if (RevisionStr
[Len
- 1] == '\n') {
135 RevisionStr
[Len
- 1] = 0;
140 if (strlen (RevisionStr
) > _MAX_BUILD_VERSION
- 1) {
141 printf ("The revision string is too long");
142 return EFI_UNSUPPORTED
;
144 if (strcmp (RevisionStr
, __BUILD_VERSION
) == 0) {
147 return EFI_UNSUPPORTED
;
151 Transfer the Ascii string to the Dec Number
153 @param InStr The Ascii string.
155 @retval DecNum Return the Dec number.
174 while (Index
< strlen (InStr
)) {
176 if ((*(InStr
+ Index
) >= '0') && (*(InStr
+ Index
) <= '9')) {
177 Temp
= *(InStr
+ Index
) - '0';
178 } else if ((*(InStr
+ Index
) >= 'a') && (*(InStr
+ Index
) <= 'f')) {
179 Temp
= *(InStr
+ Index
) - 'a' + 10;
180 } else if ((*(InStr
+ Index
) >= 'A') && (*(InStr
+ Index
) <= 'F')) {
181 Temp
= *(InStr
+ Index
) - 'A' + 10;
183 DecNum
= DecNum
+ Temp
* (UINTN
) pow (16, strlen (InStr
) - Index
- 1);
189 Check whether there are some errors in uqi parameters of One_of
191 @param Question The pointer to the question Node.
192 @param UqiValue The value of One_of.
194 @retval TRUE If existed error, return TRUE;
195 @return FALSE Otherwise, return FALSE;
199 CheckOneOfParamError (
200 IN CONST FORM_BROWSER_STATEMENT
*Question
,
205 QUESTION_OPTION
*Option
;
212 Link
= GetFirstNode (&Question
->OptionListHead
);
213 while (!IsNull (&Question
->OptionListHead
, Link
)) {
214 Option
= QUESTION_OPTION_FROM_LINK (Link
);
216 CopyMem (&Value
, &Option
->Value
.Value
.u64
, Question
->StorageWidth
);
217 if (Value
== UqiValue
) {
220 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
227 Check whether there are some errors in uqi parameters of Orderlist
229 @param HiiObjList The pointer to the Hii Object Node.
230 @param UqiValue The pointer to the Uqi parameter.
232 @retval TRUE If existed error, return TRUE;
233 @return FALSE Otherwise, return FALSE;
237 CheckOrderParamError (
238 IN CONST FORM_BROWSER_STATEMENT
*Question
,
243 MaxNum
= UqiValue
[0];
245 if (MaxNum
!= (UINT8
)(Question
->MaxContainers
)) {
253 Writes a Unicode string
255 @param Package A pointer to the Unicode string.
267 if (pcString
== NULL
) {
271 for (Index
= 0; pcString
[Index
] != 0; Index
++) {
272 printf("%c", pcString
[Index
] & 0x00FF);
277 Parse and set the quick configure information by the command line.
279 Read the UQI Config information from command line directly, and then compare it with the value in VarList.
280 Update the Update flag in Varlist.
282 @param CurUqiList The pointer to the current uqi
283 @param DefaultId The default Id.
284 @param PlatformId The platform Id.
285 @param CurQuestion The pointer to the matched question
287 @retval EFI_SUCCESS It was complete successfully
288 @retval EFI_UNSUPPORTED Update a read-only value
289 @return EFI_ABORTED An error occurred
293 SetUqiParametersWithQuestion (
294 IN UQI_PARAM_LIST
*CurUqiList
,
296 IN UINT64 PlatformId
,
297 IN FORM_BROWSER_STATEMENT
*CurQuestion
300 FORMSET_STORAGE
*VarList
;
302 UINT8
*ValueAddrOfVar
;
304 UINT64 QuestionValue
;
308 FORM_BROWSER_FORMSET
*FormSet
;
309 LIST_ENTRY
*FormSetLink
;
314 ValueAddrOfVar
= NULL
;
318 Status
= EFI_SUCCESS
;
324 // Search the Variable List by VarStoreId and Offset
327 FormSetLink
= GetFirstNode (&mFormSetListEntry
);
328 while (!IsNull (&mFormSetListEntry
, FormSetLink
)) {
329 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink
);
330 Status
= SearchVarStorage (
333 CurQuestion
->VarStoreInfo
.VarOffset
,
334 FormSet
->StorageListHead
,
335 (CHAR8
**) &ValueAddrOfVar
,
339 if (!EFI_ERROR (Status
)) {
343 FormSetLink
= GetNextNode (&mFormSetListEntry
, FormSetLink
);
347 if (CurUqiList
->Header
.ScriptsLine
== 0) {
348 printf ("Error. The question in the command line doesn't store value by EFI_VARSTORE_IFR or EFI_VARSTORE_IFR_EFI.\n");
350 printf ("Error. The question in the line %d of script doesn't store value by EFI_VARSTORE_IFR or EFI_VARSTORE_IFR_EFI.\n", CurUqiList
->Header
.ScriptsLine
);
356 // Check the length of variable value
358 if (CurQuestion
->QuestionReferToBitField
) {
359 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)&QuestionValue
);
361 switch (CurQuestion
->StorageWidth
) {
364 QuestionValue
= *(UINT8
*)ValueAddrOfVar
;
367 case sizeof (UINT16
):
368 QuestionValue
= *(UINT16
*)ValueAddrOfVar
;
371 case sizeof (UINT32
):
372 QuestionValue
= *(UINT32
*)ValueAddrOfVar
;
375 case sizeof (UINT64
):
376 QuestionValue
= *(UINT64
*)ValueAddrOfVar
;
381 // The storage width of ORDERED_LIST may not be any type above.
387 UqiValue
= *(UINT64
*)CurUqiList
->Header
.Value
;
388 CurUqiList
->SameOrNot
= TRUE
;
391 // Check and set the checkbox value
393 if (CurQuestion
->Operand
== EFI_IFR_CHECKBOX_OP
) {
394 if ((UqiValue
!= 0) && (UqiValue
!= 1)) {
395 CurUqiList
->ErrorOrNot
= TRUE
;
396 CurUqiList
->SameOrNot
= FALSE
;
397 CurUqiList
->Error
= malloc (ERROR_INFO_LENGTH
* sizeof (CHAR8
));
398 if (CurUqiList
->Error
== NULL
) {
399 printf ("Fail to allocate memory!\n");
402 memset (CurUqiList
->Error
, 0, ERROR_INFO_LENGTH
);
403 sprintf (CurUqiList
->Error
, "Error. The updated value of CHECKBOX 0x%llx is invalid.\n", (unsigned long long) UqiValue
);
404 if (CurQuestion
->QuestionReferToBitField
) {
405 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
408 CurUqiList
->Header
.DiffValue
,
410 CurQuestion
->StorageWidth
414 if (QuestionValue
!= UqiValue
) {
415 if (CurQuestion
->QuestionReferToBitField
) {
416 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
417 SetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, *(UINT32
*)CurUqiList
->Header
.Value
);
420 CurUqiList
->Header
.DiffValue
,
422 CurQuestion
->StorageWidth
426 CurUqiList
->Header
.Value
,
427 CurQuestion
->StorageWidth
430 CurUqiList
->SameOrNot
= FALSE
;
434 if (CurQuestion
->Operand
== EFI_IFR_STRING_OP
) {
435 if ((FceStrLen((wchar_t *)CurUqiList
->Header
.Value
) + 1) * 2 > CurQuestion
->StorageWidth
) {
436 CurUqiList
->ErrorOrNot
= TRUE
;
437 CurUqiList
->Error
= malloc (ERROR_INFO_LENGTH
* sizeof (CHAR8
));
438 if (CurUqiList
->Error
== NULL
) {
439 printf ("Fail to allocate memory!\n");
442 memset (CurUqiList
->Error
, 0, ERROR_INFO_LENGTH
);
443 sprintf (CurUqiList
->Error
, "Error. The updated value of STRING exceed its Size.\n");
445 CurUqiList
->Header
.DiffValue
,
447 CurQuestion
->StorageWidth
450 if (memcmp((CHAR8
*)CurUqiList
->Header
.Value
, ValueAddrOfVar
, CurQuestion
->StorageWidth
) != 0) {
452 CurUqiList
->Header
.DiffValue
,
454 CurQuestion
->StorageWidth
458 CurUqiList
->Header
.Value
,
459 CurQuestion
->StorageWidth
461 CurUqiList
->SameOrNot
= FALSE
;
466 // Check and set the NUMERIC value
468 if (CurQuestion
->Operand
== EFI_IFR_NUMERIC_OP
) {
469 if ((UqiValue
< CurQuestion
->Minimum
) || (UqiValue
> CurQuestion
->Maximum
)) {
470 CurUqiList
->ErrorOrNot
= TRUE
;
471 CurUqiList
->SameOrNot
= FALSE
;
472 CurUqiList
->Error
= malloc (ERROR_INFO_LENGTH
* sizeof (CHAR8
));
473 if (CurUqiList
->Error
== NULL
) {
474 printf ("Fail to allocate memory!\n");
477 memset (CurUqiList
->Error
, 0, ERROR_INFO_LENGTH
);
478 sprintf (CurUqiList
->Error
, "Error. The updated value of NUMERIC 0x%llx is invalid.\n", (unsigned long long) UqiValue
);
479 if (CurQuestion
->QuestionReferToBitField
) {
480 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
483 CurUqiList
->Header
.DiffValue
,
485 CurQuestion
->StorageWidth
489 if (QuestionValue
!= UqiValue
) {
490 if (CurQuestion
->QuestionReferToBitField
) {
491 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
492 SetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, *(UINT32
*)CurUqiList
->Header
.Value
);
495 CurUqiList
->Header
.DiffValue
,
497 CurQuestion
->StorageWidth
501 CurUqiList
->Header
.Value
,
502 CurQuestion
->StorageWidth
505 CurUqiList
->SameOrNot
= FALSE
;
510 // Check and set the ONE_OF value
512 if (CurQuestion
->Operand
== EFI_IFR_ONE_OF_OP
) {
513 if (CheckOneOfParamError (CurQuestion
, UqiValue
)) {
514 CurUqiList
->ErrorOrNot
= TRUE
;
515 CurUqiList
->SameOrNot
= FALSE
;
516 CurUqiList
->Error
= malloc (ERROR_INFO_LENGTH
* sizeof (CHAR8
));
517 if (CurUqiList
->Error
== NULL
) {
518 printf ("Fail to allocate memory!\n");
521 memset (CurUqiList
->Error
, 0, ERROR_INFO_LENGTH
);
522 sprintf (CurUqiList
->Error
, "Error. The updated ONE_OF value 0x%llx is invalid.\n", (unsigned long long) UqiValue
);
523 if (CurQuestion
->QuestionReferToBitField
) {
524 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
527 CurUqiList
->Header
.DiffValue
,
529 CurQuestion
->StorageWidth
533 if (QuestionValue
!= UqiValue
) {
534 if (CurQuestion
->QuestionReferToBitField
) {
535 GetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, (UINT32
*)CurUqiList
->Header
.DiffValue
);
536 SetBitsQuestionValue (CurQuestion
, ValueAddrOfVar
, *(UINT32
*)CurUqiList
->Header
.Value
);
539 CurUqiList
->Header
.DiffValue
,
541 CurQuestion
->StorageWidth
545 CurUqiList
->Header
.Value
,
546 CurQuestion
->StorageWidth
549 CurUqiList
->SameOrNot
= FALSE
;
554 // Check and set the ORDER_LIST value
556 if (CurQuestion
->Operand
== EFI_IFR_ORDERED_LIST_OP
) {
558 // Synchronize the MaxContainers value
560 *CurUqiList
->Header
.DiffValue
= (UINT8
)CurQuestion
->MaxContainers
;
562 if (CheckOrderParamError (CurQuestion
, (CHAR8
*)CurUqiList
->Header
.Value
)) {
564 CurUqiList
->ErrorOrNot
= TRUE
;
565 CurUqiList
->SameOrNot
= FALSE
;
566 CurUqiList
->Error
= malloc (ERROR_INFO_LENGTH
* sizeof (CHAR8
));
567 if (CurUqiList
->Error
== NULL
) {
568 printf ("Fail to allocate memory!\n");
571 memset (CurUqiList
->Error
, 0, ERROR_INFO_LENGTH
);
573 ErrorStr
= CurUqiList
->Error
;
574 sprintf (ErrorStr
, "Error. The updated NORDERED_LIST value ");
575 ErrorStr
= ErrorStr
+ strlen ("Error. The updated NORDERED_LIST value ");
577 for (Index
= 0; Index
< CurQuestion
->StorageWidth
; Index
++) {
578 sprintf (ErrorStr
, "%02x ", *(CurUqiList
->Header
.Value
+ Index
+ 1));
581 sprintf (ErrorStr
, "is invalid.\n");
583 CurUqiList
->Header
.DiffValue
+ 1,
585 CurQuestion
->StorageWidth
588 for (Index
= 0; Index
< CurQuestion
->StorageWidth
/CurQuestion
->MaxContainers
; Index
++) {
592 (ValueAddrOfVar
+ Index
* CurQuestion
->StorageWidth
/CurQuestion
->MaxContainers
),
593 CurQuestion
->StorageWidth
/CurQuestion
->MaxContainers
595 if (CurValue
!= *((UINT64
*)CurUqiList
->Header
.Value
+ Index
+ 1)) {
596 CurUqiList
->SameOrNot
= FALSE
;
600 if (!CurUqiList
->SameOrNot
) {
602 CurUqiList
->Header
.DiffValue
+ 1,
604 CurQuestion
->StorageWidth
606 for (Index
= 0; Index
< CurQuestion
->MaxContainers
; Index
++) {
607 switch (CurQuestion
->StorageWidth
/CurQuestion
->MaxContainers
) {
610 *((UINT8
*)ValueAddrOfVar
+ Index
) = *(UINT8
*)((UINT64
*)CurUqiList
->Header
.Value
+ 1 + Index
);
613 case sizeof (UINT16
):
614 *((UINT16
*)ValueAddrOfVar
+ Index
) = *(UINT16
*)((UINT64
*)CurUqiList
->Header
.Value
+ 1 + Index
);
617 case sizeof (UINT32
):
618 *((UINT32
*)ValueAddrOfVar
+ Index
) = *(UINT32
*)((UINT64
*)CurUqiList
->Header
.Value
+ 1 + Index
);
621 case sizeof (UINT64
):
622 *((UINT64
*)ValueAddrOfVar
+ Index
) = *((UINT64
*)CurUqiList
->Header
.Value
+ 1 + Index
);
626 *((UINT8
*)ValueAddrOfVar
+ Index
) = *(UINT8
*)((UINT64
*)CurUqiList
->Header
.Value
+ 1 + Index
);
631 // Update the vaule of ORDERED_LIST according to its size
633 CurUqiList
->Header
.Value
= (UINT8
*)((UINT64
*)CurUqiList
->Header
.Value
);
635 CurUqiList
->Header
.Value
+ 1,
637 CurQuestion
->StorageWidth
647 Parse and set the quick configure information by the command line.
649 Read the UQI Config information from command line directly, and then compare it with the value in VarList.
650 Update the Update flag in Varlist.
652 @param UqiList The pointer to the uqi list
653 @param DefaultId The default Id.
654 @param PlatformId The platform Id.
656 @retval EFI_SUCCESS It was complete successfully
657 @retval EFI_UNSUPPORTED Update a read-only value
658 @return EFI_ABORTED An error occurred
663 IN UQI_PARAM_LIST
*UqiList
,
668 FORM_BROWSER_FORMSET
*FormSet
;
669 LIST_ENTRY
*FormSetLink
;
670 FORM_BROWSER_FORM
*Form
;
671 LIST_ENTRY
*FormLink
;
672 FORM_BROWSER_STATEMENT
*Question
;
673 LIST_ENTRY
*QuestionLink
;
674 LIST_ENTRY
*FormSetEntryListHead
;
675 UQI_PARAM_LIST
*CurUqiList
;
683 FormSetEntryListHead
= &mFormSetListEntry
;
685 FormSetLink
= GetFirstNode (FormSetEntryListHead
);
686 while (!IsNull (FormSetEntryListHead
, FormSetLink
)) {
687 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink
);
689 // Parse all forms in formset
691 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
693 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
694 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
696 // Parse five kinds of Questions in Form
698 QuestionLink
= GetFirstNode (&Form
->StatementListHead
);
700 while (!IsNull (&Form
->StatementListHead
, QuestionLink
)) {
701 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
702 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
704 // Parse five kinds of Questions in Form
706 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
707 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
708 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
709 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
710 || (Question
->Operand
== EFI_IFR_STRING_OP
)
712 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
714 // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode
716 if (Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
) {
719 if ((Question
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
720 && Question
->NewEfiVarstore
721 && ((Question
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)) {
726 CurUqiList
= UqiList
;
727 while (CurUqiList
!= NULL
) {
728 if ((PlatformId
== CurUqiList
->Header
.PlatformId
[0])
729 && (DefaultId
== CurUqiList
->Header
.DefaultId
[0])
730 && CompareUqiHeader (&(Question
->Uqi
), &(CurUqiList
->Header
))
733 // Add further check to avoid a case that there are many options with a
734 // same UQI (en-Us), but always returns the first one.
736 if (!CurUqiList
->ParseOrNot
) {
737 CurUqiList
->ParseOrNot
= TRUE
;
741 CurUqiList
= CurUqiList
->Next
;
743 if (CurUqiList
!= NULL
) {
744 SetUqiParametersWithQuestion (CurUqiList
, DefaultId
, PlatformId
, Question
);
748 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
750 FormSetLink
= GetNextNode (FormSetEntryListHead
, FormSetLink
);
757 Set question value per UqiList.
759 @param UqiList The pointer to the uqi list
760 @param DefaultId The default Id.
761 @param PlatformId The platform Id.
764 SetUqiParametersMultiMode (
765 IN UQI_PARAM_LIST
*UqiList
,
770 UQI_PARAM_LIST
*CurUqiList
;
772 CurUqiList
= UqiList
;
773 while (CurUqiList
!= NULL
) {
774 if ((CurUqiList
->ParseOrNot
== FALSE
)
775 && (PlatformId
== CurUqiList
->Header
.PlatformId
[0])
776 && (DefaultId
== CurUqiList
->Header
.DefaultId
[0])
778 CurUqiList
->ParseOrNot
= TRUE
;
779 if (CurUqiList
->Header
.Question
!= NULL
) {
780 SetUqiParametersWithQuestion (CurUqiList
, DefaultId
, PlatformId
, CurUqiList
->Header
.Question
);
783 CurUqiList
= CurUqiList
->Next
;
788 Find the matched question for each UQI string in UqiList
793 IN UQI_PARAM_LIST
*UqiList
796 FORM_BROWSER_FORMSET
*FormSet
;
797 LIST_ENTRY
*FormSetLink
;
798 FORM_BROWSER_FORM
*Form
;
799 LIST_ENTRY
*FormLink
;
800 FORM_BROWSER_STATEMENT
*Question
;
801 LIST_ENTRY
*QuestionLink
;
802 LIST_ENTRY
*FormSetEntryListHead
;
803 UQI_PARAM_LIST
*CurUqiList
;
807 if (UqiList
== NULL
) {
816 FormSetEntryListHead
= &mFormSetListEntry
;
818 FormSetLink
= FormSetEntryListHead
->ForwardLink
;
819 while (FormSetEntryListHead
!= FormSetLink
) {
820 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink
);
822 // Parse all forms in formset
824 FormLink
= FormSet
->FormListHead
.ForwardLink
;
826 while (&FormSet
->FormListHead
!= FormLink
) {
827 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
829 // Parse five kinds of Questions in Form
831 QuestionLink
= Form
->StatementListHead
.ForwardLink
;
833 while (&Form
->StatementListHead
!= QuestionLink
) {
834 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
835 QuestionLink
= QuestionLink
->ForwardLink
;
837 // Parse five kinds of Questions in Form
839 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
840 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
841 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
842 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
843 || (Question
->Operand
== EFI_IFR_STRING_OP
)
846 // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode
848 if (Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
) {
850 } else if (Question
->NewEfiVarstore
851 && ((Question
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)) {
855 CurUqiList
= UqiList
;
856 PlatformId
= 0xFFFFFFFF;
858 while (CurUqiList
!= NULL
) {
859 if ((CurUqiList
->Header
.Question
== NULL
)
860 && CompareUqiHeader (&(Question
->Uqi
), &(CurUqiList
->Header
))
861 && ((PlatformId
!= CurUqiList
->Header
.PlatformId
[0]) || (DefaultId
!= CurUqiList
->Header
.DefaultId
[0]))
863 CurUqiList
->Header
.Question
= Question
;
864 PlatformId
= CurUqiList
->Header
.PlatformId
[0];
865 DefaultId
= CurUqiList
->Header
.DefaultId
[0];
867 CurUqiList
= CurUqiList
->Next
;
871 FormLink
= FormLink
->ForwardLink
;
873 FormSetLink
= FormSetLink
->ForwardLink
;
880 Create and insert the UQI Node to the UQI parameter list.
882 @retval Node address If successed, return the node address.
883 @retval NULL An error occurred.
888 CreateInsertUqiNode (
891 UQI_PARAM_LIST
*Node
;
893 Node
= (UQI_PARAM_LIST
*) malloc (sizeof (UQI_PARAM_LIST
));
897 memset (Node
, 0, sizeof (UQI_PARAM_LIST
));
899 if (mUqiList
== NULL
) {
902 mLastUqiList
->Next
= Node
;
909 Parse the first part of QUI string
911 @param **argv[] The dual array pointer to the parameters.
912 @param Number The pointer to the number of the first character of UQI.
913 @param Buffer The buffer to store the first part of UQI.
915 @retval EFI_SUCCESS Parse the QUI parameters successfully.
916 @retval EFI_INVALID_PARAMETER An error occurred.
921 ParseFirstpartOfUqi (
931 *Number
= (UINT32
)StrToDec ((*argv
)[0]);
933 if ((*Number
<= 0) || (*Number
> MAX_QUI_PARAM_LEN
)) {
934 printf ("Error. Invalid UQI.\n");
935 return EFI_INVALID_PARAMETER
;
938 *Buffer
= malloc ((*Number
+ 1) * sizeof (CHAR16
));
939 assert (*Buffer
!= NULL
);
940 memset (*Buffer
, 0, (*Number
+ 1) * sizeof (CHAR16
));
942 for (Index
= 0; Index
< *Number
; Index
++) {
943 if (StrToDec ((*argv
)[Index
]) > 0xff) {
944 printf ("Error. Invalid UQI.\n");
945 return EFI_INVALID_PARAMETER
;
947 *(*Buffer
+ Index
) = (UINT16
)StrToDec ((*argv
)[Index
+ 1]);
953 Parse the QUI input parameters from the command line
955 @param argc The pointer to the number of input parameters.
956 @param **argv[] The dual array pointer to the parameters.
958 @retval EFI_SUCCESS Parse the QUI parameters successfully.
959 @retval EFI_INVALID_PARAMETER An error occurred.
970 UQI_PARAM_LIST
*UqiNode
;
977 printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");
978 return EFI_INVALID_PARAMETER
;
981 UqiNode
= CreateInsertUqiNode ();
982 assert (UqiNode
!= NULL
);
984 UqiNode
->Header
.DefaultId
= (UINT16
*) calloc (1, sizeof (UINT16
));
985 UqiNode
->Header
.PlatformId
= (UINT64
*) calloc (1, sizeof (UINT64
));
987 Status
= ParseFirstpartOfUqi (argv
, &(UqiNode
->Header
.HexNum
), &(UqiNode
->Header
.Data
));
988 if (EFI_ERROR (Status
)) {
991 *argc
-= (UqiNode
->Header
.HexNum
+ 1);
992 *argv
+= UqiNode
->Header
.HexNum
+ 1;
994 // Parse the TYPE and value
996 if (strcmp ("ONE_OF", (*argv
)[0]) == 0) {
997 UqiNode
->Header
.Type
= ONE_OF
;
998 } else if (strcmp ("NUMERIC", (*argv
)[0]) == 0) {
999 UqiNode
->Header
.Type
= NUMERIC
;
1000 } else if (strcmp ("CHECKBOX", (*argv
)[0]) == 0) {
1001 UqiNode
->Header
.Type
= CHECKBOX
;
1002 } else if (strcmp ("STRING", (*argv
)[0]) == 0) {
1003 UqiNode
->Header
.Type
= STRING
;
1004 } else if (strcmp ("ORDERED_LIST", (*argv
)[0]) == 0) {
1005 UqiNode
->Header
.Type
= ORDERED_LIST
;
1007 printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");
1008 return EFI_INVALID_PARAMETER
;
1013 // Get the value according to the type of questions.
1015 switch (UqiNode
->Header
.Type
) {
1020 UqiNode
->Header
.Value
= malloc (sizeof (UINT64
));
1021 if (UqiNode
->Header
.Value
== NULL
) {
1022 printf ("Fali to allocate memory!\n");
1023 return EFI_OUT_OF_RESOURCES
;
1025 memset (UqiNode
->Header
.Value
, 0, sizeof (UINT64
));
1027 UqiNode
->Header
.DiffValue
= malloc (sizeof (UINT64
));
1028 if (UqiNode
->Header
.DiffValue
== NULL
) {
1029 printf ("Fali to allocate memory!\n");
1030 return EFI_OUT_OF_RESOURCES
;
1033 UqiNode
->Header
.DiffValue
,
1037 *(UINT64
*)(UqiNode
->Header
.Value
) = (UINT64
)StrToDec ((*argv
)[0]);
1041 UqiNode
->Header
.Value
= malloc (((UINTN
)StrToDec ((*argv
)[0]) + 1) * sizeof (UINT64
));
1042 if (UqiNode
->Header
.Value
== NULL
) {
1043 printf ("Fali to allocate memory!\n");
1044 return EFI_OUT_OF_RESOURCES
;
1047 UqiNode
->Header
.Value
,
1049 (UINTN
)StrToDec(((*argv
)[0]) + 1) * sizeof (UINT64
)
1052 UqiNode
->Header
.DiffValue
= malloc (((UINTN
)StrToDec ((*argv
)[0]) + 1) * sizeof (UINT64
));
1053 if (UqiNode
->Header
.DiffValue
== NULL
) {
1054 printf ("Fali to allocate memory!\n");
1055 return EFI_OUT_OF_RESOURCES
;
1058 UqiNode
->Header
.DiffValue
,
1060 (UINTN
)(StrToDec ((*argv
)[0]) + 1) * sizeof (UINT64
)
1063 *UqiNode
->Header
.Value
= (UINT8
)StrToDec ((*argv
)[0]);
1064 for (Index
= 1; Index
<= StrToDec ((*argv
)[0]); Index
++) {
1065 *((UINT64
*)UqiNode
->Header
.Value
+ Index
) = StrToDec ((*argv
)[Index
]);
1067 *argc
-= (UINTN
)StrToDec ((*argv
)[0]);
1068 *argv
+= (UINTN
)StrToDec ((*argv
)[0]);
1079 printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>'.\n");
1080 return EFI_INVALID_PARAMETER
;
1085 Parse the input Fd file, and get the file name according to the FILETYPE.
1087 @param FdName The Name of Fd file
1088 @param FILETYPE The type of Fd file
1090 @return EFI_SUCCESS Get the file name successfully
1091 @return EFI_ABORTED An error occurred.
1104 if ((Type
== INFD
) && ((FdName
== NULL
) || (Fptr
= fopen (FdName
, "r")) == NULL
)) {
1105 if (FdName
!= NULL
) {
1106 printf ("Error: The <infd> file doesn't exist '%s'\n", FdName
);
1110 if ((Type
== OUTFD
) && (FdName
== NULL
) ) {
1111 printf ("Error: The <Outfd> name is NULL.\n");
1114 if ((Type
== SETUPTXT
) && (FdName
== NULL
) ) {
1115 printf ("Error: The <script> name is NULL.\n");
1118 if (strlen (FdName
) > MAX_FILENAME_LEN
- 1) {
1119 printf ("Error: The <fd> name is too long.\n");
1126 // Get and copy the file name
1129 strncpy (mInputFdName
, FdName
, MAX_FILENAME_LEN
- 1);
1130 mInputFdName
[MAX_FILENAME_LEN
- 1] = 0;
1132 if (Type
== OUTFD
) {
1133 strncpy (mOutputFdName
, FdName
, MAX_FILENAME_LEN
- 1);
1134 mOutputFdName
[MAX_FILENAME_LEN
- 1] = 0;
1136 if (Type
== OUTTXT
) {
1137 strncpy (mOutTxtName
, FdName
, MAX_FILENAME_LEN
- 1);
1138 mOutTxtName
[MAX_FILENAME_LEN
- 1] = 0;
1140 if (Type
== SETUPTXT
) {
1141 strncpy (mSetupTxtName
, FdName
, MAX_FILENAME_LEN
- 1);
1142 mSetupTxtName
[MAX_FILENAME_LEN
- 1] = 0;
1150 Print the usage of this tools.
1161 // Print utility header
1163 printf ("\nIntel(R) Firmware Configuration Editor. (Intel(R) %s) Version %d.%d. %s.\n\n",
1165 UTILITY_MAJOR_VERSION
,
1166 UTILITY_MINOR_VERSION
,
1170 // Copyright declaration
1172 fprintf (stdout
, "Copyright (c) 2010-2018, Intel Corporation. All rights reserved.\n\n");
1176 fprintf (stdout
, "The tool enables you to retrieve and change HII configuration (Setup) data in \n");
1177 fprintf (stdout
, "Firmware Device files.\n");
1178 fprintf (stdout
, "\nUsage: \n");
1179 fprintf (stdout
, " FCE [read -i <infd> [<PlatformId UQI>] ['>' <script>]] \n");
1180 fprintf (stdout
, " FCE [update -i <infd> [<PlatformId UQI>|-s <script>] -o <outfd>\n");
1181 fprintf (stdout
, " [--remove|--ignore] [-g <FvNameGuid>]] [-a]\n");
1182 fprintf (stdout
, " FCE [verify -i <infd> -s <script>] \n");
1183 fprintf (stdout
, " FCE [updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>] \n");
1184 fprintf (stdout
, " FCE [[help] | [-?]] \n");
1185 fprintf (stdout
, "\n");
1187 fprintf (stdout
, "Options:\n");
1188 fprintf (stdout
, " read Extract the HII data from the <infd> file. \n");
1189 fprintf (stdout
, " update Update the HII data to the <outfd> file. \n");
1190 fprintf (stdout
, " verify Verify the current platform configuration. \n");
1191 fprintf (stdout
, " updateq Update the current platform configuration by command line.\n");
1192 fprintf (stdout
, " updateq only supports common mode.\n");
1193 fprintf (stdout
, " help Display the help information.\n");
1195 fprintf (stdout
, " <infd> The name of a existing Firmware Device binary file input. \n");
1196 fprintf (stdout
, " <PlatformId UQI> The UQI is required in multi-platform mode to represent a \n");
1197 fprintf (stdout
, " PlatformId question from the VFR files used during binary \n");
1198 fprintf (stdout
, " image creation. It must not be used for common mode. \n");
1199 fprintf (stdout
, " <outfd> The name of a Firmware Device binary file output. \n");
1200 fprintf (stdout
, " <script> The name of a configure scripts.\n");
1201 fprintf (stdout
, " <UQI> A hex number followed by an array of hex numbers. \n");
1202 fprintf (stdout
, " <Question Type> One of ORDERED_LIST, ONE_OF, NUMERIC, STRING or CHECKBOX. \n");
1203 fprintf (stdout
, " <Value> A single hex number, if the <Question Type> is ONE_OF,\n");
1204 fprintf (stdout
, " NUMERIC, or CHECKBOX. Or a single hex number containing \n");
1205 fprintf (stdout
, " the array size followed by an array of that length of hex\n");
1206 fprintf (stdout
, " numbers, if the <Question Type> is ORDERED_LIST. \n");
1207 fprintf (stdout
, " <FvNameGuid> GuidValue is one specific FvName guid value.\n");
1208 fprintf (stdout
, " Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.\n");
1209 fprintf (stdout
, " -i Import an existing FD file <infd>. \n");
1210 fprintf (stdout
, " -o Create the new FD with the changes made. \n");
1211 fprintf (stdout
, " -s Import config scripts. \n");
1212 fprintf (stdout
, " > Redirect the output to a scripts. \n");
1213 fprintf (stdout
, " -? Display the help information. \n");
1214 fprintf (stdout
, " --remove If one or more of the settings that are updated also \n");
1215 fprintf (stdout
, " exists in NV RAM, remove them only in multi-platform mode.\n");
1216 fprintf (stdout
, " --ignore If one or more of the settings that are updated also \n");
1217 fprintf (stdout
, " existsin NV RAM, ignore them only in multi-platform mode.\n");
1218 fprintf (stdout
, " -g Specify the FV image to store the multi-platform default \n");
1219 fprintf (stdout
, " setting. If it is missing, the multi-platform default \n");
1220 fprintf (stdout
, " will be inserted into BFV image.\n");
1221 fprintf (stdout
, " -a Specify this tool to choose the smaller size between two \n");
1222 fprintf (stdout
, " different storage formats in NV RAM. It's only vaild in \n");
1223 fprintf (stdout
, " multi-platform mode. \n");
1224 fprintf (stdout
, "\n");
1226 fprintf (stdout
, "Mode:\n");
1227 fprintf (stdout
, " Common Extract the HII data from IFR binary and update it to the \n");
1228 fprintf (stdout
, " EFI variable. \n");
1229 fprintf (stdout
, " Multi-platform The default value depends on the PlatformId and DefaultId \n");
1230 fprintf (stdout
, " described in the VFR files. This tool will create the \n");
1231 fprintf (stdout
, " binary file to store default settings at build time for \n");
1232 fprintf (stdout
, " different platforms and modes adding all default settings \n");
1233 fprintf (stdout
, " into BFV as one FFS.\n");
1235 fprintf (stdout
, "\n");
1239 Parse the command line parameters
1241 @param argc The pointer to number of input parameters.
1242 @param *argv[] The pointer to the parameters.
1244 @retval EFI_SUCCESS Parse the parameters successfully.
1245 @retval EFI_INVALID_PARAMETER An error occurred.
1260 UINT8 IndexParamRemove
;
1261 UINT8 IndexParamIgnore
;
1262 UINT8 IndexParamOptimize
;
1263 EFI_GUID FvNameGuid
;
1265 Status
= EFI_SUCCESS
;
1270 IndexParamRemove
= 0;
1271 IndexParamIgnore
= 0;
1272 IndexParamOptimize
= 0;
1273 mMultiPlatformParam
.SizeOptimizedParam
= FALSE
;
1275 // Check for only own one operations
1279 Status
= EFI_INVALID_PARAMETER
;
1284 && ((stricmp(argv
[0], "read") == 0) \
1285 || (stricmp(argv
[0], "update") == 0) \
1286 || (stricmp(argv
[0], "updateq") == 0) \
1287 || (stricmp(argv
[0], "verify") == 0) )
1289 printf ("Error: Some parameters have been lost. Please correct. \n");
1291 Status
= EFI_INVALID_PARAMETER
;
1296 if (stricmp(argv
[0], "read") == 0) {
1302 printf ("Error. The correct command is 'FCE read -i <infd>'. \n");
1304 Status
= EFI_INVALID_PARAMETER
;
1308 // Get input FD file name.
1310 if (stricmp (argv
[0], "-i") == 0) {
1311 Status
= ParseInFile (argv
[1], INFD
);
1312 if (EFI_ERROR (Status
)) {
1319 // Parse the QUI parameters
1322 Status
= ParseFirstpartOfUqi (&argv
, &(mMultiPlatformParam
.Uqi
.HexNum
), &(mMultiPlatformParam
.Uqi
.Data
));
1323 mMultiPlatformParam
.MultiPlatformOrNot
= TRUE
;
1324 if (EFI_ERROR (Status
)) {
1330 } else if (stricmp(argv
[0], "update") == 0) {
1332 // Update the config file to Fd
1334 Operations
= UPDATE
;
1339 printf ("Error. The correct command is 'FCE update -i <infd> [<PlatformId UQI>|-s <script>] -o <outfd>' \n");
1341 Status
= EFI_INVALID_PARAMETER
;
1346 } else if (stricmp(argv
[0], "verify") == 0) {
1348 // 3. Parse the command line "FCE verify -i <infd> -s <script>"
1350 Operations
= VERIFY
;
1355 printf ("Error. The correct command is 'FCE verify -i <infd> -s <script>'\n");
1357 Status
= EFI_INVALID_PARAMETER
;
1362 } else if (stricmp(argv
[0], "updateq") == 0) {
1364 // Parse the command line "FCE updateq -i <infd> -o<outfd> <UQI> <Question Type> <Value>"
1370 // Get input/output FD file name.
1373 while ((Index
> 0) && (argc
> 1)) {
1374 if (stricmp (argv
[0], "-i") == 0) {
1375 Status
= ParseInFile (argv
[1], INFD
);
1376 if (EFI_ERROR (Status
)) {
1386 if (stricmp (argv
[0], "-o") == 0) {
1387 Status
= ParseInFile (argv
[1], OUTFD
);
1388 if (EFI_ERROR (Status
)) {
1399 && (stricmp(argv
[0], "-o") != 0) \
1400 && (stricmp(argv
[0], "-i") != 0)
1402 printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>' \n");
1404 Status
= EFI_INVALID_PARAMETER
;
1410 printf ("Error. The correct command is 'FCE updateq -i <infd> -o <outfd> <UQI> <Question Type> <Value>' \n");
1412 Status
= EFI_INVALID_PARAMETER
;
1417 // Parse the QUI parameters
1419 Status
= ParseUqiParam ((UINT32
*)&argc
,&argv
);
1420 if (EFI_ERROR (Status
)) {
1423 Operations
= UPDATEQ
;
1427 if (stricmp (argv
[0], "-i") == 0) {
1428 Status
= ParseInFile (argv
[1], INFD
);
1429 if (EFI_ERROR (Status
)) {
1438 if (stricmp (argv
[0], "-o") == 0) {
1439 Status
= ParseInFile (argv
[1], OUTFD
);
1440 if (EFI_ERROR (Status
)) {
1449 if (stricmp (argv
[0], "-s") == 0) {
1450 Status
= ParseInFile (argv
[1], SETUPTXT
);
1451 if (EFI_ERROR (Status
)) {
1460 if (stricmp (argv
[0], "-g") == 0) {
1461 Status
= StringToGuid (argv
[1], &FvNameGuid
);
1462 if (EFI_ERROR (Status
)) {
1463 printf ("Error: Invalid parameters for -g option in command line. \n");
1467 mFvNameGuidString
= argv
[1];
1473 if (stricmp (argv
[0], "-a") == 0) {
1476 IndexParamOptimize
++;
1477 mMultiPlatformParam
.SizeOptimizedParam
= TRUE
;
1481 if (stricmp (argv
[0], "--remove") == 0) {
1485 Operations
= UPDATE_REMOVE
;
1489 if (stricmp (argv
[0], "--ignore") == 0) {
1493 Operations
= UPDATE_IGNORE
;
1497 if ((stricmp(argv
[0], "help") == 0) || (stricmp(argv
[0], "-?") == 0)) {
1500 Status
= EFI_INVALID_PARAMETER
;
1504 // Operations should not be none
1506 if ( Operations
== NONE
) {
1507 printf ("Error. Only support read/update/verify/updateq mode. \n");
1509 Status
= EFI_INVALID_PARAMETER
;
1513 if (Operations
== UPDATE
) {
1514 Status
= ParseFirstpartOfUqi (&argv
, &(mMultiPlatformParam
.Uqi
.HexNum
), &(mMultiPlatformParam
.Uqi
.Data
));
1515 if (!EFI_ERROR (Status
)) {
1516 mMultiPlatformParam
.MultiPlatformOrNot
= TRUE
;
1517 argc
= argc
- mMultiPlatformParam
.Uqi
.HexNum
- 1;
1518 argv
= argv
+ mMultiPlatformParam
.Uqi
.HexNum
+ 1;
1525 && (stricmp(argv
[0], "-?") != 0)
1526 && (stricmp(argv
[0], "help") != 0)
1527 && (stricmp(argv
[0], "verify") != 0)
1528 && (stricmp(argv
[0], "read") != 0)
1529 && (stricmp(argv
[0], "update") != 0)
1530 && (stricmp(argv
[0], "updateq") != 0)
1531 && (stricmp(argv
[0], "-o") != 0)
1532 && (stricmp(argv
[0], "-i") != 0)
1533 && (stricmp(argv
[0], "-s") != 0)
1534 && (stricmp(argv
[0], "-a") != 0)
1535 && (stricmp(argv
[0], "-g") != 0)
1536 && (stricmp(argv
[0], "--remove") != 0)
1537 && (stricmp(argv
[0], "--ignore") != 0)
1539 printf ("Error: Invalid parameters exist in command line. \n");
1541 Status
= EFI_INVALID_PARAMETER
;
1546 // Check the repeated parameters in command line, such as "-i -i"
1550 || (IndexParamO
> 1)
1551 || (IndexParamS
> 1)
1552 || (IndexParamOptimize
> 1)
1553 || (IndexParamRemove
> 1)
1554 || (IndexParamIgnore
> 1)
1556 printf ("Error: Redundant parameters exist in command line.\n");
1558 Status
= EFI_INVALID_PARAMETER
;
1562 // Check improper parameters in command line, such as "FCE read -i -s"
1565 ((Operations
== READ
) && ((IndexParamO
>= 1) || (IndexParamS
>= 1) || (IndexParamRemove
>= 1) || (IndexParamIgnore
>= 1))) \
1566 || ((Operations
== VERIFY
) && ((IndexParamO
>= 1) || (IndexParamRemove
>= 1) || (IndexParamIgnore
>= 1))) \
1567 || ((Operations
== UPDATEQ
) && ((IndexParamS
>= 1) || (IndexParamRemove
>= 1) || (IndexParamIgnore
>= 1))) \
1568 || ((Operations
== UPDATE
) && ((IndexParamRemove
>= 1) && (IndexParamIgnore
>= 1)))
1569 || ((Operations
!= UPDATE
&& Operations
!= UPDATE_REMOVE
&& Operations
!= UPDATE_IGNORE
) && ((IndexParamOptimize
>= 1) || (mFvNameGuidString
!= NULL
)))
1571 printf ("Error: Improper parameters exist in command line. \n");
1573 Status
= EFI_INVALID_PARAMETER
;
1581 Check whether exists the valid variables in NvStorage or not.
1583 @retval TRUE If existed, return TRUE.
1584 @retval FALSE Others
1589 IN LIST_ENTRY
*StorageListHead
1592 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
1594 VOID
*VariableStoreHeader
;
1595 BOOLEAN AuthencitatedMonotonicOrNot
;
1596 BOOLEAN AuthencitatedBasedTimeOrNot
;
1598 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
1599 VariableStoreHeader
= (VOID
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
1600 AuthencitatedMonotonicOrNot
= FALSE
;
1601 AuthencitatedBasedTimeOrNot
= FALSE
;
1604 // Judge the layout of NV by gEfiVariableGuid
1606 AuthencitatedMonotonicOrNot
= CheckMonotonicBasedVarStore (VariableStoreHeader
);
1607 AuthencitatedBasedTimeOrNot
= CheckTimeBasedVarStoreOrNot (VariableStoreHeader
);
1609 if (AuthencitatedMonotonicOrNot
) {
1611 // Check the Monotonic based authenticate variable
1613 Existed
= ExistMonotonicBasedEfiVarOrNot (StorageListHead
);
1614 } else if (AuthencitatedBasedTimeOrNot
){
1616 // Check the Time Sample authenticate variable
1618 Existed
= ExistTimeBasedEfiVarOrNot (StorageListHead
);
1621 // Check the normal variable
1623 Existed
= ExistNormalEfiVarOrNot (StorageListHead
);
1630 Exchange the data between Efi variable and the data of VarList
1632 If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
1633 update the data from varlist to efi variable.
1635 @param VarToList The flag to control the direction of exchange.
1636 @param StorageListHead Decide which variale list be updated
1638 @retval EFI_SUCCESS Get the address successfully.
1642 EfiVarAndListExchange (
1643 IN BOOLEAN VarToList
,
1644 IN LIST_ENTRY
*StorageListHead
1647 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
1649 VOID
*VariableStoreHeader
;
1650 BOOLEAN AuthencitatedMonotonicOrNot
;
1651 BOOLEAN AuthencitatedBasedTimeOrNot
;
1653 Status
= EFI_ABORTED
;
1654 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
1655 VariableStoreHeader
= (VOID
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
1656 AuthencitatedMonotonicOrNot
= FALSE
;
1657 AuthencitatedBasedTimeOrNot
= FALSE
;
1659 // Judge the layout of NV by gEfiVariableGuid
1661 AuthencitatedMonotonicOrNot
= CheckMonotonicBasedVarStore (VariableStoreHeader
);
1662 AuthencitatedBasedTimeOrNot
= CheckTimeBasedVarStoreOrNot (VariableStoreHeader
);
1664 if (AuthencitatedMonotonicOrNot
) {
1666 // Update the Monotonic based authenticate variable
1668 Status
= SynAuthEfiVariable (VarToList
, StorageListHead
);
1669 } else if (AuthencitatedBasedTimeOrNot
){
1671 // Update the Time Sample authenticate variable
1673 Status
= SynAuthEfiVariableBasedTime (VarToList
, StorageListHead
);
1676 // Update the normal variable
1678 Status
= SynEfiVariable (VarToList
, StorageListHead
);
1685 Check the layout of NvStorage and remove the variable from Efi variable
1687 Found the variable with the same name in StorageListHead and remove it.
1689 @param StorageListHead Decide which variale list be removed.
1691 @retval EFI_SUCCESS Remove the variables successfully.
1696 IN LIST_ENTRY
*StorageListHead
1699 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
1701 VOID
*VariableStoreHeader
;
1702 BOOLEAN AuthencitatedMonotonicOrNot
;
1703 BOOLEAN AuthencitatedBasedTimeOrNot
;
1705 Status
= EFI_ABORTED
;
1706 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
1707 VariableStoreHeader
= (VOID
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
1708 AuthencitatedMonotonicOrNot
= FALSE
;
1709 AuthencitatedBasedTimeOrNot
= FALSE
;
1711 // Judge the layout of NV by gEfiVariableGuid
1713 AuthencitatedMonotonicOrNot
= CheckMonotonicBasedVarStore (VariableStoreHeader
);
1714 AuthencitatedBasedTimeOrNot
= CheckTimeBasedVarStoreOrNot (VariableStoreHeader
);
1716 if (AuthencitatedMonotonicOrNot
) {
1718 // Update the Monotonic based authenticate variable
1720 Status
= RemoveAuthEfiVariable (StorageListHead
);
1721 } else if (AuthencitatedBasedTimeOrNot
){
1723 // Update the Time Sample authenticate variable
1725 Status
= RemoveAuthEfiVariableBasedTime (StorageListHead
);
1728 // Update the normal variable
1730 Status
= RemoveNormalEfiVariable (StorageListHead
);
1737 Parse the all formset in one VfrBin.
1739 Parse all questions, variables and expression in VfrBin, and store
1740 it in Formset and Form.
1742 @param BaseAddr The pointer to the array of VfrBin base address.
1743 @param UniBinBaseAddress The pointer to one Uni string base address.
1745 @retval EFI_SUCCESS The Search was complete successfully
1746 @return EFI_ABORTED An error occurred
1750 ParseFormSetInVfrBin (
1751 IN UINTN
**BaseAddr
,
1752 IN UINTN
*UniBinBaseAddress
,
1756 UINT32 PackageLength
;
1758 FORM_BROWSER_FORMSET
*FormSet
;
1759 UINT8
*IfrBinaryData
;
1760 EFI_IFR_OP_HEADER
*IfrOpHdr
;
1764 Status
= EFI_SUCCESS
;
1766 IfrBinaryData
= NULL
;
1770 // The first 4 Bytes of VfrBin is used to record the Array Length
1771 // The header of VfrBin is, ARRAY LENGTH:4 Bytes, PACKAGE HEADER:4 Bytes (2 Bytes for Len, and the other for Type)
1773 PackageLength
= *(UINT32
*)*(BaseAddr
+ Index
) - 4;
1774 IfrBinaryData
= (UINT8
*)*(BaseAddr
+ Index
) + 4;
1777 // Go through the form package to parse OpCode one by one.
1779 IfrOffset
= sizeof (EFI_HII_PACKAGE_HEADER
);
1781 while (IfrOffset
< PackageLength
) {
1783 // Search the Formset in VfrBin
1785 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) (IfrBinaryData
+ IfrOffset
);
1787 if (IfrOpHdr
->OpCode
== EFI_IFR_FORM_SET_OP
) {
1788 FormSet
= calloc (sizeof (FORM_BROWSER_FORMSET
), sizeof (CHAR8
));
1789 if (FormSet
== NULL
) {
1792 FormSet
->IfrBinaryData
= IfrBinaryData
+ IfrOffset
;
1793 FormSet
->UnicodeBinary
= (UINT8
*) UniBinBaseAddress
;
1795 //This length will be corrected in ParseOpCodes function.
1797 FormSet
->IfrBinaryLength
= PackageLength
- IfrOffset
;
1799 // Parse opcodes in the formset IFR binary.
1801 Status
= ParseOpCodes (FormSet
);
1802 if (EFI_ERROR (Status
)) {
1803 DestroyAllStorage (FormSet
->StorageListHead
);
1804 DestroyFormSet (FormSet
);
1807 IfrOffset
+= FormSet
->IfrBinaryLength
;
1808 FormSet
->EnUsStringList
.StringInfoList
= calloc (sizeof (STRING_INFO
), STRING_NUMBER
);
1809 FormSet
->EnUsStringList
.CachedIdNum
= 0;
1810 FormSet
->EnUsStringList
.MaxIdNum
= STRING_NUMBER
;
1811 FormSet
->UqiStringList
.StringInfoList
= calloc (sizeof (STRING_INFO
), STRING_NUMBER
);
1812 FormSet
->UqiStringList
.CachedIdNum
= 0;
1813 FormSet
->UqiStringList
.MaxIdNum
= STRING_NUMBER
;
1815 // Insert the FormSet to mFormSet
1817 InsertTailList (&mFormSetListEntry
, &FormSet
->Link
);
1819 IfrOffset
+= IfrOpHdr
->Length
;
1827 Store all defaultId to mMultiPlatformParam.
1829 The mMultiPlatformParam.DefaultId[0] is used to store standard default.
1831 @param DefaultId The current defaultID.
1833 @retval EFI_SUCCESS It was complete successfully
1834 @return EFI_ABORTED An error occurred
1843 if ((mMultiPlatformParam
.DefaultIdNum
== 0) && (DefaultId
!= 0)) {
1844 mMultiPlatformParam
.DefaultId
[0] = DefaultId
;
1845 mMultiPlatformParam
.DefaultIdNum
++;
1849 // Only store the different value to mMultiPlatformParam.DefaultId[1] - mMultiPlatformParam.DefaultId[n]
1851 for (Index
= 0; Index
< mMultiPlatformParam
.DefaultIdNum
; Index
++) {
1852 if (mMultiPlatformParam
.DefaultId
[Index
] == DefaultId
) {
1856 mMultiPlatformParam
.DefaultId
[Index
] = DefaultId
;
1857 mMultiPlatformParam
.DefaultIdNum
++;
1861 Read all defaultId and platformId from binary.
1863 @param Binary The pointer to the bianry
1864 @param Storage The pointer to the Storage
1867 ReadDefaultAndPlatformIdFromBfv (
1869 IN FORMSET_STORAGE
*Storage
1876 Length
= *(UINT16
*)Binary
- sizeof (UINT16
);
1880 Binary
= Binary
+ sizeof (UINT16
);
1882 for (Size
= 0; Size
< Length
; Size
+= sizeof (UINT16
) + mMultiPlatformParam
.PlatformIdWidth
, Index
++) {
1883 Storage
->DefaultId
[Index
] = *(UINT16
*)(Binary
+ Size
);
1884 memcpy (&Storage
->PlatformId
[Index
], (Binary
+ Size
+ sizeof (UINT16
)), mMultiPlatformParam
.PlatformIdWidth
);
1886 Storage
->DefaultPlatformIdNum
= Index
- 1;
1890 Store all defaultId and platformId to binary.
1892 @param Binary The pointer to the bianry
1893 @param Storage The pointer to the Storage
1895 @retval Length Return the length of the header
1898 WriteDefaultAndPlatformId (
1900 IN FORMSET_STORAGE
*Storage
1910 Buffer
= Buffer
+ sizeof (CHAR16
);
1912 for (Index
= 0; Index
<= Storage
->DefaultPlatformIdNum
; Index
++) {
1913 *(UINT16
*)Buffer
= Storage
->DefaultId
[Index
];
1914 Buffer
= Buffer
+ sizeof (CHAR16
);
1915 memcpy (Buffer
, &Storage
->PlatformId
[Index
], mMultiPlatformParam
.PlatformIdWidth
);
1916 Buffer
= Buffer
+ mMultiPlatformParam
.PlatformIdWidth
;
1918 Length
= (UINT16
) (Buffer
- Binary
);
1920 // Record the offset to the first two bytes
1922 *(UINT16
*)Binary
= Length
;
1928 Store all defaultId and platformId to binary.
1930 @param Binary The pointer to the bianry
1931 @param Storage The pointer to the Storage
1933 @retval Length Return the length of the header
1936 WriteNvStoreDefaultAndPlatformId (
1938 IN FORMSET_STORAGE
*Storage
1946 Buffer
= Binary
+ 8;
1948 for (Index
= 0; Index
<= Storage
->DefaultPlatformIdNum
; Index
++) {
1949 *(UINT64
*)Buffer
= Storage
->PlatformId
[Index
];
1950 Buffer
= Buffer
+ sizeof(UINT64
);
1951 *(UINT16
*)Buffer
= Storage
->DefaultId
[Index
];
1952 Buffer
= Buffer
+ sizeof(UINT16
);
1954 Buffer
= Buffer
+ 6;
1956 Length
= (UINT16
) (Buffer
- Binary
- 8);
1963 Read the platformId from questions.
1965 @retval EFI_SUCCESS It was complete successfully.
1966 @return EFI_ABORTED An error occurred.
1970 IN FORM_BROWSER_STATEMENT
*CurQuestion
1976 QUESTION_OPTION
*Option
;
1983 // Check whether it is the question of paltform Id
1985 if (!CompareUqiHeader (&(CurQuestion
->Uqi
), &(mMultiPlatformParam
.Uqi
))) {
1989 // Copy the Question with platform to mMultiPlatformParam
1991 memcpy (&mMultiPlatformParam
.PlatformIdQuestion
, CurQuestion
, sizeof (FORM_BROWSER_STATEMENT
));
1992 mMultiPlatformParam
.Question
= CurQuestion
;
1994 // Pick up the value of NUMERIC and ONE_OF from current question and fill it in mMultiPlatformParam
1996 mMultiPlatformParam
.PlatformIdWidth
= CurQuestion
->StorageWidth
;
1998 if (CurQuestion
->Operand
== EFI_IFR_NUMERIC_OP
) {
2000 if (CurQuestion
->Step
== 0) {
2003 Step
= CurQuestion
->Step
;
2005 for (IdValue
= CurQuestion
->Minimum
; IdValue
< CurQuestion
->Maximum
; IdValue
+= Step
) {
2006 mMultiPlatformParam
.PlatformId
[Index
++] = (UINT64
)IdValue
;
2010 if (CurQuestion
->Operand
== EFI_IFR_ONE_OF_OP
) {
2013 Link
= GetFirstNode (&CurQuestion
->OptionListHead
);
2014 while (!IsNull (&CurQuestion
->OptionListHead
, Link
)) {
2015 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2016 mMultiPlatformParam
.PlatformId
[Index
++] = Option
->Value
.Value
.u64
;
2017 Link
= GetNextNode (&CurQuestion
->OptionListHead
, Link
);
2021 if (Index
>= MAX_PLATFORM_DEFAULT_ID_NUM
) {
2024 mMultiPlatformParam
.PlatformIdNum
= Index
;
2030 Clear the buffer of Storage list.
2032 @param StorageListHead The pointer to the entry of the storage list
2033 @param DefaultId The default Id for multi-platform support
2034 @param PlatformId The platform Id for multi-platform support
2039 ClearStorageEntryList (
2040 IN LIST_ENTRY
*StorageListHead
,
2041 IN UINT16 DefaultId
,
2042 IN UINT64 PlatformId
2046 LIST_ENTRY
*StorageLink
;
2047 FORMSET_STORAGE
*Storage
;
2051 StorageLink
= GetFirstNode (StorageListHead
);
2053 while (!IsNull (StorageListHead
, StorageLink
)) {
2054 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2055 if (Storage
!= NULL
) {
2056 memset (Storage
->Buffer
, 0x0, Storage
->Size
);
2057 Storage
->DefaultId
[0] = DefaultId
;
2058 Storage
->PlatformId
[0] = PlatformId
;
2059 Storage
->DefaultPlatformIdNum
= 0;
2061 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
2066 Append the platformid and default to the variables of CurDefaultId and CurPlatformId
2068 @param StorageListHead The pointer to the storage list
2069 @param CurDefaultId The default Id for multi-platform mode
2070 @param CurPlatformId The platform Id for multi-platform mode
2071 @param DefaultId The default Id for multi-platform mode
2072 @param PlatformId The platform Id for multi-platform mode
2077 AppendIdToVariables (
2078 IN LIST_ENTRY
*StorageListHead
,
2079 IN UINT16 CurDefaultId
,
2080 IN UINT64 CurPlatformId
,
2081 IN UINT16 DefaultId
,
2082 IN UINT64 PlatformId
2085 LIST_ENTRY
*StorageLink
;
2086 FORMSET_STORAGE
*Storage
;
2090 StorageLink
= GetFirstNode (StorageListHead
);
2092 while (!IsNull (StorageListHead
, StorageLink
)) {
2093 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2095 if ((Storage
->DefaultId
[0] == CurDefaultId
)
2096 && (Storage
->PlatformId
[0] == CurPlatformId
)
2098 ++Storage
->DefaultPlatformIdNum
;
2099 Storage
->DefaultId
[Storage
->DefaultPlatformIdNum
] = DefaultId
;
2100 Storage
->PlatformId
[Storage
->DefaultPlatformIdNum
] = PlatformId
;
2103 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
2109 Check whether StorageListHead2 is included in StorageListHead1
2111 @param StorageListHead1 The pointer to the entry of storage list
2112 @param StorageListHead2 The pointer to the entry of storage list
2113 @param DefaultId The default Id for multi-platform mode
2114 @param PlatformId The platform Id for multi-platform mode
2116 @retval TRUE Totally included.
2117 @return FALSE Other cases.
2120 ComparePartSameVariableList (
2121 IN LIST_ENTRY
*StorageListHead1
,
2122 IN LIST_ENTRY
*StorageListHead2
,
2123 OUT UINT16
*DefaultId
,
2124 OUT UINT64
*PlatformId
2127 LIST_ENTRY
*StorageLink
;
2128 LIST_ENTRY
*TempStorageHead
;
2129 LIST_ENTRY
*TempStorageLink
;
2130 LIST_ENTRY
*TempStorageHead2
;
2131 LIST_ENTRY
*TempStorageLink2
;
2132 FORMSET_STORAGE
*Storage
;
2133 FORMSET_STORAGE
*TempStorage
;
2134 FORMSET_STORAGE
*TempStorage2
;
2135 UINT16 CurDefaultId
;
2136 UINT64 CurPlatformId
;
2141 TempStorageHead
= NULL
;
2142 TempStorageLink
= NULL
;
2143 TempStorageHead2
= NULL
;
2144 TempStorageLink2
= NULL
;
2147 TempStorage2
= NULL
;
2152 TempStorageHead
= StorageListHead1
;
2156 // Get the number of variables in StorageListHead2;
2158 StorageLink
= GetFirstNode (StorageListHead2
);
2160 while (!IsNull (StorageListHead2
, StorageLink
)) {
2161 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2163 // For multi-platform support, only need to calcuate the type of EFI_IFR_VARSTORE_EFI_OP.
2165 if (mMultiPlatformParam
.MultiPlatformOrNot
&&
2166 (Storage
->Type
== EFI_IFR_VARSTORE_EFI_OP
) && (Storage
->Name
!= NULL
) && (Storage
->NewEfiVarstore
) &&
2167 ((Storage
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == EFI_VARIABLE_NON_VOLATILE
)) {
2170 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2173 // Parse every variables in StorageListHead1 and compare with ones in StorageListHead2
2174 // Only all variables in StorageListHead2 are included in StorageListHead1, return TRUE.
2176 StorageLink
= GetFirstNode (StorageListHead1
);
2178 while (!IsNull (StorageListHead1
, StorageLink
)) {
2179 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2181 // Get specified DefaultId and PlatformId firstly
2183 CurDefaultId
= Storage
->DefaultId
[0];
2184 CurPlatformId
= Storage
->PlatformId
[0];
2187 // Compare all variables under same defaultId and platformId
2189 TempStorageLink
= GetFirstNode (TempStorageHead
);
2190 while (!IsNull (TempStorageHead
, TempStorageLink
)) {
2191 TempStorage
= FORMSET_STORAGE_FROM_LINK (TempStorageLink
);
2192 if ((TempStorage
->DefaultId
[0] == CurDefaultId
)
2193 && (TempStorage
->PlatformId
[0] == CurPlatformId
)
2194 && (TempStorage
->Name
!= NULL
)
2195 && (TempStorage
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
2196 && (TempStorage
->NewEfiVarstore
)
2197 && ((TempStorage
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == EFI_VARIABLE_NON_VOLATILE
)
2200 //Search the matched variable by Guid and name in StorageListHead2
2202 TempStorageHead2
= StorageListHead2
;
2203 TempStorageLink2
= GetFirstNode (TempStorageHead2
);
2205 while (!IsNull (TempStorageHead2
, TempStorageLink2
)) {
2206 TempStorage2
= FORMSET_STORAGE_FROM_LINK (TempStorageLink2
);
2207 if ((TempStorage2
->Name
!= NULL
)
2208 && (TempStorage2
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
2209 && (TempStorage2
->NewEfiVarstore
)
2210 && ((TempStorage2
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == EFI_VARIABLE_NON_VOLATILE
)
2211 && !FceStrCmp (TempStorage
->Name
, TempStorage2
->Name
)
2212 && !CompareGuid(&TempStorage
->Guid
, &TempStorage2
->Guid
)
2214 if (CompareMem (TempStorage
->Buffer
, TempStorage2
->Buffer
, TempStorage
->Size
) == 0) {
2218 TempStorageLink2
= GetNextNode (TempStorageHead2
, TempStorageLink2
);
2221 TempStorageLink
= GetNextNode (TempStorageHead
, TempStorageLink
);
2224 // Check the matched variable number
2226 if (Index
== VariableNum
) {
2227 *DefaultId
= CurDefaultId
;
2228 *PlatformId
= CurPlatformId
;
2231 StorageLink
= GetNextNode (StorageListHead1
, StorageLink
);
2237 Check whether the defaultId and platformId mathched the variable or not
2239 @param Storage The pointer to the storage
2240 @param DefaultId The default Id for multi-platform mode
2241 @param PlatformId The platform Id for multi-platform mode
2243 @retval TRUE Not Matched.
2244 @return FALSE Matched any one
2247 NotEqualAnyIdOfStorage (
2248 IN FORMSET_STORAGE
*Storage
,
2249 IN UINT16 DefaultId
,
2250 IN UINT64 PlatformId
2255 for (Index
= 0; Index
<= Storage
->DefaultPlatformIdNum
; Index
++) {
2256 if ((Storage
->DefaultId
[Index
] == DefaultId
)
2257 &&(Storage
->PlatformId
[Index
] == PlatformId
)
2266 Copy Stroage from StorageListHead2 to StorageListHead1
2268 @param NewStorageListHead The pointer to the entry of storage list
2269 @param OldStorageListHead The pointer to the entry of storage list
2270 @param DefaultId The default Id for multi-platform mode
2271 @param PlatformId The platform Id for multi-platform mode
2272 @param AssignIdOrNot If True, assign the platform Id and default Id to storage;
2273 Or else, only copy the variables under the specified platform
2274 Id and default to the other list.
2275 @param Mode The operation of mode
2277 @retval EFI_SUCCESS It was complete successfully
2278 @return EFI_ABORTED An error occurred
2282 IN LIST_ENTRY
*NewStorageListHead
,
2283 IN LIST_ENTRY
*OldStorageListHead
,
2284 IN UINT16 DefaultId
,
2285 IN UINT64 PlatformId
,
2286 IN BOOLEAN AssignIdOrNot
,
2287 IN OPERATION_TYPE Mode
2290 LIST_ENTRY
*StorageLink
;
2291 LIST_ENTRY
*NameValueLink
;
2292 FORMSET_STORAGE
*Storage
;
2293 FORMSET_STORAGE
*StorageCopy
;
2294 IN LIST_ENTRY
*StorageListHead1
;
2295 IN LIST_ENTRY
*StorageListHead2
;
2296 NAME_VALUE_NODE
*NameValueNode
;
2297 NAME_VALUE_NODE
*CopyNameValueNode
;
2300 NameValueNode
= NULL
;
2301 StorageListHead1
= NewStorageListHead
;
2302 StorageListHead2
= OldStorageListHead
;
2304 StorageLink
= GetFirstNode (StorageListHead2
);
2306 while (!IsNull (StorageListHead2
, StorageLink
)) {
2307 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2309 if ((Storage
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
2310 ||(Storage
->Type
== EFI_IFR_VARSTORE_OP
)
2313 // Only support EfiVarStore in Multi-Platform mode, and the attribute must be EFI_VARIABLE_NON_VOLATILE
2315 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
2316 if (Storage
->Type
== EFI_IFR_VARSTORE_OP
) {
2317 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2320 if ((Storage
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
2321 && Storage
->NewEfiVarstore
2322 && ((Storage
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)
2324 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2327 if (AssignIdOrNot
) {
2328 Storage
->DefaultId
[0] = DefaultId
;
2329 Storage
->PlatformId
[0] = PlatformId
;
2332 //only copy the variables under the specified platform Id and default to the other list.
2334 if ((Mode
== VERIFY
) && (NotEqualAnyIdOfStorage (Storage
, DefaultId
, PlatformId
))) {
2335 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2337 } else if ((Mode
!= VERIFY
) && (Storage
->DefaultId
[0] != DefaultId
|| Storage
->PlatformId
[0] != PlatformId
) ) {
2338 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2344 // Copy Storage Node
2346 if (Storage
->Name
== NULL
) {
2350 StorageCopy
= calloc (sizeof (FORMSET_STORAGE
), sizeof (CHAR8
));
2351 if (StorageCopy
== NULL
) {
2352 printf ("Memory allocation failed.\n");
2355 memcpy (StorageCopy
, Storage
, sizeof (FORMSET_STORAGE
));
2357 if (Mode
== VERIFY
) {
2358 StorageCopy
->DefaultId
[0] = DefaultId
;
2359 StorageCopy
->PlatformId
[0] = PlatformId
;
2362 //Set the flags for sorting out the variables
2364 StorageCopy
->Skip
= FALSE
;
2366 StorageCopy
->Name
= NULL
;
2367 StorageCopy
->Name
= calloc (FceStrLen (Storage
->Name
) + 1, sizeof (CHAR16
));
2368 if (StorageCopy
->Name
== NULL
) {
2369 printf ("Memory allocation failed.\n");
2373 StrCpy (StorageCopy
->Name
, Storage
->Name
);
2375 StorageCopy
->Buffer
= NULL
;
2376 StorageCopy
->Buffer
= calloc (Storage
->Size
, sizeof (CHAR8
));
2377 if (StorageCopy
->Buffer
== NULL
) {
2378 free (StorageCopy
->Name
);
2380 printf ("Memory allocation failed.\n");
2383 CopyMem (StorageCopy
->Buffer
, Storage
->Buffer
, Storage
->Size
);
2385 // Copy NameValue list of storage node
2387 InitializeListHead (&StorageCopy
->NameValueListHead
);
2389 NameValueLink
= GetFirstNode (&Storage
->NameValueListHead
);
2391 while (!IsNull (&Storage
->NameValueListHead
, NameValueLink
)) {
2393 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (NameValueLink
);
2394 CopyNameValueNode
= NULL
;
2395 CopyNameValueNode
= calloc (sizeof (NAME_VALUE_NODE
), sizeof (CHAR8
));
2396 if (CopyNameValueNode
== NULL
) {
2397 free (StorageCopy
->Name
);
2398 free (StorageCopy
->Buffer
);
2400 printf ("Memory allocation failed.\n");
2403 memcpy (CopyNameValueNode
, NameValueNode
, sizeof (NAME_VALUE_NODE
));
2405 CopyNameValueNode
->Name
= NULL
;
2406 CopyNameValueNode
->Value
= NULL
;
2407 CopyNameValueNode
->EditValue
= NULL
;
2409 CopyNameValueNode
->Name
= calloc (FceStrLen (NameValueNode
->Name
) + 1, sizeof (CHAR16
));
2410 CopyNameValueNode
->Value
= calloc (FceStrLen (NameValueNode
->Value
) + 1, sizeof (CHAR16
));
2411 CopyNameValueNode
->EditValue
= calloc (FceStrLen (NameValueNode
->EditValue
) + 1, sizeof (CHAR16
));
2412 if ((CopyNameValueNode
->Name
== NULL
)
2413 || (CopyNameValueNode
->Value
== NULL
)
2414 || (CopyNameValueNode
->EditValue
== NULL
)
2416 free (StorageCopy
->Name
);
2417 free (StorageCopy
->Buffer
);
2419 if (CopyNameValueNode
->Name
!= NULL
) {
2420 free (CopyNameValueNode
->Name
);
2422 if (CopyNameValueNode
->Value
!= NULL
) {
2423 free (CopyNameValueNode
->Value
);
2425 if (CopyNameValueNode
->EditValue
!= NULL
) {
2426 free (CopyNameValueNode
->EditValue
);
2428 free (CopyNameValueNode
);
2429 printf ("Memory allocation failed.\n");
2432 StrCpy (CopyNameValueNode
->Name
, NameValueNode
->Name
);
2433 StrCpy (CopyNameValueNode
->Value
, NameValueNode
->Value
);
2434 StrCpy (CopyNameValueNode
->EditValue
, NameValueNode
->EditValue
);
2436 // Insert it to StorageCopy->NameValueListHead
2438 InsertTailList(&StorageCopy
->NameValueListHead
,&CopyNameValueNode
->Link
);
2439 NameValueLink
= GetNextNode (&Storage
->NameValueListHead
, NameValueLink
);
2443 // Insert it to StorageListHead1
2445 InsertTailList(StorageListHead1
,&StorageCopy
->Link
);
2447 StorageLink
= GetNextNode (StorageListHead2
, StorageLink
);
2453 Check whether the current defaultId and platfrom is equal to the first one of one
2454 group of defaultId and platformId which have the same variable data.
2456 @param DefaultId The default Id
2457 @param PlatformId The platform Id
2459 @retval TRUE If not equal to the first defaultId and platformId, return TRUE
2460 @return EFI_ABORTED Others
2464 IN UINT16 DefaultId
,
2465 IN UINT64 PlatformId
2470 for (Index
= 0; Index
< mMultiPlatformParam
.KeyIdNum
; Index
++) {
2472 (DefaultId
== mMultiPlatformParam
.KeyDefaultId
[Index
])
2473 && (PlatformId
== mMultiPlatformParam
.KeyPlatformId
[Index
])
2482 Evaluate the value in all formset according to the defaultId and platformId.
2484 If not the multi-platform mode, the defaultId is 0. In this case, the
2485 platform Id will be the default value of that question.
2487 @param UpdateMode It will be TRUE in update Mode
2489 @retval EFI_SUCCESS It was complete successfully
2490 @return EFI_ABORTED An error occurred
2493 EvaluateTheValueInFormset (
2494 IN BOOLEAN UpdateMode
2500 UINT16 CurDefaultId
;
2501 UINT64 CurPlatformId
;
2502 UINT16 DefaultIndex
;
2503 UINT16 PlatformIndex
;
2505 UQI_PARAM_LIST
*CurUqiList
;
2507 Status
= EFI_SUCCESS
;
2509 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
2510 ScanUqiFullList (mUqiList
);
2513 // Multi-platform mode support
2515 for (DefaultIndex
= 0; DefaultIndex
< mMultiPlatformParam
.DefaultIdNum
; DefaultIndex
++) {
2516 for (PlatformIndex
= 0; PlatformIndex
< mMultiPlatformParam
.PlatformIdNum
; PlatformIndex
++) {
2517 DefaultId
= mMultiPlatformParam
.DefaultId
[DefaultIndex
];
2518 PlatformId
= mMultiPlatformParam
.PlatformId
[PlatformIndex
];
2520 //Only parse one time, if a group of defaultId and platformId which have the same variable
2521 // Take the first one as a key Id of a group
2523 if (UpdateMode
&& NoTheKeyIdOfGroup (DefaultId
, PlatformId
)) {
2527 // Initialize the Storage of mVarListEntry
2529 ClearStorageEntryList (&mVarListEntry
, DefaultId
, PlatformId
);
2531 Status
= ExtractDefault (
2538 if (EFI_ERROR (Status
)) {
2542 // Clear the platformId as 0 after calculation.
2544 Status
= AssignThePlatformId (0);
2545 if (EFI_ERROR (Status
)) {
2546 printf ("Failed to clear the platformid.\n");
2550 // Update the value from script file
2553 SetUqiParametersMultiMode (mUqiList
,DefaultId
, PlatformId
);
2556 // If not existed the same variables in mAllVarListEntry, insert the new ones.
2557 // Or else, only add the defaultId and platformId to the former one.
2559 if (ComparePartSameVariableList (&mAllVarListEntry
, &mVarListEntry
, &CurDefaultId
, &CurPlatformId
)) {
2560 AppendIdToVariables (&mAllVarListEntry
, CurDefaultId
, CurPlatformId
, DefaultId
, PlatformId
);
2563 // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well
2565 Status
= BuildVariableList (&mAllVarListEntry
, &mVarListEntry
, DefaultId
, PlatformId
, TRUE
, UPDATE
);
2566 if (EFI_ERROR (Status
)) {
2570 // In update mode, add the other defaultId and platform of a group to the variale list
2573 CurUqiList
= mUqiList
;
2575 while (CurUqiList
!= NULL
) {
2576 if ((DefaultId
== CurUqiList
->Header
.DefaultId
[0])
2577 && (PlatformId
== CurUqiList
->Header
.PlatformId
[0])
2581 CurUqiList
= CurUqiList
->Next
;
2584 if (CurUqiList
== NULL
) {
2588 for (Index
= 1; Index
< CurUqiList
->Header
.IdNum
; Index
++) {
2589 CurDefaultId
= CurUqiList
->Header
.DefaultId
[Index
];
2590 CurPlatformId
= CurUqiList
->Header
.PlatformId
[Index
];
2591 AppendIdToVariables (&mAllVarListEntry
, DefaultId
, PlatformId
, CurDefaultId
, CurPlatformId
);
2601 Status
= ExtractDefault (
2608 if (EFI_ERROR (Status
)) {
2612 // If existed the variable in NvStorage, copy them to mVarListEntry.
2613 // Synchronize the default value from the EFI variable zone to variable list
2615 Status
= EfiVarAndListExchange (TRUE
, &mVarListEntry
);
2616 if (Status
== EFI_INVALID_PARAMETER
) {
2617 Status
= EFI_ABORTED
;
2621 // Update the value from script file
2624 Status
= SetUqiParameters (mUqiList
,0, 0);
2625 if (EFI_ERROR (Status
)) {
2630 // Copy Stroage from mVarListEntry to mAllVarListEntry
2632 Status
= BuildVariableList (&mAllVarListEntry
, &mVarListEntry
, 0, 0, TRUE
, UPDATE
);
2633 if (EFI_ERROR (Status
)) {
2641 Check and compare the value between the script file and variable from BFV.
2643 It's used in the update operation of multi-plaform mode.
2645 @retval EFI_SUCCESS It was complete successfully
2646 @return EFI_ABORTED An error occurred
2650 CheckValueUpdateList (
2656 UINT16 DefaultIndex
;
2657 UINT16 PlatformIndex
;
2659 FORMSET_STORAGE
*Storage
;
2660 LIST_ENTRY
*StorageLink
;
2661 UINT16 PreDefaultId
;
2662 UINT64 PrePlatformId
;
2665 PreDefaultId
= 0xFFFF;
2666 PrePlatformId
= 0xFFFFFFFFFFFFFFFF;
2668 ScanUqiFullList (mUqiList
);
2669 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
2670 StorageLink
= GetFirstNode (&mBfvVarListEntry
);
2671 while (!IsNull (&mBfvVarListEntry
, StorageLink
)) {
2672 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
2673 if (PreDefaultId
== Storage
->DefaultId
[0] && PrePlatformId
== Storage
->PlatformId
[0]) {
2674 StorageLink
= GetNextNode (&mBfvVarListEntry
, StorageLink
);
2677 PreDefaultId
= Storage
->DefaultId
[0];
2678 PrePlatformId
= Storage
->PlatformId
[0];
2680 DefaultId
= PreDefaultId
;
2681 PlatformId
= PrePlatformId
;
2683 //Only parse one time, if a group of defaultId and platformId which have the same variable
2684 // Take the first one as a key Id of a group
2686 if (NoTheKeyIdOfGroup (DefaultId
, PlatformId
)) {
2690 // Copy Stroage from mBfvVarListEntry to mVarListEntry. The mVarListEntry was attached to
2691 // the FormSet->StorageListHead.
2693 DestroyAllStorage (&mVarListEntry
);
2694 Status
= BuildVariableList (&mVarListEntry
, &mBfvVarListEntry
, DefaultId
, PlatformId
, FALSE
, UPDATE
);
2695 if (EFI_ERROR (Status
)) {
2698 SetUqiParametersMultiMode (mUqiList
,DefaultId
, PlatformId
);
2700 // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well
2702 Status
= BuildVariableList (&mAllVarListEntry
, &mVarListEntry
, DefaultId
, PlatformId
, TRUE
, UPDATE
);
2703 if (EFI_ERROR (Status
)) {
2706 StorageLink
= GetNextNode (&mBfvVarListEntry
, StorageLink
);
2709 for (DefaultIndex
= 0; DefaultIndex
< mMultiPlatformParam
.DefaultIdNum
; DefaultIndex
++) {
2710 for (PlatformIndex
= 0; PlatformIndex
< mMultiPlatformParam
.PlatformIdNum
; PlatformIndex
++) {
2711 DefaultId
= mMultiPlatformParam
.DefaultId
[DefaultIndex
];
2712 PlatformId
= mMultiPlatformParam
.PlatformId
[PlatformIndex
];
2714 //Only parse one time, if a group of defaultId and platformId which have the same variable
2715 // Take the first one as a key Id of a group
2717 if (NoTheKeyIdOfGroup (DefaultId
, PlatformId
)) {
2721 // Copy Stroage from mBfvVarListEntry to mVarListEntry. The mVarListEntry was attached to
2722 // the FormSet->StorageListHead.
2724 DestroyAllStorage (&mVarListEntry
);
2725 Status
= BuildVariableList (&mVarListEntry
, &mBfvVarListEntry
, DefaultId
, PlatformId
, FALSE
, UPDATE
);
2726 if (EFI_ERROR (Status
)) {
2729 SetUqiParametersMultiMode (mUqiList
,DefaultId
, PlatformId
);
2731 // Copy Stroage from mVarListEntry to mAllVarListEntry and assign the defaultId and platformId as well
2733 Status
= BuildVariableList (&mAllVarListEntry
, &mVarListEntry
, DefaultId
, PlatformId
, TRUE
, UPDATE
);
2734 if (EFI_ERROR (Status
)) {
2743 Read defaultId and platformId from the whole FD, and store these two values to mMultiPlatformParam.
2745 If not multi-platform mode, only return EFI_ABORTED.
2747 @param Fv the Pointer to the FFS
2748 @param Length the length of FFS
2750 @retval EFI_SUCCESS It was complete successfully
2751 @return EFI_ABORTED An error occurred
2755 ReadAllIfrToFromset (
2760 UINT8 NumberofMachingVfrBin
;
2761 UINTN
*VfrBinBaseAddress
;
2762 UINTN
*UniBinBaseAddress
;
2765 EFI_SECTION_STRUCT
*EfiBufferHeader
;
2768 NumberofMachingVfrBin
= 0;
2769 VfrBinBaseAddress
= NULL
;
2770 UniBinBaseAddress
= NULL
;
2771 Status
= EFI_SUCCESS
;
2772 EfiBufferHeader
= NULL
;
2776 // Locate the efi base address
2778 EfiBufferHeader
= malloc (sizeof (EFI_SECTION_STRUCT
));
2779 if (EfiBufferHeader
== NULL
) {
2785 sizeof (EFI_SECTION_STRUCT
)
2788 Status
= ParseSection (
2794 if (Status
!= EFI_SUCCESS
) {
2795 Status
= EFI_ABORTED
;
2799 EfiAddr
= (VOID
*)EfiBufferHeader
->BufferBase
;
2801 //Search the Offset at the end of FFS, whatever it is compressed or not
2803 Status
= SearchVfrBinInFFS (Fv
, EfiAddr
, Length
, &VfrBinBaseAddress
, &NumberofMachingVfrBin
);
2804 if (Status
!= EFI_SUCCESS
) {
2805 Status
= EFI_ABORTED
;
2808 Status
= SearchUniBinInFFS (
2814 if (Status
!= EFI_SUCCESS
) {
2815 Status
= EFI_ABORTED
;
2819 // Read all Ifr information into Formset and Form structure
2821 for (Index
= 0; Index
< NumberofMachingVfrBin
; Index
++) {
2822 if ((EfiBufferHeader
->BufferBase
+ EfiBufferHeader
->Length
) < *(VfrBinBaseAddress
+ Index
)
2823 || (EfiBufferHeader
->BufferBase
+ EfiBufferHeader
->Length
) < *UniBinBaseAddress
2825 printf ("Failed to locate Ifr data from efi by the offset.\n");
2826 Status
= EFI_ABORTED
;
2829 Status
= ParseFormSetInVfrBin (
2830 (UINTN
**)VfrBinBaseAddress
,
2831 (UINTN
*)*UniBinBaseAddress
,
2834 if (EFI_ERROR (Status
)) {
2835 Status
= EFI_ABORTED
;
2842 // Free the memory which stores the offset
2844 if (VfrBinBaseAddress
!= NULL
) {
2845 free (VfrBinBaseAddress
);
2847 if (UniBinBaseAddress
!= NULL
) {
2848 free (UniBinBaseAddress
);
2851 // Free the memory for uncompressed space in section
2853 for (Index
= 0; Index
< EfiBufferHeader
->UnCompressIndex
; Index
++) {
2854 if ((VOID
*)EfiBufferHeader
->UncompressedBuffer
[Index
] != NULL
) {
2855 free ((VOID
*)EfiBufferHeader
->UncompressedBuffer
[Index
]);
2862 Get next questions of four kinds in FormSet list.
2864 If not one kinds of ONE_OF CHECK_BOX ORDER_LIST and NUMERIC, continue to parse next question.
2865 If parse to the end of questions, return NULL.
2867 @param FormSetEntryListHead the pointer to the LIST_ENTRY
2868 @param OrderOfQuestion the order of question
2870 @retval If succeed, return the pointer to the question
2873 FORM_BROWSER_STATEMENT
*
2875 IN LIST_ENTRY
*FormSetEntryListHead
,
2876 IN OUT UINT32
*OrderOfQuestion
2879 FORM_BROWSER_FORMSET
*FormSet
;
2880 LIST_ENTRY
*FormSetLink
;
2881 FORM_BROWSER_FORM
*Form
;
2882 LIST_ENTRY
*FormLink
;
2883 FORM_BROWSER_STATEMENT
*Question
;
2884 LIST_ENTRY
*QuestionLink
;
2892 QuestionLink
= NULL
;
2895 FormSetLink
= GetFirstNode (FormSetEntryListHead
);
2896 while (!IsNull (FormSetEntryListHead
, FormSetLink
)) {
2897 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink
);
2899 // Parse all forms in formset
2901 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
2903 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
2904 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
2906 // Parse five kinds of Questions in Form
2908 QuestionLink
= GetFirstNode (&Form
->StatementListHead
);
2910 while (!IsNull (&Form
->StatementListHead
, QuestionLink
)) {
2911 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
2913 // Parse five kinds of Questions in Form
2915 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
2916 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
2917 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
2918 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
2919 || (Question
->Operand
== EFI_IFR_STRING_OP
)
2921 if (*OrderOfQuestion
== Index
++) {
2922 (*OrderOfQuestion
)++;
2926 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
2929 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
2931 FormSetLink
= GetNextNode (FormSetEntryListHead
, FormSetLink
);
2937 Read defaultId and platformId from the whole FD, and store these two values to mMultiPlatformParam.
2939 If not multi-platform mode, only return EFI_ABORTED.
2941 @param Fv the Pointer to the FFS
2942 @param Length the length of FFS
2944 @retval EFI_SUCCESS It was complete successfully
2945 @return EFI_ABORTED An error occurred
2949 ReadDefaultAndPlatformId (
2950 IN LIST_ENTRY
*FormSetEntryListHead
2954 FORM_BROWSER_FORMSET
*FormSet
;
2955 LIST_ENTRY
*FormLink
;
2956 FORMSET_DEFAULTSTORE
*DefaultStore
;
2957 LIST_ENTRY
*DefaultStoreLink
;
2958 FORM_BROWSER_STATEMENT
*CurQuestion
;
2960 UINT32 QuestionOrder
;
2962 Status
= EFI_SUCCESS
;
2967 //Check whether it is the Multi-Platform solution or not
2969 if (!mMultiPlatformParam
.MultiPlatformOrNot
) {
2970 Status
= EFI_SUCCESS
;
2974 // Read defaultId from FormSet List
2976 FormLink
= GetFirstNode (FormSetEntryListHead
);
2977 while (!IsNull (FormSetEntryListHead
, FormLink
)) {
2978 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormLink
);
2980 // Parse Default Store in formset
2982 DefaultStoreLink
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
2984 while (!IsNull (&FormSet
->DefaultStoreListHead
, DefaultStoreLink
)) {
2985 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (DefaultStoreLink
);
2986 StoreAllDefaultId (DefaultStore
->DefaultId
);
2987 DefaultStoreLink
= GetNextNode (&FormSet
->DefaultStoreListHead
, DefaultStoreLink
);
2989 FormLink
= GetNextNode (FormSetEntryListHead
, FormLink
);
2993 //Read the platformId from FormSetList
2995 while ((CurQuestion
= GetNextQuestion (FormSetEntryListHead
, &QuestionOrder
)) != NULL
) {
2996 Status
= ReadPlaformId (CurQuestion
);
2997 if (!EFI_ERROR (Status
)) {
3002 if (MatchedNum
== 0) {
3003 printf ("There are no questions included in the platformid in the FD.");
3004 Status
= EFI_ABORTED
;
3005 } else if (MatchedNum
> 1) {
3006 printf ("There are %d questions included in the platformid in the FD.", MatchedNum
);
3007 Status
= EFI_ABORTED
;
3009 Status
= EFI_SUCCESS
;
3018 Read the first two bytes to check whether it is Ascii or UCS2.
3020 @param ScriptFile Pointer to the script file.
3022 @reture TRUE If ascii, return TRUE
3023 @reture FALSE Others, return FALSE.
3031 CHAR16 FirstTwoBytes
;
3033 fread(&FirstTwoBytes
, 1, 2, ScriptFile
);
3035 if (FirstTwoBytes
== BigUnicodeFileTag
) {
3037 } else if (FirstTwoBytes
== LittleUnicodeFileTag
) {
3045 Read Unicode characters and transfer it to ASCII.
3047 @param ScriptFile The pointer to the script file.
3048 @param Type The type of BigUCS2 or LittleUCS2
3050 @return The ASCII characters
3055 IN OUT
FILE *ScriptFile
,
3071 if (ScriptFile
== NULL
) {
3074 StrChar8
= calloc (MAX_STR_LEN_FOR_PICK_UQI
, sizeof (CHAR8
));
3077 for (Index
= 0; Index
< MAX_STR_LEN_FOR_PICK_UQI
; Index
++) {
3079 // The first parse should skip the 0x0020 (BigUCS2) or 0x2000 (LittleUCS2)
3083 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3084 } while ((TempChar16
== 0x0020) || (TempChar16
== 0x2000));
3087 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3090 // Read until break the "Space"
3092 if ((TempChar16
== 0x0020) || (TempChar16
== 0x2000)) {
3095 if (Type
== BIG_UCS2
) {
3096 TempChar8
= (CHAR8
)TempChar16
;
3098 TempChar8
= (CHAR8
)(TempChar16
>> 8);
3100 memcpy (StrChar8
+ Index
, &TempChar8
, 0x1);
3102 if (Index
== MAX_STR_LEN_FOR_PICK_UQI
) {
3106 *(StrChar8
+ Index
) = '\0';
3112 Read Unicode characters and transfer it to ASCII.
3114 @param AsciiStr The pointer to the Ascii string. It may inlcudes blank space.
3115 @param IdArray The pointer to the array of Id.
3117 @return The number of default or platform Id
3122 GetNumFromAsciiString (
3124 IN OUT UINT64
*IdArray
3130 CHAR8 CharArray
[16];
3131 BOOLEAN ExistedValue
;
3136 ExistedValue
= FALSE
;
3138 while (*(AsciiStr
+ Index1
) != '\n') {
3141 ExistedValue
= FALSE
;
3142 memset (CharArray
, 0, 16);
3143 for (; *(AsciiStr
+ Index1
) == ' '; Index1
++);
3144 for (; (*(AsciiStr
+ Index1
) != ' ') && (*(AsciiStr
+ Index1
) != '\n'); Index1
++) {
3145 assert (Index2
<= 15);
3146 *(CharArray
+ Index2
++) = *(AsciiStr
+ Index1
);
3147 ExistedValue
= TRUE
;
3149 if (ExistedValue
&& (*(AsciiStr
+ Index1
- 1) != '\n')) {
3150 sscanf(CharArray
, "%lld", (long long *)&IdArray
[NumofId
++]);
3157 Parse the script file to build the linked list of question structures.
3159 Pick up the UQI information and save it to the UqiList. The current scripts
3160 could be Ascii or UCS2 (Little or Big Mode).
3162 @param ScriptFile The pointer to the script file.
3165 @return EFI_INVALID_PARAMETER ScriptFile is NULL
3170 PickUpUqiFromScript (
3181 UQI_PARAM_LIST
*UqiNode
;
3182 UINTN MaxContainers
;
3184 FILE_TYPE AsciiOrUcs2
;
3186 CHAR8 DefaultIdStr
[30];
3187 CHAR8 PlatformIdStr
[30];
3188 CHAR8 PlatformUqi
[30];
3194 BOOLEAN ReadDefaultId
;
3195 BOOLEAN ReadPlatformId
;
3196 BOOLEAN ReadPlatformIdUqi
;
3197 UINT64 DefaultId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
3198 UINT64 PlatformId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
3199 UINT16 DefaultIdNum
;
3200 UINT16 PlatformIdNum
;
3201 UINT8 Array
[MAX_PLATFORM_DEFAULT_ID_NUM
* MAX_PLATFORM_DEFAULT_ID_NUM
];
3207 AsciiOrUcs2
= ASCII
;
3213 ReadDefaultId
= FALSE
;
3214 ReadPlatformId
= FALSE
;
3215 ReadPlatformIdUqi
= FALSE
;
3220 memset (DefaultId
, 0, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
3221 memset (PlatformId
, 0, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
3222 memcpy (DefaultIdStr
, "/ FCEKEY DEFAULT_ID:", strlen ("/ FCEKEY DEFAULT_ID:") + 1);
3223 memcpy (PlatformIdStr
,"/FCEKEY PLATFORM_ID:", strlen ("/FCEKEY PLATFORM_ID:") + 1);
3224 memcpy (PlatformUqi
, "/FCEKEY PLATFORM_UQI:", strlen ("/FCEKEY PLATFORM_UQI:") + 1);
3226 if (ScriptFile
== NULL
) {
3227 return EFI_INVALID_PARAMETER
;
3230 // Check the file type
3232 AsciiOrUcs2
= IsAsciiOrUcs2 (ScriptFile
);
3233 if (AsciiOrUcs2
== ASCII
) {
3234 fseek (ScriptFile
, 0, SEEK_SET
);
3237 while(!feof(ScriptFile
)) {
3247 memset(Type
, 0, 32);
3249 // Read first character of the line to find the line type
3251 if (AsciiOrUcs2
== ASCII
) {
3252 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3254 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3255 if (AsciiOrUcs2
== BIG_UCS2
) {
3256 TempChar
= (CHAR8
)TempChar16
;
3258 TempChar
= (CHAR8
)(TempChar16
>> 8);
3262 // Take "\n\r" one line
3264 if (TempChar
!= 0x0d) {
3271 // Process question line
3273 // Read size of UQI string
3275 if (AsciiOrUcs2
== ASCII
) {
3276 fscanf(ScriptFile
, " %x", (INT32
*)&UqiSize
);
3278 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3279 if (Char8Str
== NULL
) {
3282 sscanf(Char8Str
, " %x", (INT32
*)&UqiSize
);
3283 if (Char8Str
!= NULL
) {
3288 if (UqiSize
> MAX_INPUT_ALLOCATE_SIZE
) {
3293 if (AsciiOrUcs2
== ASCII
) {
3294 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3296 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3297 if (AsciiOrUcs2
== BIG_UCS2
) {
3298 TempChar
= (CHAR8
)TempChar16
;
3300 TempChar
= (CHAR8
)(TempChar16
>> 8);
3303 } while((TempChar
!= '\n') && !feof(ScriptFile
));
3307 // Malloc buffer for string size + null termination
3309 UqiBuffer
= (CHAR16
*)calloc(UqiSize
+ 1, sizeof(CHAR16
));
3311 if (UqiBuffer
== NULL
) {
3312 printf("Error. Unable to allocate 0x%04lx bytes for UQI string -- FAILURE\n", (unsigned long)((UqiSize
+ 1) * sizeof(CHAR16
)));
3318 for (Index
= 0; Index
< UqiSize
; Index
++) {
3319 if (AsciiOrUcs2
== ASCII
) {
3320 fscanf(ScriptFile
, " %hx", (short *)&(UqiBuffer
[Index
]));
3322 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3323 if (Char8Str
== NULL
) {
3327 sscanf(Char8Str
, " %hx", (short *)&(UqiBuffer
[Index
]));
3328 if (Char8Str
!= NULL
) {
3335 // Set null termination
3337 UqiBuffer
[Index
] = 0;
3339 // Read question type
3341 if (AsciiOrUcs2
== ASCII
) {
3342 fscanf(ScriptFile
, "%31s", Type
);
3344 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3345 if (Char8Str
== NULL
) {
3349 sscanf(Char8Str
, " %31s", Type
);
3350 if (Char8Str
!= NULL
) {
3355 if (stricmp(Type
, "ONE_OF") == 0) {
3356 UqiNode
= CreateInsertUqiNode ();
3357 if (UqiNode
== NULL
) {
3361 UqiNode
->Header
.Type
= ONE_OF
;
3362 UqiNode
->Header
.HexNum
= UqiSize
;
3363 UqiNode
->Header
.Data
= UqiBuffer
;
3364 UqiNode
->Header
.Value
= (UINT8
*)calloc(1, sizeof(UINT64
));
3365 UqiNode
->Header
.DiffValue
= (UINT8
*)calloc(1, sizeof(UINT64
));
3366 UqiNode
->Header
.IdNum
= PlatformIdNum
;
3367 UqiNode
->Header
.DefaultId
= (UINT16
*)calloc (PlatformIdNum
, sizeof (UINT16
));
3368 if (UqiNode
->Header
.DefaultId
== NULL
) {
3369 printf("Fail to allocate memory");
3370 return EFI_OUT_OF_RESOURCES
;
3372 UqiNode
->Header
.PlatformId
= (UINT64
*)calloc (PlatformIdNum
, sizeof (UINT64
));
3373 if (UqiNode
->Header
.PlatformId
== NULL
) {
3374 printf("Fail to allocate memory");
3375 return EFI_OUT_OF_RESOURCES
;
3377 for (Index5
= 0; Index5
< PlatformIdNum
; Index5
++) {
3378 UqiNode
->Header
.DefaultId
[Index5
] = (UINT16
)DefaultId
[Index5
];
3380 memcpy (UqiNode
->Header
.PlatformId
, PlatformId
, PlatformIdNum
* sizeof (UINT64
));
3382 if (AsciiOrUcs2
== ASCII
) {
3383 fscanf(ScriptFile
, " %llx", (long long *)UqiNode
->Header
.Value
);
3385 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3386 if (Char8Str
== NULL
) {
3389 sscanf(Char8Str
, " %llx", (long long *)UqiNode
->Header
.Value
);
3390 if (Char8Str
!= NULL
) {
3396 } else if (stricmp(Type
, "CHECKBOX") == 0) {
3397 UqiNode
= CreateInsertUqiNode ();
3398 if (UqiNode
== NULL
) {
3402 UqiNode
->Header
.Type
= CHECKBOX
;
3403 UqiNode
->Header
.HexNum
= UqiSize
;
3404 UqiNode
->Header
.Data
= UqiBuffer
;
3405 UqiNode
->Header
.Value
= (UINT8
*)calloc(1, sizeof(UINT64
));
3406 UqiNode
->Header
.DiffValue
= (UINT8
*)calloc(1, sizeof(UINT64
));
3407 UqiNode
->Header
.IdNum
= PlatformIdNum
;
3408 UqiNode
->Header
.DefaultId
= (UINT16
*)calloc (PlatformIdNum
, sizeof (UINT16
));
3409 if (UqiNode
->Header
.DefaultId
== NULL
) {
3410 printf ("Fali to allocate memory!\n");
3411 return EFI_OUT_OF_RESOURCES
;
3413 UqiNode
->Header
.PlatformId
= (UINT64
*)calloc (PlatformIdNum
, sizeof (UINT64
));
3414 if (UqiNode
->Header
.PlatformId
== NULL
) {
3415 printf ("Fali to allocate memory!\n");
3416 return EFI_OUT_OF_RESOURCES
;
3418 for (Index5
= 0; Index5
< PlatformIdNum
; Index5
++) {
3419 UqiNode
->Header
.DefaultId
[Index5
] = (UINT16
)DefaultId
[Index5
];
3421 memcpy (UqiNode
->Header
.PlatformId
, PlatformId
, PlatformIdNum
* sizeof (UINT64
));
3423 if (AsciiOrUcs2
== ASCII
) {
3424 fscanf(ScriptFile
, " %llx", (long long *)UqiNode
->Header
.Value
);
3426 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3427 if (Char8Str
== NULL
) {
3430 sscanf(Char8Str
, " %llx", (long long *)UqiNode
->Header
.Value
);
3431 if (Char8Str
!= NULL
) {
3437 } else if (stricmp(Type
, "STRING") == 0) {
3438 UqiNode
= CreateInsertUqiNode ();
3439 if (UqiNode
== NULL
) {
3444 UqiNode
->Header
.Type
= STRING
;
3445 UqiNode
->Header
.HexNum
= UqiSize
;
3446 UqiNode
->Header
.Data
= UqiBuffer
;
3447 UqiNode
->Header
.Value
= (UINT8
*)calloc(MAX_INPUT_ALLOCATE_SIZE
, sizeof(CHAR16
));
3448 UqiNode
->Header
.DiffValue
= (UINT8
*)calloc(MAX_INPUT_ALLOCATE_SIZE
, sizeof(CHAR16
));
3449 if (UqiNode
->Header
.Value
== NULL
) {
3450 printf ("Fali to allocate memory!\n");
3451 return EFI_OUT_OF_RESOURCES
;
3453 if (UqiNode
->Header
.DiffValue
== NULL
) {
3454 printf ("Fali to allocate memory!\n");
3455 return EFI_OUT_OF_RESOURCES
;
3457 UqiNode
->Header
.IdNum
= PlatformIdNum
;
3458 UqiNode
->Header
.DefaultId
= (UINT16
*)calloc (PlatformIdNum
, sizeof (UINT16
));
3459 if (UqiNode
->Header
.DefaultId
== NULL
) {
3460 printf ("Fali to allocate memory!\n");
3461 return EFI_OUT_OF_RESOURCES
;
3463 UqiNode
->Header
.PlatformId
= (UINT64
*)calloc (PlatformIdNum
, sizeof (UINT64
));
3464 if (UqiNode
->Header
.PlatformId
== NULL
) {
3465 printf ("Fali to allocate memory!\n");
3466 return EFI_OUT_OF_RESOURCES
;
3468 for (Index5
= 0; Index5
< PlatformIdNum
; Index5
++) {
3469 UqiNode
->Header
.DefaultId
[Index5
] = (UINT16
)DefaultId
[Index5
];
3471 memcpy (UqiNode
->Header
.PlatformId
, PlatformId
, PlatformIdNum
* sizeof (UINT64
));
3475 for (Index
= 0; Index
< MAX_INPUT_ALLOCATE_SIZE
; Index
++) {
3476 if (AsciiOrUcs2
== ASCII
) {
3477 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3479 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3480 if (AsciiOrUcs2
== BIG_UCS2
) {
3481 TempChar
= (CHAR8
)TempChar16
;
3483 TempChar
= (CHAR8
)(TempChar16
>> 8);
3486 if (TempChar
== '\"') {
3487 if (InQuote
== TRUE
) {
3495 if (Index
> IdStart
) {
3496 if (InQuote
== FALSE
) {
3499 *(UqiNode
->Header
.Value
+ Index
- IdStart
-1) = TempChar
;
3504 if (IdEnd
< IdStart
) {
3505 printf("The STRING is not end with \" character!\n");
3509 printf("The STRING is not start with \" character!\n");
3513 } else if (stricmp(Type
, "NUMERIC") == 0) {
3514 UqiNode
= CreateInsertUqiNode ();
3515 if (UqiNode
== NULL
) {
3519 UqiNode
->Header
.Type
= NUMERIC
;
3520 UqiNode
->Header
.HexNum
= UqiSize
;
3521 UqiNode
->Header
.Data
= UqiBuffer
;
3522 UqiNode
->Header
.Value
= (UINT8
*)calloc(1, sizeof(UINT64
));
3523 UqiNode
->Header
.DiffValue
= (UINT8
*)calloc(1, sizeof(UINT64
));
3524 UqiNode
->Header
.IdNum
= PlatformIdNum
;
3525 UqiNode
->Header
.DefaultId
= (UINT16
*)calloc (PlatformIdNum
, sizeof (UINT16
));
3526 if (UqiNode
->Header
.DefaultId
== NULL
) {
3527 printf ("Fali to allocate memory!\n");
3528 return EFI_OUT_OF_RESOURCES
;
3530 UqiNode
->Header
.PlatformId
= (UINT64
*)calloc (PlatformIdNum
, sizeof (UINT64
));
3531 if (UqiNode
->Header
.PlatformId
== NULL
) {
3532 printf ("Fali to allocate memory!\n");
3533 return EFI_OUT_OF_RESOURCES
;
3535 for (Index5
= 0; Index5
< PlatformIdNum
; Index5
++) {
3536 UqiNode
->Header
.DefaultId
[Index5
] = (UINT16
)DefaultId
[Index5
];
3538 memcpy (UqiNode
->Header
.PlatformId
, PlatformId
, PlatformIdNum
* sizeof (UINT64
));
3540 if (AsciiOrUcs2
== ASCII
) {
3541 fscanf(ScriptFile
, " %llx", (long long *)UqiNode
->Header
.Value
);
3543 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3544 if (Char8Str
== NULL
) {
3547 sscanf(Char8Str
, " %llx", (long long *)UqiNode
->Header
.Value
);
3548 if (Char8Str
!= NULL
) {
3554 } else if (stricmp(Type
, "ORDERED_LIST") == 0) {
3555 UqiNode
= CreateInsertUqiNode ();
3556 if (UqiNode
== NULL
) {
3560 UqiNode
->Header
.Type
= ORDERED_LIST
;
3561 UqiNode
->Header
.HexNum
= UqiSize
;
3562 UqiNode
->Header
.Data
= UqiBuffer
;
3563 UqiNode
->Header
.IdNum
= PlatformIdNum
;
3564 UqiNode
->Header
.DefaultId
= (UINT16
*)calloc (PlatformIdNum
, sizeof (UINT16
));
3565 if (UqiNode
->Header
.DefaultId
== NULL
) {
3566 printf ("Fali to allocate memory!\n");
3567 return EFI_OUT_OF_RESOURCES
;
3569 UqiNode
->Header
.PlatformId
= (UINT64
*)calloc (PlatformIdNum
, sizeof (UINT64
));
3570 if (UqiNode
->Header
.PlatformId
== NULL
) {
3571 printf ("Fali to allocate memory!\n");
3572 return EFI_OUT_OF_RESOURCES
;
3574 for (Index5
= 0; Index5
< PlatformIdNum
; Index5
++) {
3575 UqiNode
->Header
.DefaultId
[Index5
] = (UINT16
)DefaultId
[Index5
];
3577 memcpy (UqiNode
->Header
.PlatformId
, PlatformId
, PlatformIdNum
* sizeof (UINT64
));
3579 if (AsciiOrUcs2
== ASCII
) {
3580 fscanf(ScriptFile
, " %x", (INT32
*)&MaxContainers
);
3582 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3583 if (Char8Str
== NULL
) {
3586 sscanf(Char8Str
, " %x", (INT32
*)&MaxContainers
);
3587 if (Char8Str
!= NULL
) {
3592 if (MaxContainers
> MAX_INPUT_ALLOCATE_SIZE
) {
3595 UqiNode
->Header
.Value
= (UINT8
*)calloc(MaxContainers
+ 1, sizeof(UINT64
));
3596 if (UqiNode
->Header
.Value
== NULL
) {
3597 printf ("Fali to allocate memory!\n");
3598 return EFI_OUT_OF_RESOURCES
;
3600 UqiNode
->Header
.DiffValue
= (UINT8
*)calloc(MaxContainers
+ 1, sizeof(UINT64
));
3601 if (UqiNode
->Header
.DiffValue
== NULL
) {
3602 printf ("Fali to allocate memory!\n");
3603 return EFI_OUT_OF_RESOURCES
;
3605 *UqiNode
->Header
.Value
= (UINT8
) MaxContainers
;
3606 *UqiNode
->Header
.DiffValue
= (UINT8
) MaxContainers
;
3608 for (Index
= 1; Index
<= MaxContainers
; Index
++) {
3609 if (*(UqiNode
->Header
.Value
+ Index
) == '/') {
3610 printf ("Error. Failed to parse the value of ORDERED_LIST.\n");
3611 return EFI_INVALID_PARAMETER
;
3613 if (AsciiOrUcs2
== ASCII
) {
3614 fscanf(ScriptFile
, " %llx", ((long long *)UqiNode
->Header
.Value
+ Index
));
3616 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3617 if (Char8Str
== NULL
) {
3620 sscanf(Char8Str
, " %llx", ((long long *)UqiNode
->Header
.Value
+ Index
));
3621 if (Char8Str
!= NULL
) {
3632 // Free UQI buffer before skipping to next line
3636 printf ("Error. Invalid parameters exist in scripts line %d", ScriptsLine
);
3639 UqiNode
->Header
.ScriptsLine
= ScriptsLine
;
3641 // Skip to next line
3644 if (AsciiOrUcs2
== ASCII
) {
3645 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3647 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3648 if (AsciiOrUcs2
== BIG_UCS2
) {
3649 TempChar
= (CHAR8
)TempChar16
;
3651 TempChar
= (CHAR8
)(TempChar16
>> 8);
3654 } while((TempChar
!= '\n') && !feof(ScriptFile
));
3660 // Newline, skip to next character
3666 // Get the value of PlatformId and DefaultId from comments
3669 if (AsciiOrUcs2
== ASCII
) {
3670 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3672 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3673 if (AsciiOrUcs2
== BIG_UCS2
) {
3674 TempChar
= (CHAR8
)TempChar16
;
3676 TempChar
= (CHAR8
)(TempChar16
>> 8);
3682 if (!ReadDefaultId
) {
3683 if (TempChar
== DefaultIdStr
[Index1
]) {
3688 if (Index1
== strlen (DefaultIdStr
)) {
3691 memset (Array
, 0, MAX_PLATFORM_DEFAULT_ID_NUM
* MAX_PLATFORM_DEFAULT_ID_NUM
);
3692 ReadDefaultId
= TRUE
;
3693 mMultiPlatformParam
.MultiPlatformOrNot
= TRUE
;
3695 } else if (ReadDefaultId
) {
3696 if (TempChar
== '\n') {
3697 ReadDefaultId
= FALSE
;
3698 Array
[Index3
] = TempChar
;
3699 DefaultIdNum
= GetNumFromAsciiString ((CHAR8
*)Array
, DefaultId
);
3700 mMultiPlatformParam
.KeyDefaultId
[mMultiPlatformParam
.KeyIdNum
] = (UINT16
)DefaultId
[0];
3702 Array
[Index3
++] = TempChar
;
3708 if (!ReadPlatformId
) {
3709 if (TempChar
== PlatformIdStr
[Index2
]) {
3714 if (Index2
== strlen (PlatformIdStr
)) {
3717 memset (Array
, 0, MAX_PLATFORM_DEFAULT_ID_NUM
* MAX_PLATFORM_DEFAULT_ID_NUM
);
3718 ReadPlatformId
= TRUE
;
3720 } else if (ReadPlatformId
) {
3721 if (TempChar
== '\n') {
3722 ReadPlatformId
= FALSE
;
3723 Array
[Index3
] = TempChar
;
3724 PlatformIdNum
= GetNumFromAsciiString ((CHAR8
*)Array
, PlatformId
);
3726 // Take the first defaultid an platformid as the key of this group
3728 mMultiPlatformParam
.KeyPlatformId
[mMultiPlatformParam
.KeyIdNum
++] = PlatformId
[0];
3729 assert (DefaultIdNum
== PlatformIdNum
);
3731 Array
[Index3
++] = TempChar
;
3735 //"/ PlatformIdUqi:"
3737 if (!ReadPlatformIdUqi
) {
3738 if (TempChar
== PlatformUqi
[Index4
]) {
3743 if (Index4
== strlen (PlatformUqi
)) {
3746 memset (Array
, 0, MAX_PLATFORM_DEFAULT_ID_NUM
* MAX_PLATFORM_DEFAULT_ID_NUM
);
3747 ReadPlatformIdUqi
= TRUE
;
3749 } else if (ReadPlatformIdUqi
) {
3750 if (mMultiPlatformParam
.Uqi
.HexNum
> 0) {
3754 // Read size of UQI string
3756 if (AsciiOrUcs2
== ASCII
) {
3757 fscanf(ScriptFile
, " %x", (INT32
*)&mMultiPlatformParam
.Uqi
.HexNum
);
3759 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3760 if (Char8Str
== NULL
) {
3763 sscanf(Char8Str
, " %x", (INT32
*)&mMultiPlatformParam
.Uqi
.HexNum
);
3764 if (Char8Str
!= NULL
) {
3769 if (mMultiPlatformParam
.Uqi
.HexNum
> MAX_INPUT_ALLOCATE_SIZE
) {
3773 // Malloc buffer for string size + null termination
3775 if (mMultiPlatformParam
.Uqi
.Data
!= NULL
) {
3776 free (mMultiPlatformParam
.Uqi
.Data
);
3777 mMultiPlatformParam
.Uqi
.Data
= NULL
;
3779 mMultiPlatformParam
.Uqi
.Data
= (CHAR16
*)calloc(mMultiPlatformParam
.Uqi
.HexNum
+ 1, sizeof(CHAR16
));
3781 if (mMultiPlatformParam
.Uqi
.Data
== NULL
) {
3782 printf("Error. Unable to allocate 0x%04zx bytes for UQI string -- FAILURE\n", (mMultiPlatformParam
.Uqi
.HexNum
+ 1) * sizeof(CHAR16
));
3788 for (Index
= 0; Index
< mMultiPlatformParam
.Uqi
.HexNum
; Index
++) {
3789 if (AsciiOrUcs2
== ASCII
) {
3790 fscanf(ScriptFile
, " %hx", (short *)&(mMultiPlatformParam
.Uqi
.Data
[Index
]));
3792 Char8Str
= ReadUcs2ToStr (ScriptFile
, AsciiOrUcs2
);
3793 if (Char8Str
== NULL
) {
3796 sscanf(Char8Str
, " %hx", (short *)&(mMultiPlatformParam
.Uqi
.Data
[Index
]));
3797 if (Char8Str
!= NULL
) {
3804 // Set null termination
3806 mMultiPlatformParam
.Uqi
.Data
[Index
] = 0;
3807 ReadPlatformIdUqi
= FALSE
;
3810 } while((TempChar
!= '\n') && !feof(ScriptFile
));
3813 // To do: Get and set DefaultId and PlatformId here!
3817 // Comment or garbage, skip to next line
3820 if (AsciiOrUcs2
== ASCII
) {
3821 fread(&TempChar
, sizeof (CHAR8
), 1, ScriptFile
);
3823 fread(&TempChar16
, sizeof (CHAR16
), 1, ScriptFile
);
3824 if (AsciiOrUcs2
== BIG_UCS2
) {
3825 TempChar
= (CHAR8
)TempChar16
;
3827 TempChar
= (CHAR8
)(TempChar16
>> 8);
3830 } while((TempChar
!= '\n') && !feof(ScriptFile
));
3838 Get the offset of file name from the whole path.
3840 @param NameStr The whole file path.
3842 @retval Offset Return the offset of file name in path
3846 GetOffsetOfFileName (
3858 if (NameStr
== NULL
) {
3861 while (*Str
!= '\0') {
3862 if (*Str
== OS_SEP
) {
3868 if (*(NameStr
+ CurIndex
) == OS_SEP
) {
3869 return CurIndex
+ 1;
3875 Print the questions which is updated to the current platform successfully.
3877 Parse the Uqi List, and print it till break NULL.
3879 @param List Pointer to a List.
3881 @retval EFI_SUCCESS The Print was complete successfully
3882 @return EFI_ABORTED An error occurred
3886 PrintUpdateListInfo (
3887 IN UQI_PARAM_LIST
*UqiList
3893 UQI_PARAM_LIST
*CurList
;
3900 printf ("\n\n -- Update List -- ");
3902 while (CurList
!= NULL
) {
3903 if (!CurList
->ErrorOrNot
&& CurList
->ParseOrNot
&& !CurList
->SameOrNot
) {
3905 printf ("\n\n[Script line %d] Update No.%d:\n", CurList
->Header
.ScriptsLine
, ++Index1
);
3906 printf ("Q %04x ", CurList
->Header
.HexNum
);
3907 for (Index2
= 0; Index2
< CurList
->Header
.HexNum
; Index2
++) {
3908 printf ("%04x ", CurList
->Header
.Data
[Index2
]);
3910 if (CurList
->Header
.Type
== ORDERED_LIST
) {
3911 printf ("ORDERED_LIST ");
3912 } else if (CurList
->Header
.Type
== CHECKBOX
) {
3913 printf ("CHECKBOX ");
3914 } else if (CurList
->Header
.Type
== ONE_OF
) {
3916 } else if (CurList
->Header
.Type
== NUMERIC
) {
3917 printf ("NUMERIC ");
3918 } else if (CurList
->Header
.Type
== STRING
) {
3921 printf ("UNKNOWN ");
3924 //Print the value of scripts
3926 printf ("\n[ Update Value From: ");
3927 if (CurList
->Header
.Type
== ORDERED_LIST
) {
3928 for (Index2
= 0; Index2
<= *(CurList
->Header
.DiffValue
); Index2
++) {
3929 printf ("%02x ", *(CurList
->Header
.DiffValue
+ Index2
));
3931 } else if (CurList
->Header
.Type
== STRING
) {
3933 WriteUnicodeStr((CHAR16
*)CurList
->Header
.DiffValue
);
3936 printf ("%llx ", *(unsigned long long*)(UINT64
*)CurList
->Header
.DiffValue
);
3939 //Print the value of current platform
3942 if (CurList
->Header
.Type
== ORDERED_LIST
) {
3943 for (Index2
= 0; Index2
<= *(CurList
->Header
.Value
); Index2
++) {
3944 printf ("%02x ", *(CurList
->Header
.Value
+ Index2
));
3946 } else if (CurList
->Header
.Type
== STRING
) {
3948 WriteUnicodeStr((CHAR16
*)CurList
->Header
.Value
);
3951 printf ("%llx ", *(unsigned long long*)(UINT64
*)CurList
->Header
.Value
);
3955 CurList
= CurList
->Next
;
3958 printf ("\n\n\n[Results]: %d questions have been updated successfully in total. \n", Index
);
3960 printf ("\n\n\n[Results]: %d question has been updated successfully in total. \n", Index
);
3966 Print the error, when update questions.
3968 Parse the Uqi List, and print it till break NULL.
3970 @param List The Pointer to a List.
3976 IN UQI_PARAM_LIST
*UqiList
3982 UQI_PARAM_LIST
*CurList
;
3991 while (CurList
!= NULL
) {
3992 if (CurList
->ErrorOrNot
&& CurList
->ParseOrNot
) {
3995 printf ("\n\n[Script line %d] Error Information No.%d:\n", CurList
->Header
.ScriptsLine
, ++Index1
);
3996 printf ("Q %04x ", CurList
->Header
.HexNum
);
3997 for (Index2
= 0; Index2
< CurList
->Header
.HexNum
; Index2
++) {
3998 printf ("%04x ", CurList
->Header
.Data
[Index2
]);
4000 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4001 printf ("ORDERED_LIST ");
4002 } else if (CurList
->Header
.Type
== CHECKBOX
) {
4003 printf ("CHECKBOX ");
4004 } else if (CurList
->Header
.Type
== ONE_OF
) {
4006 } else if (CurList
->Header
.Type
== NUMERIC
) {
4007 printf ("NUMERIC ");
4008 } else if (CurList
->Header
.Type
== STRING
) {
4011 printf ("UNKNOWN ");
4014 //Print the Input value of scripts
4016 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4017 for (Index2
= 0; Index2
<= *CurList
->Header
.Value
; Index2
++) {
4018 printf ("%02x ", *(CurList
->Header
.Value
+ Index2
));
4020 } else if (CurList
->Header
.Type
== STRING
) {
4022 WriteUnicodeStr((CHAR16
*)CurList
->Header
.Value
);
4025 printf ("%llx ", *(unsigned long long*)(UINT64
*)CurList
->Header
.Value
);
4028 //Print the Error information
4030 if (CurList
->Error
!= NULL
) {
4031 printf ("\n%s ", CurList
->Error
);
4034 CurList
= CurList
->Next
;
4038 printf ("\n\n[Results]: Occurred %d errors during the update process. \n", Index
);
4040 printf ("\n\n[Results]: Occurred %d error during the update process. \n", Index
);
4047 Any questions that exist in both the script and the current platform and have
4048 different values will be logged to the screen.
4050 Parse the Uqi List, and print it till break NULL.
4052 @param List Pointer to a List.
4054 @retval EFI_SUCCESS The Print was complete successfully
4055 @return EFI_ABORTED An error occurreds
4059 PrintVerifiedListInfo (
4060 IN UQI_PARAM_LIST
*UqiList
4067 UQI_PARAM_LIST
*CurList
;
4078 StrLen1
= strlen (mSetupTxtName
+ GetOffsetOfFileName (mSetupTxtName
));
4079 StrLen2
= strlen (mInputFdName
+ GetOffsetOfFileName (mInputFdName
));
4081 StrLen
= (StrLen1
> StrLen2
) ? StrLen1
:StrLen2
;
4083 printf ("\n\n -- Different List -- ");
4085 while (CurList
!= NULL
) {
4086 if (!CurList
->SameOrNot
&& CurList
->ParseOrNot
) {
4088 printf ("\n\n[Script line %d] Difference No.%d:", CurList
->Header
.ScriptsLine
, ++Index1
);
4089 printf ("\n[%s", mSetupTxtName
+ GetOffsetOfFileName (mSetupTxtName
));
4090 for (Index3
= 0; Index3
< StrLen
- StrLen1
; Index3
++) {
4094 printf (" Q %04x ", CurList
->Header
.HexNum
);
4095 for (Index2
= 0; Index2
< CurList
->Header
.HexNum
; Index2
++) {
4096 printf ("%04x ", CurList
->Header
.Data
[Index2
]);
4098 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4099 printf ("ORDERED_LIST ");
4100 } else if (CurList
->Header
.Type
== CHECKBOX
) {
4101 printf ("CHECKBOX ");
4102 } else if (CurList
->Header
.Type
== ONE_OF
) {
4104 } else if (CurList
->Header
.Type
== NUMERIC
) {
4105 printf ("NUMERIC ");
4106 } else if (CurList
->Header
.Type
== STRING
) {
4109 printf ("UNKNOWN ");
4112 //Print the Input value of scripts
4114 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4115 for (Index2
= 0; Index2
<= *(CurList
->Header
.Value
); Index2
++) {
4116 printf ("%02x ", *(CurList
->Header
.Value
+ Index2
));
4118 } else if (CurList
->Header
.Type
== STRING
) {
4120 WriteUnicodeStr((CHAR16
*)CurList
->Header
.Value
);
4123 printf ("%llx ", *(unsigned long long*)(UINT64
*)CurList
->Header
.Value
);
4126 //Print the value of current platform
4128 printf ("\n[%s", mInputFdName
+ GetOffsetOfFileName (mInputFdName
));
4129 for (Index3
= 0; Index3
< StrLen
- StrLen2
; Index3
++) {
4133 printf (" Q %04x ", CurList
->Header
.HexNum
);
4134 for (Index2
= 0; Index2
< CurList
->Header
.HexNum
; Index2
++) {
4135 printf ("%04x ", CurList
->Header
.Data
[Index2
]);
4137 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4138 printf ("ORDERED_LIST ");
4139 } else if (CurList
->Header
.Type
== CHECKBOX
) {
4140 printf ("CHECKBOX ");
4141 } else if (CurList
->Header
.Type
== ONE_OF
) {
4143 } else if (CurList
->Header
.Type
== NUMERIC
) {
4144 printf ("NUMERIC ");
4145 } else if (CurList
->Header
.Type
== STRING
) {
4148 printf ("UNKNOWN ");
4150 if (CurList
->Header
.Type
== ORDERED_LIST
) {
4151 for (Index2
= 0; Index2
<= *(CurList
->Header
.DiffValue
); Index2
++) {
4152 printf ("%02x ", *(CurList
->Header
.DiffValue
+ Index2
));
4154 } else if (CurList
->Header
.Type
== STRING
) {
4156 WriteUnicodeStr((CHAR16
*)CurList
->Header
.DiffValue
);
4159 printf ("%llx ", *(unsigned long long*)(UINT64
*)CurList
->Header
.DiffValue
);
4162 CurList
= CurList
->Next
;
4166 "\n\n\n[Results]: There are %d differences between '%s' and '%s' in total.\n\n\n",
4168 mSetupTxtName
+ GetOffsetOfFileName (mSetupTxtName
),
4169 mInputFdName
+ GetOffsetOfFileName (mInputFdName
)
4173 "\n\n\n[Results]: There is %d difference between '%s' and '%s' in total.\n\n\n",
4175 mSetupTxtName
+ GetOffsetOfFileName (mSetupTxtName
),
4176 mInputFdName
+ GetOffsetOfFileName (mInputFdName
)
4182 Insert Uqi object to the end of unidirection List.
4184 @param InList The Pointer to the current object
4185 @param UqiListEntry The pointer to the entry of UqiList
4190 InsertUnidirectionList (
4191 IN UQI_PARAM_LIST
*InList
,
4192 IN UQI_PARAM_LIST
**UqiListEntry
4195 UQI_PARAM_LIST
**UqiCurList
;
4196 UQI_PARAM_LIST
*UqiNext
;
4201 if (UqiListEntry
== NULL
) {
4205 // Insert to Uqi Node to UqiList
4207 UqiCurList
= UqiListEntry
;
4208 UqiNext
= *UqiCurList
;
4209 if (UqiNext
== NULL
) {
4211 //Insert is the first node as node header
4213 *UqiCurList
= InList
;
4215 while ((UqiNext
!= NULL
) && (UqiNext
->Next
!= NULL
)) {
4216 UqiNext
= UqiNext
->Next
;
4218 UqiNext
->Next
= InList
;
4224 Free variable unidirection List.
4226 @param UqiListEntry The pointer to the entry of UqiList
4231 FreeUnidirectionList (
4232 IN UQI_PARAM_LIST
*UqiListEntry
4235 UQI_PARAM_LIST
*Next
;
4241 while (UqiListEntry
!= NULL
) {
4242 Next
= UqiListEntry
->Next
;
4243 if (UqiListEntry
->Header
.Value
!= NULL
) {
4244 free (UqiListEntry
->Header
.Value
);
4246 if (UqiListEntry
->Header
.DiffValue
!= NULL
) {
4247 free (UqiListEntry
->Header
.DiffValue
);
4249 if (UqiListEntry
->Header
.Data
!= NULL
) {
4250 free (UqiListEntry
->Header
.Data
);
4252 if (UqiListEntry
->Header
.DefaultId
!= NULL
) {
4253 free (UqiListEntry
->Header
.DefaultId
);
4255 if (UqiListEntry
->Header
.PlatformId
!= NULL
) {
4256 free (UqiListEntry
->Header
.PlatformId
);
4258 if (UqiListEntry
->Error
!= NULL
) {
4259 free (UqiListEntry
->Error
);
4261 free (UqiListEntry
);
4262 UqiListEntry
= Next
;
4269 Delete a directory and files in it.
4271 @param DirName Name of the directory need to be deleted.
4273 @return EFI_INVALID_PARAMETER
4282 CHAR8
* SystemCommand
;
4284 SystemCommand
= NULL
;
4286 if (DirName
== NULL
) {
4287 return EFI_INVALID_PARAMETER
;
4291 // Delete a directory and files in it.
4294 SystemCommand
= malloc (
4295 strlen (RMDIR_STR
) +
4299 if (SystemCommand
== NULL
) {
4300 return EFI_OUT_OF_RESOURCES
;
4309 system (SystemCommand
);
4310 free(SystemCommand
);
4316 Pick up the FFS from the FD image.
4318 Call BfmLib to get all FFS in one FD image, and save all which includes IFR
4319 Binary to gEfiFdInfo structure.
4321 @retval EFI_SUCCESS Get the address successfully.
4329 CHAR8
*SystemCommandFormatString
;
4330 CHAR8
*SystemCommand
;
4331 CHAR8
*TempSystemCommand
;
4336 Status
= EFI_SUCCESS
;
4337 SystemCommandFormatString
= NULL
;
4338 SystemCommand
= NULL
;
4339 TempSystemCommand
= NULL
;
4343 memset (&gEfiFdInfo
, 0, sizeof (G_EFI_FD_INFO
));
4345 // Construction 'system' command string
4347 SystemCommandFormatString
= "BfmLib -e \"%s\" ";
4349 SystemCommand
= malloc (
4350 strlen (SystemCommandFormatString
) + strlen (mInputFdName
) + 1
4353 if (SystemCommand
== NULL
) {
4354 printf ("Fail to allocate memory.\n");
4360 "BfmLib -e \"%s\" ",
4364 if (mFullGuidToolDefinitionDir
[0] != 0) {
4365 TempSystemCommand
= SystemCommand
;
4366 SystemCommand
= malloc (
4367 strlen (mFullGuidToolDefinitionDir
) + strlen (OS_SEP_STR
) + strlen (TempSystemCommand
) + 1
4370 if (SystemCommand
== NULL
) {
4371 free (TempSystemCommand
);
4372 return EFI_UNSUPPORTED
;
4374 strcpy (SystemCommand
, mFullGuidToolDefinitionDir
);
4375 strcat (SystemCommand
, OS_SEP_STR
);
4376 strcat (SystemCommand
, TempSystemCommand
);
4377 free (TempSystemCommand
);
4382 // Call BfmLib to get all FFS in Temp folder of current path
4384 ReturnValue
= system (SystemCommand
);
4385 free (SystemCommand
);
4386 if (ReturnValue
== -1) {
4387 printf ("Error. Call BfmLib failed.\n");
4391 //Pick up the FFS which is interrelated with the IFR binary.
4393 TemDir
= getcwd (NULL
, _MAX_PATH
);
4394 if (strlen (TemDir
) + strlen (OS_SEP_STR
) + strlen (TEMP_DIR_NAME
)> _MAX_PATH
- 1) {
4395 printf ("The directory is too long \n");
4398 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TemDir
) - 1);
4399 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TemDir
) - 1);
4400 mMultiPlatformParam
.ExistStorageFfsInBfv
= FALSE
;
4401 Status
= FindFileInFolder (TemDir
, &mMultiPlatformParam
.ExistStorageFfsInBfv
, &mMultiPlatformParam
.SizeOptimized
);
4406 #define BUILD_IN_TOOL_COUNT 4
4408 Generate pre-defined guided tools data.
4410 @return An EFI_HANDLE contain guided tools data.
4415 PreDefinedGuidedTools (
4421 GUID_SEC_TOOL_ENTRY
*FirstGuidTool
;
4422 GUID_SEC_TOOL_ENTRY
*LastGuidTool
;
4423 GUID_SEC_TOOL_ENTRY
*NewGuidTool
;
4427 CHAR8 PreDefinedGuidedTool
[BUILD_IN_TOOL_COUNT
][255] = {
4428 "a31280ad-481e-41b6-95e8-127f4c984779 TIANO TianoCompress",
4429 "ee4e5898-3914-4259-9d6e-dc7bd79403cf LZMA LzmaCompress",
4430 "fc1bcdb0-7d31-49aa-936a-a4600d9dd083 CRC32 GenCrc32",
4431 "3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress"
4435 FirstGuidTool
= NULL
;
4436 LastGuidTool
= NULL
;
4439 for (Index
= 0; Index
< BUILD_IN_TOOL_COUNT
; Index
++) {
4440 Tool
= SplitStringByWhitespace (PreDefinedGuidedTool
[Index
]);
4441 if ((Tool
!= NULL
) &&
4444 Status
= StringToGuid (Tool
->Strings
[0], &Guid
);
4445 if (!EFI_ERROR (Status
)) {
4446 NewGuidTool
= malloc (sizeof (GUID_SEC_TOOL_ENTRY
));
4447 if (NewGuidTool
!= NULL
) {
4448 memcpy (&(NewGuidTool
->Guid
), &Guid
, sizeof (Guid
));
4449 NewGuidTool
->Name
= CloneString(Tool
->Strings
[1]);
4450 NewGuidTool
->Path
= CloneString(Tool
->Strings
[2]);
4451 NewGuidTool
->Next
= NULL
;
4453 printf ( "Fail to allocate memory. \n");
4455 FreeStringList (Tool
);
4459 if (FirstGuidTool
== NULL
) {
4460 FirstGuidTool
= NewGuidTool
;
4462 LastGuidTool
->Next
= NewGuidTool
;
4464 LastGuidTool
= NewGuidTool
;
4468 fprintf (stdout
, "Error");
4471 FreeStringList (Tool
);
4475 return FirstGuidTool
;
4479 Read all storages under a specified platformId and defaultId from BFV.
4481 @param Binary The pointer to the buffer of binary.
4482 @param StorageListEntry The pointer to the storage list.
4484 @return length The length of storage
4487 ReadStorageFromBinary (
4489 IN LIST_ENTRY
*StorageListEntry
4494 BOOLEAN AuthencitatedMonotonicOrNot
;
4495 BOOLEAN AuthencitatedBasedTimeOrNot
;
4498 AuthencitatedMonotonicOrNot
= FALSE
;
4499 AuthencitatedBasedTimeOrNot
= FALSE
;
4500 DataBase
= Binary
+ sizeof (EFI_COMMON_SECTION_HEADER
);
4502 // Judge the layout of NV by Variable Guid
4504 AuthencitatedMonotonicOrNot
= CheckMonotonicBasedVarStore ((VOID
*)(DataBase
+ *(UINT16
*)DataBase
));
4505 AuthencitatedBasedTimeOrNot
= CheckTimeBasedVarStoreOrNot ((VOID
*)(DataBase
+ *(UINT16
*)DataBase
));
4507 if (AuthencitatedMonotonicOrNot
) {
4509 // Read variable with Monotonic based layout from binary
4511 Length
= ReadMonotonicBasedVariableToList (Binary
, StorageListEntry
);
4512 } else if (AuthencitatedBasedTimeOrNot
){
4514 // Read variable with time-based layout from binary
4516 Length
= ReadTimeBasedVariableToList (Binary
, StorageListEntry
);
4519 // Read variable with normal layout from binary
4521 Length
= ReadVariableToList (Binary
, StorageListEntry
);
4528 Insert one storage to the raw bianry, and return its length.
4530 @param Storage The pointer to a storage in storage list.
4531 @param Binary The pointer to the buffer of binary.
4533 @return length The length of storage
4536 PutStorageToBinary (
4537 IN FORMSET_STORAGE
*Storage
,
4539 IN LIST_ENTRY
*StorageListEntry
4542 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
4545 UINT8
*BinaryBeginning
;
4546 FORMSET_STORAGE
*CurStorage
;
4547 LIST_ENTRY
*StorageLink
;
4548 VOID
*VariableStoreHeader
;
4549 BOOLEAN AuthencitatedMonotonicOrNot
;
4550 BOOLEAN AuthencitatedBasedTimeOrNot
;
4552 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
4555 BinaryBeginning
= Binary
;
4556 VariableStoreHeader
= (VOID
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
4557 AuthencitatedMonotonicOrNot
= FALSE
;
4558 AuthencitatedBasedTimeOrNot
= FALSE
;
4560 // Judge the layout of NV by gEfiVariableGuid
4562 AuthencitatedMonotonicOrNot
= CheckMonotonicBasedVarStore (VariableStoreHeader
);
4563 AuthencitatedBasedTimeOrNot
= CheckTimeBasedVarStoreOrNot (VariableStoreHeader
);
4565 // Build the binary for BFV
4567 StorageLink
= GetFirstNode (StorageListEntry
);
4569 while (!IsNull (StorageListEntry
, StorageLink
)) {
4570 CurStorage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
4571 if ((CurStorage
->DefaultId
[0] == Storage
->DefaultId
[0])
4572 && (CurStorage
->PlatformId
[0] == Storage
->PlatformId
[0])
4573 && !CurStorage
->Skip
4575 CurStorage
->Skip
= TRUE
;
4577 if (AuthencitatedMonotonicOrNot
) {
4579 // Copy variable with Monotonic based layout to binary
4581 Length
= CopyMonotonicBasedVariableToBinary (CurStorage
, BinaryBeginning
, Index
);
4582 } else if (AuthencitatedBasedTimeOrNot
){
4584 // Copy variable with time-based layout to binary
4586 Length
= CopyTimeBasedVariableToBinary (CurStorage
, BinaryBeginning
, Index
);
4589 // Copy variable with normall layout to binary
4591 Length
= CopyVariableToBinary (CurStorage
, BinaryBeginning
, Index
);
4595 StorageLink
= GetNextNode (StorageListEntry
, StorageLink
);
4598 // Fix the length of storage header under a specified DefaultId and PlatformId
4600 if (AuthencitatedMonotonicOrNot
) {
4601 FixMontonicVariableHeaderSize (BinaryBeginning
, Length
);
4602 } else if (AuthencitatedBasedTimeOrNot
){
4603 FixBasedTimeVariableHeaderSize (BinaryBeginning
, Length
);
4605 FixVariableHeaderSize (BinaryBeginning
, Length
);
4611 Insert one storage to Fd's NvStoreDatabase, and return its length.
4613 @param Storage The pointer to a storage in storage list.
4614 @param Binary The pointer to the buffer of binary.
4616 @return length The length of storage
4619 PutStorageToNvStoreBinary (
4620 IN FORMSET_STORAGE
*Storage
,
4622 IN LIST_ENTRY
*StorageListEntry
4627 UINT8
*BinaryBeginning
;
4628 FORMSET_STORAGE
*CurStorage
;
4629 LIST_ENTRY
*StorageLink
;
4633 BinaryBeginning
= Binary
;
4635 // Build the binary for NvStorDatabase
4637 StorageLink
= GetFirstNode (StorageListEntry
);
4638 while (!IsNull (StorageListEntry
, StorageLink
)) {
4639 CurStorage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
4640 if ((CurStorage
->PlatformId
[0] == Storage
->PlatformId
[0])
4641 && (CurStorage
->DefaultId
[0] == Storage
->DefaultId
[0])
4642 && !CurStorage
->Skip
4644 CurStorage
->Skip
= TRUE
;
4645 Length
= CopyVariableToNvStoreBinary (CurStorage
, BinaryBeginning
, Index
);
4648 StorageLink
= GetNextNode (StorageListEntry
, StorageLink
);
4651 Length
= (Length
+ 3) & ~3;
4652 FixNvStoreVariableHeaderSize (BinaryBeginning
, Length
);
4657 Optimize the Delta binary size based on the default setting binary, and
4658 create a new binary with new size on the Storage.ffs.
4660 @param DefaultBinary The pointer to a default setting binary
4661 @param DefaultHeaderLen The header lenght of default setting binary
4662 @param DeltaBinary The pointer to a delta setting binary
4663 @param CurrentSize The size of current delta data.
4665 @return length The length of new storage
4668 OptimizeStorageDeltaData (
4669 IN UINT8
*DefaultBinary
,
4670 IN UINT8
*CurrentBinary
,
4671 IN OUT UINT8
*DeltaBinary
,
4672 IN UINT32 CurrentSize
4677 UINT32 DefaultHeaderSize
;
4678 UINT32 DeltaHeaderSize
;
4680 PCD_DATA_DELTA DeltaData
;
4681 DefaultHeaderSize
= ((PCD_DEFAULT_DATA
*)DefaultBinary
)->HeaderSize
+ 4;
4682 DeltaHeaderSize
= ((PCD_DEFAULT_DATA
*)CurrentBinary
)->HeaderSize
+ 4;
4684 // Copy the Delta Header directly
4686 Size
= DeltaHeaderSize
;
4687 memcpy (DeltaBinary
, CurrentBinary
, Size
);
4689 // Compare the delta data and optimize the size
4691 for (Index
= 0; Index
< CurrentSize
- DeltaHeaderSize
; Index
++) {
4692 if (*(DefaultBinary
+ DefaultHeaderSize
+ Index
) != *(CurrentBinary
+ DeltaHeaderSize
+ Index
)) {
4693 DeltaData
.Offset
= Index
;
4694 DeltaData
.Value
= *(CurrentBinary
+ DeltaHeaderSize
+ Index
);
4695 memcpy (DeltaBinary
+ Size
, &DeltaData
, sizeof (DeltaData
));
4696 Size
= Size
+ sizeof(DeltaData
);
4699 *(UINT32
*)DeltaBinary
= Size
;
4700 AlignSize
= (Size
+ 7) & ~7;
4701 //set Alignment data 0x00
4702 for (Index
= 0; Index
< AlignSize
- Size
; Index
++){
4703 *(DeltaBinary
+ Size
+ Index
) = 0x0;
4709 Optimize the Delta binary size based on the default setting binary, and
4710 create a new binary with new size on the Storage.ffs.
4712 @param DefaultBinary The pointer to a default setting binary
4713 @param DefaultHeaderLen The header lenght of default setting binary
4714 @param DeltaBinary The pointer to a delta setting binary
4715 @param CurrentSize The size of current delta data.
4717 @return length The length of new storage
4720 OptimizeStorageSection (
4721 IN UINT8
*DefaultBinary
,
4722 IN UINT8
*CurrentBinary
,
4723 IN OUT UINT8
*DeltaBinary
,
4724 IN UINT32 CurrentSize
4729 UINT32 DefaultHeaderSize
;
4730 UINT32 DeltaHeaderSize
;
4731 DATA_DELTA DeltaData
;
4733 DefaultHeaderSize
= *(UINT16
*)DefaultBinary
;
4734 DeltaHeaderSize
= *(UINT16
*)CurrentBinary
;
4737 // Copy the Delta Header directly
4739 Size
= DeltaHeaderSize
;
4740 memcpy (DeltaBinary
, CurrentBinary
, Size
);
4742 // Compare the delta data and optimize the size
4744 for (Index
= 0; Index
< CurrentSize
- DeltaHeaderSize
; Index
++) {
4745 if (*(DefaultBinary
+ DefaultHeaderSize
+ Index
) != *(CurrentBinary
+ DeltaHeaderSize
+ Index
)) {
4746 DeltaData
.Offset
= Index
;
4747 DeltaData
.Value
= *(CurrentBinary
+ DeltaHeaderSize
+ Index
);
4748 memcpy (DeltaBinary
+ Size
, &DeltaData
, sizeof (DeltaData
));
4749 Size
= Size
+ sizeof(DeltaData
);
4756 Create the storage section and copy it to memory.
4758 @param Buffer The pointer to the buffer
4759 @param Size The size of input buffer.
4761 @return the new size
4764 CreateStorageSection (
4765 IN OUT UINT8
*Buffer
,
4776 // Create the raw section files in FFS
4778 BinaryFd
= fopen (FileName
, "wb+");
4779 if (BinaryFd
== NULL
) {
4780 printf ("Error. Failed to create the raw data section.\n");
4783 fseek (BinaryFd
, 0, SEEK_SET
);
4784 BytesWrite
= fwrite (Buffer
, sizeof (CHAR8
), Size
, BinaryFd
);
4786 if (BytesWrite
!= Size
) {
4787 printf ("Error. Failed to write the raw data section.\n");
4790 CreateRawSection (FileName
, FileName
);
4792 BinaryFd
= fopen (FileName
, "rb");
4793 if (BinaryFd
== NULL
) {
4794 printf ("Error. Failed to open the raw data section.\n");
4797 fseek (BinaryFd
, 0, SEEK_SET
);
4798 BytesWrite
= fread (Buffer
, sizeof (CHAR8
), (Size
+ sizeof (EFI_COMMON_SECTION_HEADER
)), BinaryFd
);
4800 if (BytesWrite
!= (Size
+ sizeof (EFI_COMMON_SECTION_HEADER
))) {
4801 printf ("Error. Failed to read the raw data section.\n");
4805 SectionSize
= FvBufExpand3ByteSize (((EFI_COMMON_SECTION_HEADER
*)Buffer
)->Size
);
4810 Read NvStoreDataBase and insert it to the Storage list.
4812 @param InputFdName The pointer to the input fd name.
4813 @param VarListEntry The pointer to the variable list.
4815 @return EFI_INVALID_PARAMETER
4819 ReadStorageFromNvStoreDatabase (
4820 IN LIST_ENTRY
*VarListEntry
4826 UINT8
*VarDataBinary
;
4827 UINT8
*PreVarDataBinary
;
4829 PCD_DEFAULT_DATA
*DeltaVarStoreHeader
;
4830 PCD_DEFAULT_DATA
*PrePcdDefaultData
;
4835 UINT32 BinaryLength
;
4837 UINT32 PreVarDataSize
;
4838 PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*NvStoreHeader
;
4847 DeltaVarStoreHeader
= NULL
;
4848 PreVarDataBinary
= NULL
;
4851 Size
= sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
);
4852 VarDataBinary
= NULL
;
4855 // Check whether the FD has included the storage FFS
4857 //if (!mMultiPlatformParam.ExistStorageFfsInBfv) {
4858 // return EFI_ABORTED;
4860 NvStoreHeader
= (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*)gEfiFdInfo
.NvStoreDatabase
;
4861 BinaryLength
= NvStoreHeader
->Length
;
4862 Binary
= (UINT8
*)gEfiFdInfo
.NvStoreDatabase
;
4864 // If detect size optimized format, transfer it to normal format
4867 if (mMultiPlatformParam
.SizeOptimized
) {
4868 FullBinary
= calloc(gEfiFdInfo
.FdSize
, sizeof(UINT8
));
4869 if (FullBinary
== NULL
) {
4870 printf ("Error. Memory allocation failed.\n");
4874 while (Size
< BinaryLength
) {
4875 DataBase
= Binary
+ Size
;
4876 DataSize
= *(UINT32
*)DataBase
;
4877 if (Size
== sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
)) {
4878 PrePcdDefaultData
= (PCD_DEFAULT_DATA
*) DataBase
;
4879 HeaderSize
= PrePcdDefaultData
->HeaderSize
;
4880 PreVarDataSize
= DataSize
- 4 - HeaderSize
;
4881 VarDataBinary
= malloc(DataSize
);
4882 if (VarDataBinary
== NULL
) {
4883 printf ("Error. Memory allocation failed.\n");
4886 memcpy (VarDataBinary
, DataBase
, DataSize
);
4887 PreVarDataBinary
= malloc(DataSize
- 4 - HeaderSize
);
4888 if (PreVarDataBinary
== NULL
) {
4889 printf ("Error. Memory allocation failed.\n");
4892 memcpy (PreVarDataBinary
, DataBase
+ 4 + HeaderSize
, DataSize
- 4 - HeaderSize
);
4894 DeltaVarStoreHeader
= (PCD_DEFAULT_DATA
*)DataBase
;
4895 DeltaSize
= DeltaVarStoreHeader
->DataSize
;
4896 HeaderSize
= DeltaVarStoreHeader
->HeaderSize
;
4897 DeltaData
= (UINT8
*) DeltaVarStoreHeader
;
4899 VarDataBinary
= malloc(PreVarDataSize
+ HeaderSize
+ 4);
4900 if (VarDataBinary
== NULL
) {
4901 printf ("Error. Memory allocation failed.\n");
4905 // Copy the default setting data
4907 memcpy (VarDataBinary
, DataBase
, HeaderSize
+ 4);
4908 memcpy (VarDataBinary
+ HeaderSize
+ 4, PreVarDataBinary
, PreVarDataSize
);
4910 // Merge the delta data with default setting to get the full delta data
4912 for (Index
= 0; Index
< (DeltaSize
- HeaderSize
- 4)/sizeof(PCD_DATA_DELTA
); Index
++) {
4913 Offset
= ((PCD_DATA_DELTA
*)(DeltaData
+ HeaderSize
+ 4 + Index
* sizeof(PCD_DATA_DELTA
)))->Offset
;
4914 Value
= ((PCD_DATA_DELTA
*)(DeltaData
+ HeaderSize
+ 4 + Index
* sizeof(PCD_DATA_DELTA
)))->Value
;
4915 if (*(VarDataBinary
+ HeaderSize
+ 4 + Offset
) != Value
) {
4916 *(VarDataBinary
+ HeaderSize
+ 4 + Offset
) = (UINT8
)Value
;
4921 // Store the Variable Data to VarListEntry
4924 ReadNvStoreVariableToList(VarDataBinary
, VarListEntry
);
4925 Size
+= (DataSize
+ 7) & ~7;
4928 if (VarDataBinary
!= NULL
) {
4929 free (VarDataBinary
);
4935 Read FFS from BFV and insert it to the Storage list.
4937 @param InputFdName The pointer to the input fd name.
4938 @param VarListEntry The pointer to the variable list.
4940 @return EFI_INVALID_PARAMETER
4944 ReadStorageFromBfv (
4945 IN LIST_ENTRY
*VarListEntry
4952 UINT8
*PreVarStoreHeader
;
4953 DATA_DELTA
*DeltaVarStoreHeader
;
4957 UINT32 BinaryLength
;
4960 UINT32 FullSectionLen
;
4961 UINT32 FullSectionSize
;
4962 EFI_FFS_FILE_HEADER
*FfsHeader
;
4972 PreVarStoreHeader
= NULL
;
4973 DeltaVarStoreHeader
= NULL
;
4976 FullSectionSize
= 0;
4977 Size
= sizeof (EFI_FFS_FILE_HEADER
);
4982 SectionName
= getcwd(NULL
, _MAX_PATH
);
4983 if (strlen (SectionName
) + 2 * strlen (OS_SEP_STR
) + strlen ("Temp") + strlen ("TempSection.sec") >
4985 printf ("Error. The current path is too long.\n");
4986 return EFI_INVALID_PARAMETER
;
4989 sprintf (SectionName
+ strlen (SectionName
), "%cTemp%cTempSection.sec", OS_SEP
, OS_SEP
);
4991 // Check whether the FD has included the storage FFS
4993 if (!mMultiPlatformParam
.ExistStorageFfsInBfv
) {
4996 FfsHeader
= (EFI_FFS_FILE_HEADER
*)gEfiFdInfo
.StorageFfsInBfv
;
4997 BinaryLength
= FvBufExpand3ByteSize (FfsHeader
->Size
);
4998 Binary
= (UINT8
*)FfsHeader
;
5000 // If detect size optimized format, transfer it to normal format
5003 if (mMultiPlatformParam
.SizeOptimized
) {
5004 FullBinary
= calloc(gEfiFdInfo
.FdSize
, sizeof(UINT8
));
5005 if (FullBinary
== NULL
) {
5006 printf ("Error. Memory allocation failed.\n");
5009 while (Size
< BinaryLength
) {
5010 SectionSize
= FvBufExpand3ByteSize (((EFI_COMMON_SECTION_HEADER
*)(Binary
+ Size
))->Size
);
5011 DataBase
= Binary
+ Size
+ sizeof (EFI_COMMON_SECTION_HEADER
);
5012 if (Size
== sizeof (EFI_FFS_FILE_HEADER
)) {
5013 PreVarStoreHeader
= DataBase
+ *(UINT16
*)DataBase
;
5014 PreDataSize
= SectionSize
- (*(UINT16
*)DataBase
+ sizeof(EFI_COMMON_SECTION_HEADER
));
5015 memcpy (FullBinary
, DataBase
, SectionSize
- sizeof(EFI_COMMON_SECTION_HEADER
));
5016 FullSectionLen
= CreateStorageSection (FullBinary
, *(UINT16
*)DataBase
+ PreDataSize
, SectionName
);
5018 DeltaVarStoreHeader
= (DATA_DELTA
*)(DataBase
+ *(UINT16
*)DataBase
);
5019 DeltaSize
= *(UINT16
*)DataBase
+ PreDataSize
;
5020 DeltaData
= FullBinary
+ FullSectionSize
+ *(UINT16
*)DataBase
;
5022 // Copy the DefaultId and PlatformId directly
5024 memcpy (FullBinary
+ FullSectionSize
, DataBase
, *(UINT16
*)DataBase
);
5026 // Copy the default setting data
5028 memcpy (DeltaData
, PreVarStoreHeader
, PreDataSize
);
5030 // Merge the delta data with default setting to get the full delta data
5032 for (Index
= 0; Index
< (SectionSize
- *(UINT16
*)DataBase
- sizeof(EFI_COMMON_SECTION_HEADER
))/sizeof(DATA_DELTA
); Index
++) {
5033 Offset
= (DeltaVarStoreHeader
+ Index
)->Offset
;
5034 Value
= (DeltaVarStoreHeader
+ Index
)->Value
;
5035 if (*(DeltaData
+ Offset
) != Value
) {
5036 *(DeltaData
+ Offset
) = Value
;
5039 FullSectionLen
= CreateStorageSection (FullBinary
+ FullSectionSize
, DeltaSize
, SectionName
);
5042 // Store the previous binary information
5044 DataBase
= FullBinary
+ FullSectionSize
+ sizeof (EFI_COMMON_SECTION_HEADER
);
5045 PreVarStoreHeader
= DataBase
+ *(UINT16
*)DataBase
;
5047 Size
+= (SectionSize
+ 3) & ~3;
5048 FullSectionSize
+= (FullSectionLen
+ 3) & ~3;;
5051 // Update to the new size
5053 BinaryLength
= FullSectionSize
;
5054 Binary
= FullBinary
;
5059 // Read the storage from BFV and insert to storage list
5061 while (Size
< BinaryLength
) {
5062 SectionSize
= ReadStorageFromBinary ((Binary
+ Size
), VarListEntry
);
5063 Size
+= (SectionSize
+ 3) & ~3;
5065 if (FullBinary
!= NULL
) {
5072 #define SIZE_64K 0x10000
5075 Create the storage and insert it to BFV by calling BfmLib.
5077 @param InputFdName The pointer to the input fd name.
5078 @param OutputFdName The pointer to the input fd name.
5079 @param VarListEntry The pointer to the variable list.
5081 @return EFI_INVALID_PARAMETER
5086 IN CHAR8
*InputFdName
,
5087 IN CHAR8
*OutputFdName
,
5088 IN LIST_ENTRY
*VarListEntry
5093 UINT32 BinaryLength
;
5094 UINT32 PreBinaryLength
;
5095 UINT32 OptimizedBinaryLength
;
5097 UINT32 OptimizedSize
;
5099 LIST_ENTRY
*StorageLink
;
5100 FORMSET_STORAGE
*Storage
;
5101 CHAR8
*SystemCommandFormatString
;
5102 CHAR8
*SectionNameFormatString
;
5103 CHAR8
*SystemCommand
;
5104 CHAR8
*TempSystemCommand
;
5107 BOOLEAN SizeOptimizedFlag
;
5108 CHAR8
*SectionName
[_MAXIMUM_SECTION_FILE_NUM
];
5112 // Workaround for static code checkers.
5113 // Ensures the size of 'IndexStr' can hold all the digits of an unsigned
5119 PreBinaryLength
= 0;
5126 Status
= EFI_SUCCESS
;
5127 SystemCommandFormatString
= NULL
;
5128 SectionNameFormatString
= NULL
;
5129 SystemCommand
= NULL
;
5130 TempSystemCommand
= NULL
;
5131 SizeOptimizedFlag
= FALSE
;
5135 TemDir
= getcwd (NULL
, _MAX_PATH
);
5136 SectionNameFormatString
= "%s%cTemp%c%s.sec";
5138 memset (SectionName
, 0, _MAXIMUM_SECTION_FILE_NUM
* sizeof(CHAR8
*));
5139 FileName
= malloc (strlen (TemDir
) + 1 + strlen ("Storage.ffs") + 1);
5140 if (FileName
== NULL
) {
5141 printf ("Error. Memory allocation failed.\n");
5142 Status
= EFI_ABORTED
;
5145 sprintf (FileName
, "%s%cStorage.ffs", TemDir
, OS_SEP
);
5147 // Allocate the buffer which is the same with the input FD
5149 Binary
= malloc (SIZE_64K
);
5150 if (Binary
== NULL
) {
5151 printf ("Error. Memory allocation failed.\n");
5152 Status
= EFI_ABORTED
;
5155 PreBinary
= malloc (SIZE_64K
);
5156 if (PreBinary
== NULL
) {
5157 printf ("Error. Memory allocation failed.\n");
5158 Status
= EFI_ABORTED
;
5162 // If already existed a Storage.ffs in FD, keep the same format when execute update operation whatever input -a or not -a options.
5164 if (mMultiPlatformParam
.SizeOptimized
5165 || (!mMultiPlatformParam
.ExistStorageFfsInBfv
&& mMultiPlatformParam
.SizeOptimizedParam
)
5167 SizeOptimizedFlag
= TRUE
;
5168 } else if (mMultiPlatformParam
.ExistStorageFfsInBfv
&& mMultiPlatformParam
.SizeOptimizedParam
&& !mMultiPlatformParam
.SizeOptimized
) {
5169 printf ("\nWarning. The \"-a\" parameter is ignored.\n");
5172 // Build the binary for BFV
5174 StorageLink
= GetFirstNode (VarListEntry
);
5176 while (!IsNull (VarListEntry
, StorageLink
)) {
5177 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
5178 if (!Storage
->Skip
) {
5180 // Assign the section name under the Temp directory
5182 sprintf (IndexStr
, "%d", Index
);
5183 SectionName
[Index
] = calloc (
5184 strlen (SectionNameFormatString
) + strlen (TemDir
) + strlen(IndexStr
) + 1,
5187 if (SectionName
[Index
] == NULL
) {
5188 printf ("Error. Memory allocation failed.\n");
5189 Status
= EFI_ABORTED
;
5200 memset(Binary
, 0, SIZE_64K
);
5201 Size
= PutStorageToBinary (Storage
, Binary
, VarListEntry
);
5202 assert (Size
< SIZE_64K
);
5204 // Re-calculate the storage section by size optimization
5206 if (PreBinaryLength
!= 0 && SizeOptimizedFlag
) {
5207 OptimizedSize
= OptimizeStorageSection (
5208 PreBinary
+ sizeof (EFI_COMMON_SECTION_HEADER
),
5210 PreBinary
+ PreBinaryLength
,
5213 if (OptimizedSize
== 0) {
5214 printf ("Error. Failed to optimize the storage section.\n");
5215 Status
= EFI_ABORTED
;
5220 // Create the raw section with normal format
5222 assert (Size
< SIZE_64K
- sizeof (EFI_COMMON_SECTION_HEADER
));
5223 BinaryLength
= CreateStorageSection (Binary
, Size
, SectionName
[Index
]);
5224 if (BinaryLength
== 0) {
5225 printf ("Error. Failed to create the storage section.\n");
5226 Status
= EFI_ABORTED
;
5229 assert (BinaryLength
< SIZE_64K
);
5232 // Create the raw section with optimized format
5234 if (PreBinaryLength
!= 0 && SizeOptimizedFlag
) {
5235 OptimizedBinaryLength
= CreateStorageSection (PreBinary
+ PreBinaryLength
, OptimizedSize
, SectionName
[Index
]);
5236 if (OptimizedBinaryLength
== 0) {
5237 printf ("Error. Failed to create the storage section.\n");
5238 Status
= EFI_ABORTED
;
5242 PreBinaryLength
= BinaryLength
;
5243 memcpy (PreBinary
, Binary
, PreBinaryLength
);
5246 StorageLink
= GetNextNode (VarListEntry
, StorageLink
);
5249 // Create the raw ffs by GenFfs
5251 CreateRawFfs (&SectionName
[0], FileName
, SizeOptimizedFlag
);
5254 // Call BfmLib to insert this binary into the BFV of FD.
5257 // Construction 'system' command string
5259 if (mMultiPlatformParam
.ExistStorageFfsInBfv
) {
5260 if (mFvNameGuidString
!= NULL
) {
5261 SystemCommandFormatString
= "BfmLib -r \"%s\" \"%s\" \"%s\" -g %s";
5262 SystemCommand
= malloc (
5263 strlen (SystemCommandFormatString
) + strlen (mInputFdName
) + strlen (mOutputFdName
) + strlen (FileName
) + strlen (mFvNameGuidString
) + 1
5265 if (SystemCommand
== NULL
) {
5266 Status
= EFI_ABORTED
;
5271 "BfmLib -r \"%s\" \"%s\" \"%s\" -g %s",
5278 SystemCommandFormatString
= "BfmLib -r \"%s\" \"%s\" \"%s\"";
5279 SystemCommand
= malloc (
5280 strlen (SystemCommandFormatString
) + strlen (mInputFdName
) + strlen (mOutputFdName
) + strlen (FileName
) + 1
5282 if (SystemCommand
== NULL
) {
5283 Status
= EFI_ABORTED
;
5288 "BfmLib -r \"%s\" \"%s\" \"%s\"",
5295 if (mFvNameGuidString
!= NULL
) {
5296 SystemCommandFormatString
= "BfmLib -i \"%s\" \"%s\" \"%s\" -g %s";
5297 SystemCommand
= malloc (
5298 strlen (SystemCommandFormatString
) + strlen (mInputFdName
) + strlen (mOutputFdName
) + strlen (FileName
) + strlen (mFvNameGuidString
) + 1
5300 if (SystemCommand
== NULL
) {
5301 Status
= EFI_ABORTED
;
5306 "BfmLib -i \"%s\" \"%s\" \"%s\" -g %s",
5313 SystemCommandFormatString
= "BfmLib -i \"%s\" \"%s\" \"%s\"";
5314 SystemCommand
= malloc (
5315 strlen (SystemCommandFormatString
) + strlen (mInputFdName
) + strlen (mOutputFdName
) + strlen (FileName
) + 1
5317 if (SystemCommand
== NULL
) {
5318 Status
= EFI_ABORTED
;
5323 "BfmLib -i \"%s\" \"%s\" \"%s\"",
5331 if (mFullGuidToolDefinitionDir
[0] != 0) {
5332 TempSystemCommand
= SystemCommand
;
5333 SystemCommand
= malloc (
5334 strlen (mFullGuidToolDefinitionDir
) + strlen ("\\") + strlen (TempSystemCommand
) + 1
5337 if (SystemCommand
== NULL
) {
5338 free (TempSystemCommand
);
5341 strcpy (SystemCommand
, mFullGuidToolDefinitionDir
);
5342 strcat (SystemCommand
, OS_SEP_STR
);
5343 strcat (SystemCommand
, TempSystemCommand
);
5344 free (TempSystemCommand
);
5347 ReturnValue
= system (SystemCommand
);
5348 free (SystemCommand
);
5350 if (ReturnValue
== -1) {
5351 Status
= EFI_ABORTED
;
5354 for (Index
= 0; SectionName
[Index
] != NULL
; Index
++) {
5355 free (SectionName
[Index
]);
5357 if (PreBinary
!= NULL
) {
5367 Create the storage and insert it to NvStoreDatabase.
5369 @param InputFdName The pointer to the input fd name.
5370 @param OutputFdName The pointer to the input fd name.
5371 @param VarListEntry The pointer to the variable list.
5373 @return EFI_INVALID_PARAMETER
5377 InsertBinaryToNvStoreDatabase (
5378 IN CHAR8
*InputFdName
,
5379 IN CHAR8
*OutputFdName
,
5380 IN LIST_ENTRY
*VarListEntry
5385 UINT8
*NvStoreDatabaseBuffer
;
5386 UINT32 PreBinaryLength
;
5388 UINT32 NvStoreDatabaseSize
;
5389 UINT32 OptimizedSize
;
5391 LIST_ENTRY
*StorageLink
;
5392 FORMSET_STORAGE
*Storage
;
5393 BOOLEAN SizeOptimizedFlag
;
5394 PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*NvStoreBufferHeader
;
5395 PCD_DEFAULT_DATA
*PcdDefaultData
;
5398 // Workaround for static code checkers.
5399 // Ensures the size of 'IndexStr' can hold all the digits of an unsigned
5403 PreBinaryLength
= 0;
5408 NvStoreDatabaseBuffer
= NULL
;
5409 PcdDefaultData
= NULL
;
5411 NvStoreDatabaseSize
= 0;
5413 Status
= EFI_SUCCESS
;
5414 SizeOptimizedFlag
= FALSE
;
5417 // Allocate the buffer which is the same with the input FD
5420 Binary
= malloc (SIZE_64K
);
5421 if (Binary
== NULL
) {
5422 printf ("Error. Memory allocation failed.\n");
5423 Status
= EFI_ABORTED
;
5426 NvStoreBufferHeader
= (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*) gEfiFdInfo
.NvStoreDatabase
;
5427 NvStoreDatabaseBuffer
= malloc (NvStoreBufferHeader
->MaxLength
);
5428 if (NvStoreDatabaseBuffer
== NULL
) {
5429 printf ("Error. Memory allocation failed.\n");
5430 Status
= EFI_ABORTED
;
5433 memcpy(NvStoreDatabaseBuffer
, gEfiFdInfo
.NvStoreDatabase
, NvStoreBufferHeader
->MaxLength
);
5434 PreBinary
= malloc (SIZE_64K
);
5435 if (PreBinary
== NULL
) {
5436 printf ("Error. Memory allocation failed.\n");
5437 Status
= EFI_ABORTED
;
5441 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
5442 SizeOptimizedFlag
= TRUE
;
5444 Status
= EFI_ABORTED
;
5448 // Build the binary for BFV
5450 StorageLink
= GetFirstNode (VarListEntry
);
5451 while (!IsNull (VarListEntry
, StorageLink
)) {
5452 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
5453 if (!Storage
->Skip
) {
5454 memset(Binary
, 0, SIZE_64K
);
5455 Size
= PutStorageToNvStoreBinary (Storage
, Binary
, VarListEntry
);
5456 assert (Size
< SIZE_64K
);
5458 // Re-calculate the storage section by size optimization
5460 if (PreBinaryLength
!= 0 && SizeOptimizedFlag
) {
5461 OptimizedSize
= OptimizeStorageDeltaData (
5464 NvStoreDatabaseBuffer
+ NvStoreDatabaseSize
,
5467 if (OptimizedSize
== 0) {
5468 printf ("Error. Failed to optimize the storage section.\n");
5469 Status
= EFI_ABORTED
;
5473 OptimizedSize
= (OptimizedSize
+ 7) & ~7;
5474 NvStoreDatabaseSize
+= OptimizedSize
;
5477 Size
= (Size
+ 7) & ~7;
5478 PcdDefaultData
= (PCD_DEFAULT_DATA
*)Binary
;
5479 memcpy(NvStoreDatabaseBuffer
+ sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER
), Binary
, Size
+ PcdDefaultData
->HeaderSize
+ 4 );
5480 PreBinaryLength
= Size
+ PcdDefaultData
->HeaderSize
+ 4;
5481 NvStoreDatabaseSize
= sizeof(PCD_NV_STORE_DEFAULT_BUFFER_HEADER
) + PreBinaryLength
;
5482 memcpy(PreBinary
, Binary
, PreBinaryLength
);
5485 StorageLink
= GetNextNode (VarListEntry
, StorageLink
);
5487 if (NvStoreBufferHeader
->Length
!= NvStoreDatabaseSize
) {
5488 ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*)NvStoreDatabaseBuffer
)->Length
= NvStoreDatabaseSize
;
5490 memcpy(gEfiFdInfo
.NvStoreDatabase
, NvStoreDatabaseBuffer
, NvStoreDatabaseSize
);
5493 DestroyAllStorage (&mAllVarListEntry
);
5494 if (PreBinary
!= NULL
) {
5503 extern UINT32 mMaxCount
;
5504 extern UINT32 mCount
;
5505 extern CHAR8
*mStringBuffer
;
5508 Read the HII configure file from all FFS
5510 @retval EFI_SUCCESS It was complete successfully
5511 @return EFI_ABORTED An error occurred
5521 UINT16 DefaultIndex
;
5522 UINT16 PlatformIndex
;
5523 UINT16 PreDefaultId
;
5524 UINT64 PrePlatformId
;
5525 LIST_ENTRY NewStorageListHead
;
5526 BOOLEAN BfvOverried
;
5527 FORMSET_STORAGE
*Storage
;
5528 LIST_ENTRY
*StorageLink
;
5531 Status
= EFI_SUCCESS
;
5532 BfvOverried
= FALSE
;
5534 PreDefaultId
= 0xFFFF;
5535 PrePlatformId
= 0xFFFFFFFFFFFFFFFF;
5537 // Read all Ifr information to Formset list
5539 for (Index
= 0; (gEfiFdInfo
.FfsArray
[Index
] != NULL
) && (gEfiFdInfo
.Length
[Index
] != 0); Index
++) {
5540 Status
= ReadAllIfrToFromset (
5541 gEfiFdInfo
.FfsArray
[Index
],
5542 gEfiFdInfo
.Length
[Index
]
5544 if (EFI_ERROR (Status
)) {
5549 // Read defaultId and platformId
5551 if (!gEfiFdInfo
.ExistNvStoreDatabase
) {
5552 Status
= ReadDefaultAndPlatformId (&mFormSetListEntry
);
5553 if (EFI_ERROR (Status
)) {
5558 // If existed the variable data in BFV, abstract them to a variable list.
5559 // If not exsited, just skip it.
5561 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5562 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
5563 Status
= ReadStorageFromNvStoreDatabase(&mBfvVarListEntry
);
5565 Status
= ReadStorageFromBfv (&mBfvVarListEntry
);
5567 if (!EFI_ERROR (Status
)) {
5572 // If not existed the storage data in BFV, evaluate the
5573 // default value according to the defaultId and platformId
5574 // Or else, skip it.
5577 Status
= EvaluateTheValueInFormset (FALSE
);
5578 if (EFI_ERROR (Status
)) {
5584 // Output the question and value information on screen
5586 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5588 // Multi-platform mode support
5590 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
5591 StorageLink
= GetFirstNode (&mBfvVarListEntry
);
5592 while (!IsNull (&mBfvVarListEntry
, StorageLink
)) {
5593 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
5594 if (PreDefaultId
== Storage
->DefaultId
[0] && PrePlatformId
== Storage
->PlatformId
[0]) {
5595 StorageLink
= GetNextNode (&mBfvVarListEntry
, StorageLink
);
5598 PreDefaultId
= Storage
->DefaultId
[0];
5599 PrePlatformId
= Storage
->PlatformId
[0];
5601 InitializeListHead(&NewStorageListHead
);
5603 // Use the varaible stroage list from BFV
5605 Status
= BuildVariableList(
5606 &NewStorageListHead
,
5608 Storage
->DefaultId
[0],
5609 Storage
->PlatformId
[0],
5614 if (EFI_ERROR (Status
)) {
5615 DestroyAllStorage (&NewStorageListHead
);
5618 if (IsListEmpty (&NewStorageListHead
)) {
5621 Status
= PrintInfoInAllFormset (&mFormSetListEntry
, &NewStorageListHead
);
5622 if (EFI_ERROR (Status
)) {
5623 DestroyAllStorage (&NewStorageListHead
);
5626 DestroyAllStorage (&NewStorageListHead
);
5627 StorageLink
= GetNextNode (&mBfvVarListEntry
, StorageLink
);
5630 for (DefaultIndex
= 0; DefaultIndex
< mMultiPlatformParam
.DefaultIdNum
; DefaultIndex
++) {
5631 for (PlatformIndex
= 0; PlatformIndex
< mMultiPlatformParam
.PlatformIdNum
; PlatformIndex
++) {
5632 InitializeListHead(&NewStorageListHead
);
5635 // Use the varaible stroage list from BFV
5637 Status
= BuildVariableList(
5638 &NewStorageListHead
,
5640 mMultiPlatformParam
.DefaultId
[DefaultIndex
],
5641 mMultiPlatformParam
.PlatformId
[PlatformIndex
],
5647 // Use the varaible storage list from IFR
5649 Status
= BuildVariableList(
5650 &NewStorageListHead
,
5652 mMultiPlatformParam
.DefaultId
[DefaultIndex
],
5653 mMultiPlatformParam
.PlatformId
[PlatformIndex
],
5658 if (EFI_ERROR (Status
)) {
5659 DestroyAllStorage (&NewStorageListHead
);
5662 if (IsListEmpty (&NewStorageListHead
)) {
5665 Status
= PrintInfoInAllFormset (&mFormSetListEntry
, &NewStorageListHead
);
5666 if (EFI_ERROR (Status
)) {
5667 DestroyAllStorage (&NewStorageListHead
);
5670 DestroyAllStorage (&NewStorageListHead
);
5675 Status
= PrintInfoInAllFormset (&mFormSetListEntry
, &mAllVarListEntry
);
5676 if (EFI_ERROR (Status
)) {
5685 Update the HII setup value.
5687 Read the Config information from config file, and then compare it with the current FFS.
5688 Record the different value to EFI variable.
5690 @param Fv the Pointer to the FFS
5691 @param Length the length of FFS
5693 @retval EFI_SUCCESS It was complete successfully
5694 @return EFI_ABORTED An error occurred
5704 BOOLEAN BfvOverried
;
5706 Status
= EFI_SUCCESS
;
5707 BfvOverried
= FALSE
;
5710 // Read all Ifr information to Formset list
5712 for (Index
= 0; (gEfiFdInfo
.FfsArray
[Index
] != NULL
) && (gEfiFdInfo
.Length
[Index
] != 0); Index
++) {
5713 Status
= ReadAllIfrToFromset (
5714 gEfiFdInfo
.FfsArray
[Index
],
5715 gEfiFdInfo
.Length
[Index
]
5717 if (EFI_ERROR (Status
)) {
5722 // Read defaultId and platformId
5724 if (!gEfiFdInfo
.ExistNvStoreDatabase
) {
5725 Status
= ReadDefaultAndPlatformId (&mFormSetListEntry
);
5726 if (EFI_ERROR (Status
)) {
5731 // If existed the variable data in BFV, abstract them to a variable list.
5732 // If not exsited, just skip it.
5734 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5735 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
5736 Status
= ReadStorageFromNvStoreDatabase (&mBfvVarListEntry
);
5738 Status
= ReadStorageFromBfv (&mBfvVarListEntry
);
5740 if (!EFI_ERROR (Status
)) {
5744 if (mMultiPlatformParam
.MultiPlatformOrNot
&& BfvOverried
) {
5745 if (mUqiList
== NULL
) {
5748 Status
= CheckValueUpdateList ();
5749 if (EFI_ERROR (Status
)) {
5754 // Evaluate the default value according to the defaultId and platformId
5756 if (mUqiList
== NULL
) {
5757 Status
= EvaluateTheValueInFormset (FALSE
);
5759 Status
= EvaluateTheValueInFormset (TRUE
);
5761 if (EFI_ERROR (Status
)) {
5766 // print error information in UQI list
5768 if (PrintErrorInfo (mUqiList
)) {
5772 // Output the variable information to BFV in multi-platform mode
5773 // Or write it to the Nvstrage in general mode
5775 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5776 if (ExistEfiVarOrNot (&mAllVarListEntry
) && Operations
== UPDATE
) {
5777 printf ("Error. Please use --remove or --ignore to update the variable storage for an FD with variables in its NvStorage.\n");
5782 // Sync the data from List data to efi variable.
5784 Status
= EfiVarAndListExchange (FALSE
, &mAllVarListEntry
);
5785 if (Status
== EFI_OUT_OF_RESOURCES
) {
5786 printf ("Error. There is no available space in efi variable. \n");
5789 if (Status
== EFI_INVALID_PARAMETER
) {
5794 PrintUpdateListInfo (mUqiList
);
5800 Quick Update the HII setup value.
5802 Read the Config information from command line directly, and then compare it with the current FFS.
5803 Record the different value to EFI variable.
5805 @retval EFI_SUCCESS It was complete successfully
5806 @return EFI_ABORTED An error occurred
5810 QuickUpdateCongFile (
5817 Status
= EFI_SUCCESS
;
5820 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5821 printf ("Error. The quick update operation is not supported in multi-platform mode.\n");
5825 // Check whether the FD has included the storage FFS
5827 if (mMultiPlatformParam
.ExistStorageFfsInBfv
) {
5828 printf ("Error. Variable storage exists in BFV of Fd. This is generated in multi-platform mode.\n");
5829 printf ("Error. The quick update operation is not supported in multi-platform mode.\n");
5833 // Read all Ifr information to Formset list
5835 for (Index
= 0; (gEfiFdInfo
.FfsArray
[Index
] != NULL
) && (gEfiFdInfo
.Length
[Index
] != 0); Index
++) {
5836 Status
= ReadAllIfrToFromset (
5837 gEfiFdInfo
.FfsArray
[Index
],
5838 gEfiFdInfo
.Length
[Index
]
5840 if (EFI_ERROR (Status
)) {
5845 // Evaluate the default value according to the defaultId and platformId
5847 Status
= EvaluateTheValueInFormset (TRUE
);
5848 if (EFI_ERROR (Status
)) {
5852 // print error information in UQI list
5854 if (PrintErrorInfo (mUqiList
)) {
5858 // Sync the data from mAllVarListEntry data to efi variable.
5860 Status
= EfiVarAndListExchange (FALSE
, &mAllVarListEntry
);
5861 if (Status
== EFI_OUT_OF_RESOURCES
) {
5862 printf ("Error. There is no available space in Nvstorage. \n");
5865 if (Status
== EFI_INVALID_PARAMETER
) {
5869 PrintUpdateListInfo (mUqiList
);
5875 Check the HII setup value.
5877 Read the Config information from config file, and then compare it with the current FFS.
5878 Print the different values on screen.
5880 @retval EFI_SUCCESS It was complete successfully
5881 @return EFI_ABORTED An error occurred
5891 UINT16 DefaultIndex
;
5892 UINT16 PlatformIndex
;
5896 Status
= EFI_SUCCESS
;
5903 // Read all Ifr information to Formset list
5905 for (Index
= 0; (gEfiFdInfo
.FfsArray
[Index
] != NULL
) && (gEfiFdInfo
.Length
[Index
] != 0); Index
++) {
5906 Status
= ReadAllIfrToFromset (
5907 gEfiFdInfo
.FfsArray
[Index
],
5908 gEfiFdInfo
.Length
[Index
]
5910 if (EFI_ERROR (Status
)) {
5915 // Read defaultId and platformId
5917 Status
= ReadDefaultAndPlatformId (&mFormSetListEntry
);
5918 if (EFI_ERROR (Status
)) {
5922 // Read the config data from BFV in multi-platform mode
5924 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5925 Status
= ReadStorageFromBfv (&mAllVarListEntry
);
5926 if (EFI_ERROR (Status
)) {
5927 printf ("Error. No storage variable data exists in BFV.\n");
5932 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
5933 ScanUqiFullList (mUqiList
);
5936 // Multi-platform mode support
5938 for (DefaultIndex
= 0; DefaultIndex
< mMultiPlatformParam
.DefaultIdNum
; DefaultIndex
++) {
5939 for (PlatformIndex
= 0; PlatformIndex
< mMultiPlatformParam
.PlatformIdNum
; PlatformIndex
++) {
5940 DefaultId
= mMultiPlatformParam
.DefaultId
[DefaultIndex
];
5941 PlatformId
= mMultiPlatformParam
.PlatformId
[PlatformIndex
];
5943 //Only parse one time, if a group of defaultId and platformId which have the same variable
5944 // Take the first one as a key Id of a group
5946 if (NoTheKeyIdOfGroup (DefaultId
, PlatformId
)) {
5950 InitializeListHead(&mVarListEntry
);
5951 Status
= BuildVariableList(
5959 if (EFI_ERROR (Status
)) {
5962 if (IsListEmpty (&mVarListEntry
)) {
5965 SetUqiParametersMultiMode (mUqiList
, DefaultId
, PlatformId
);
5966 DestroyAllStorage (&mVarListEntry
);
5973 Status
= ExtractDefault (
5980 if (EFI_ERROR (Status
)) {
5984 // If existed the variable in NvStorage, copy them to mVarListEntry.
5985 // Synchronize the default value from the EFI variable zone to variable list
5987 Status
= EfiVarAndListExchange (TRUE
, &mVarListEntry
);
5988 if (Status
== EFI_INVALID_PARAMETER
) {
5989 Status
= EFI_ABORTED
;
5993 // Update the value from script file
5995 Status
= SetUqiParameters (mUqiList
,0, 0);
5996 if (EFI_ERROR (Status
)) {
6000 // Copy Stroage from mVarListEntry to mAllVarListEntry
6002 Status
= BuildVariableList (&mAllVarListEntry
, &mVarListEntry
, 0, 0, TRUE
, VERIFY
);
6003 if (EFI_ERROR (Status
)) {
6007 PrintVerifiedListInfo (mUqiList
);
6012 Search the config file from the path list.
6014 Split the path from env PATH, and then search the cofig
6015 file from these paths. The priority is from left to
6016 right of PATH string. When met the first Config file, it
6017 will break and return the pointer to the full file name.
6019 @param PathList the pointer to the path list.
6020 @param FileName the pointer to the file name.
6022 @retval The pointer to the file name.
6023 @return NULL An error occurred.
6026 SearchConfigFromPathList (
6032 CHAR8
*FileNamePath
;
6035 FileNamePath
= NULL
;
6037 CurDir
= strtok (PathList
,";");
6039 CurDir
= strtok (PathList
,":");
6041 while (CurDir
!= NULL
) {
6042 FileNamePath
= (char *)calloc(
6043 strlen (CurDir
) + strlen (OS_SEP_STR
) +strlen (FileName
) + 1,
6046 if (FileNamePath
== NULL
) {
6049 sprintf(FileNamePath
, "%s%c%s", CurDir
, OS_SEP
, FileName
);
6050 if (access (FileNamePath
, 0) != -1) {
6051 return FileNamePath
;
6054 CurDir
= strtok(NULL
, ";");
6056 CurDir
= strtok(NULL
, ":");
6058 free (FileNamePath
);
6059 FileNamePath
= NULL
;
6065 FCE application entry point
6067 @param argc The number of input parameters.
6068 @param *argv[] The array pointer to the parameters.
6070 @retval 0 The application exited normally.
6071 @retval 1 An error occurred.
6072 @retval 2 An error about check occurred.
6087 BOOLEAN IsFileExist
;
6088 CHAR8 FullGuidToolDefinition
[_MAX_PATH
];
6092 UINTN FileNameIndex
;
6096 Status
= EFI_SUCCESS
;
6103 mFormSetOrderRead
= 0;
6104 mFormSetOrderParse
= 0;
6111 TemDir
= getcwd (NULL
, _MAX_PATH
);
6112 if (strlen (TemDir
) + strlen (OS_SEP_STR
) + strlen (TEMP_DIR_NAME
) > _MAX_PATH
- 1) {
6113 printf ("The directory is too long \n");
6116 strncat (TemDir
, OS_SEP_STR
, _MAX_PATH
- strlen (TemDir
) - 1);
6117 strncat (TemDir
, TEMP_DIR_NAME
, _MAX_PATH
- strlen (TemDir
) - 1);
6118 memset (&mMultiPlatformParam
, 0, sizeof (MULTI_PLATFORM_PARAMETERS
));
6120 SetUtilityName (UTILITY_NAME
);
6122 // Workaroud: the first call to this function
6123 // returns a file name ends with dot
6128 CHAR8 tmp
[] = "/tmp/fileXXXXXX";
6130 Fdtmp
= mkstemp(tmp
);
6134 // Save, and then skip filename arg
6136 mUtilityFilename
= argv
[0];
6140 // Get the same path with the application itself
6142 if (strlen (mUtilityFilename
) > _MAX_PATH
- 1) {
6143 Error (NULL
, 0, 2000, "Parameter: The input file name is too long", NULL
);
6146 strncpy (FullGuidToolDefinition
, mUtilityFilename
, _MAX_PATH
- 1);
6147 FullGuidToolDefinition
[_MAX_PATH
- 1] = 0;
6148 FileNameIndex
= strlen (FullGuidToolDefinition
);
6149 while (FileNameIndex
!= 0) {
6151 if (FullGuidToolDefinition
[FileNameIndex
] == OS_SEP
) {
6152 FullGuidToolDefinition
[FileNameIndex
] = 0;
6153 strcpy (mFullGuidToolDefinitionDir
, FullGuidToolDefinition
);
6158 // Build the path list for Config file scan. The priority is below.
6159 // 1. Scan the current path
6160 // 2. Scan the same path with the application itself
6161 // 3. Scan the current %PATH% of OS environment
6162 // 4. Use the build-in default configuration
6164 PathList
= getenv("PATH");
6165 if (PathList
== NULL
) {
6166 Error (NULL
, 0, 1001, "Option: Environment variable 'PATH' does not exist", NULL
);
6169 EnvLen
= strlen(PathList
);
6170 NewPathList
= (char *)calloc(
6173 + strlen (mFullGuidToolDefinitionDir
)
6179 if (NewPathList
== NULL
) {
6180 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
6186 sprintf (NewPathList
, "%s;%s;%s", ".", mFullGuidToolDefinitionDir
, PathList
);
6188 sprintf (NewPathList
, "%s:%s:%s", ".", mFullGuidToolDefinitionDir
, PathList
);
6195 // Load Guid Tools definition
6197 InFilePath
= SearchConfigFromPathList(NewPathList
, mGuidToolDefinition
);
6199 if (InFilePath
!= NULL
) {
6200 printf ("\nThe Guid Tool Definition comes from the '%s'. \n", InFilePath
);
6201 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (InFilePath
);
6205 // Use the pre-defined standard guided tools.
6207 printf ("\nThe Guid Tool Definition comes from the build-in default configuration. \n");
6208 mParsedGuidedSectionTools
= PreDefinedGuidedTools ();
6211 // Parse the command line
6213 strcpy (mSetupTxtName
, "NoSetupFile");
6214 Status
= ParseCommmadLine (argc
,argv
);
6215 if (EFI_ERROR (Status
)) {
6219 // Print utility header
6221 printf ("\nIntel(R) Firmware Configuration Editor. (Intel(R) %s) Version %d.%d. %s.\n\n",
6223 UTILITY_MAJOR_VERSION
,
6224 UTILITY_MINOR_VERSION
,
6228 // Check the revision of BfmLib
6230 Status
= CheckBfmLibRevision ();
6231 if (EFI_ERROR (Status
)) {
6232 printf ("Please use the correct revision of BfmLib %s. \n", __BUILD_VERSION
);
6235 if (strcmp (mSetupTxtName
, "NoSetupFile")) {
6236 ScriptFile
= fopen (mSetupTxtName
, "r");
6237 if (ScriptFile
== NULL
) {
6238 printf ("Error. Cannot open the script file.\n");
6241 Status
= PickUpUqiFromScript (ScriptFile
);
6242 if (EFI_ERROR (Status
)) {
6243 fclose (ScriptFile
);
6244 IsFileExist
= FALSE
;
6247 fclose (ScriptFile
);
6249 if (!mMultiPlatformParam
.MultiPlatformOrNot
6250 && (Operations
== UPDATE_REMOVE
|| Operations
== UPDATE_IGNORE
)
6252 printf ("Error. --remove and --ignore cannot be used in normal mode.\n");
6257 if (access (TemDir
, 0) != -1) {
6262 // Initialize the variables
6264 Status
= PickUpFfsFromFd ();
6265 if (EFI_ERROR (Status
)) {
6266 printf ("Error. Invalid FD file.\n");
6267 IsFileExist
= FALSE
;
6271 if (gEfiFdInfo
.FfsArray
[0] == NULL
) {
6272 printf ("Error. Cannot find any HII offset in current FD files, please check the BaseTools.\n");
6277 //Config the global variables
6279 if (mMultiPlatformParam
.Uqi
.Data
!= NULL
) {
6282 Status
= GetEfiVariablesAddr (UqiIsSet
);
6283 if (EFI_ERROR (Status
)) {
6284 printf ("Error. Cannot locate the EFI variable zone in FD.\n");
6288 if (gEfiFdInfo
.ExistNvStoreDatabase
&& !mMultiPlatformParam
.MultiPlatformOrNot
) {
6289 mMultiPlatformParam
.MultiPlatformOrNot
= TRUE
;
6292 // Initialize the FormSet and VarList List
6294 InitializeListHead (&mFormSetListEntry
);
6295 InitializeListHead (&mVarListEntry
);
6296 InitializeListHead (&mBfvVarListEntry
);
6297 InitializeListHead (&mAllVarListEntry
);
6299 mStringBuffer
= malloc (mMaxCount
);
6300 if (mStringBuffer
== NULL
) {
6301 printf ("Fali to allocate memory!\n");
6307 // Decide how to deal with the Fd
6309 switch (Operations
) {
6312 printf ("\nStart the Read Mode:\n");
6313 Status
= ReadCongFile ();
6314 if (EFI_ERROR (Status
)) {
6322 printf ("\nStart the Update Mode:\n");
6323 Status
= UpdateCongFile ();
6324 if (EFI_ERROR (Status
)) {
6330 printf ("\nStart the Verify Mode:\n");
6331 Status
= CheckCongFile ();
6332 if (EFI_ERROR (Status
)) {
6338 printf ("\nStart the Update Quick Mode:\n");
6339 Status
= QuickUpdateCongFile ();
6340 if (EFI_ERROR (Status
)) {
6350 mStringBuffer
[mCount
] = '\0';
6351 fwrite (mStringBuffer
, sizeof (CHAR8
), mCount
, stdout
);
6353 free (mStringBuffer
);
6355 if (Status
!= SUCCESS
) {
6359 // If multi-platform mode, insert the variables to BFV
6361 if (mMultiPlatformParam
.MultiPlatformOrNot
6362 && (IsListEmpty (&mAllVarListEntry
) == FALSE
)
6363 &&((Operations
== UPDATE
) || (Operations
== UPDATE_REMOVE
) || (Operations
== UPDATE_IGNORE
) || (Operations
== UPDATEQ
))
6365 IsFileExist
= FALSE
;
6366 if (gEfiFdInfo
.ExistNvStoreDatabase
) {
6367 Status
= InsertBinaryToNvStoreDatabase (mInputFdName
, mOutputFdName
, &mAllVarListEntry
);
6369 Status
= InsertBinaryToBfv (mInputFdName
, mOutputFdName
, &mAllVarListEntry
);
6371 if (EFI_ERROR (Status
)) {
6375 // Remove the variables in NvStorage in multi-platform mode by user specified requirement
6377 if (Operations
== UPDATE_REMOVE
) {
6378 if (gEfiFdInfo
.Fd
!= NULL
) {
6379 free (gEfiFdInfo
.Fd
);
6381 gEfiFdInfo
.Fd
= ReadFileToMemory (mOutputFdName
, &gEfiFdInfo
.FdSize
);
6382 if (gEfiFdInfo
.Fd
== NULL
) {
6383 Status
= EFI_ABORTED
;
6385 Status
= RemoveEfiVar (&mAllVarListEntry
);
6387 if (EFI_ERROR (Status
)) {
6388 printf ("Error. Failed to remove the variable from NVRAM.\n");
6396 (!mMultiPlatformParam
.MultiPlatformOrNot
&&((Operations
== UPDATE
) || (Operations
== UPDATEQ
)))
6397 || (mMultiPlatformParam
.MultiPlatformOrNot
&& (Operations
== UPDATE_REMOVE
|| ((Operations
== UPDATE
) && IsListEmpty (&mAllVarListEntry
))))
6399 OutputFd
= fopen (mOutputFdName
, "wb+");
6400 if (OutputFd
== NULL
) {
6401 printf ("Error. Failed to create the output FD file.\n");
6405 fseek (OutputFd
, 0, SEEK_SET
);
6406 BytesWrite
= fwrite (gEfiFdInfo
.Fd
, sizeof (CHAR8
), gEfiFdInfo
.FdSize
, OutputFd
);
6408 if (BytesWrite
!= gEfiFdInfo
.FdSize
) {
6409 printf ("Error. Failed to create the FD image. \n");
6414 if ((Operations
== UPDATE
) || (Operations
== UPDATE_REMOVE
) || (Operations
== UPDATE_IGNORE
) || (Operations
== UPDATEQ
)) {
6415 printf ("\nCongratulations. The output Fd file '%s' has been completed successfully.\n", mOutputFdName
);
6419 // Delete the temporary directory and files
6427 if (gEfiFdInfo
.Fd
!= NULL
) {
6428 free (gEfiFdInfo
.Fd
);
6431 if (mMultiPlatformParam
.Uqi
.Value
!= NULL
) {
6432 free (mMultiPlatformParam
.Uqi
.Value
);
6434 if (mMultiPlatformParam
.Uqi
.Data
!= NULL
) {
6435 free (mMultiPlatformParam
.Uqi
.Data
);
6437 while (gEfiFdInfo
.FfsArray
[Index
] != NULL
) {
6438 free (gEfiFdInfo
.FfsArray
[Index
++]);
6441 DestroyAllFormSet (&mFormSetListEntry
);
6442 DestroyAllStorage (&mVarListEntry
);
6443 DestroyAllStorage (&mBfvVarListEntry
);
6444 DestroyAllStorage (&mAllVarListEntry
);
6445 FreeUnidirectionList (mUqiList
);