2 Utility functions for UI presentation.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 BOOLEAN mHiiPackageListUpdated
;
13 UI_MENU_SELECTION
*gCurrentSelection
;
14 EFI_HII_HANDLE mCurrentHiiHandle
= NULL
;
15 EFI_GUID mCurrentFormSetGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
16 UINT16 mCurrentFormId
= 0;
17 EFI_EVENT mValueChangedEvent
= NULL
;
18 LIST_ENTRY mRefreshEventList
= INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList
);
19 UINT16 mCurFakeQestId
;
20 FORM_DISPLAY_ENGINE_FORM gDisplayFormData
;
21 BOOLEAN mFinishRetrieveCall
= FALSE
;
24 Evaluate all expressions in a Form.
26 @param FormSet FormSet this Form belongs to.
29 @retval EFI_SUCCESS The expression evaluated successfuly
33 EvaluateFormExpressions (
34 IN FORM_BROWSER_FORMSET
*FormSet
,
35 IN FORM_BROWSER_FORM
*Form
40 FORM_EXPRESSION
*Expression
;
42 Link
= GetFirstNode (&Form
->ExpressionListHead
);
43 while (!IsNull (&Form
->ExpressionListHead
, Link
)) {
44 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
45 Link
= GetNextNode (&Form
->ExpressionListHead
, Link
);
47 if (Expression
->Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
||
48 Expression
->Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
||
49 Expression
->Type
== EFI_HII_EXPRESSION_WARNING_IF
||
50 Expression
->Type
== EFI_HII_EXPRESSION_WRITE
||
51 (Expression
->Type
== EFI_HII_EXPRESSION_READ
&& Form
->FormType
!= STANDARD_MAP_FORM_TYPE
)) {
53 // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
58 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
59 if (EFI_ERROR (Status
)) {
68 Base on the opcode buffer info to get the display statement.
70 @param OpCode The input opcode buffer for this statement.
72 @retval Statement The statement use this opcode buffer.
75 FORM_DISPLAY_ENGINE_STATEMENT
*
77 IN EFI_IFR_OP_HEADER
*OpCode
80 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
83 Link
= GetFirstNode (&gDisplayFormData
.StatementListHead
);
84 while (!IsNull (&gDisplayFormData
.StatementListHead
, Link
)) {
85 DisplayStatement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
87 if (DisplayStatement
->OpCode
== OpCode
) {
88 return DisplayStatement
;
90 Link
= GetNextNode (&gDisplayFormData
.StatementListHead
, Link
);
97 Free the refresh event list.
106 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
108 while (!IsListEmpty (&mRefreshEventList
)) {
109 Link
= GetFirstNode (&mRefreshEventList
);
110 EventNode
= FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link
);
111 RemoveEntryList (&EventNode
->Link
);
113 gBS
->CloseEvent (EventNode
->RefreshEvent
);
115 FreePool (EventNode
);
120 Check whether this statement value is changed. If yes, update the statement value and return TRUE;
123 @param Statement The statement need to check.
128 IN OUT FORM_BROWSER_STATEMENT
*Statement
131 GetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
134 // Reset FormPackage update flag
136 mHiiPackageListUpdated
= FALSE
;
139 // Question value may be changed, need invoke its Callback()
141 ProcessCallBackFunction (gCurrentSelection
, gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
143 if (mHiiPackageListUpdated
) {
145 // Package list is updated, force to reparse IFR binary of target Formset
147 mHiiPackageListUpdated
= FALSE
;
148 gCurrentSelection
->Action
= UI_ACTION_REFRESH_FORMSET
;
153 Refresh the question which has refresh guid event attribute.
155 @param Event The event which has this function related.
156 @param Context The input context info related to this event or the status code return to the caller.
160 RefreshEventNotifyForStatement(
165 FORM_BROWSER_STATEMENT
*Statement
;
167 Statement
= (FORM_BROWSER_STATEMENT
*)Context
;
168 UpdateStatement(Statement
);
169 gBS
->SignalEvent (mValueChangedEvent
);
173 Refresh the questions within this form.
175 @param Event The event which has this function related.
176 @param Context The input context info related to this event or the status code return to the caller.
180 RefreshEventNotifyForForm(
185 gCurrentSelection
->Action
= UI_ACTION_REFRESH_FORMSET
;
187 gBS
->SignalEvent (mValueChangedEvent
);
191 Create refresh hook event for statement which has refresh event or interval.
193 @param Statement The statement need to check.
197 CreateRefreshEventForStatement (
198 IN FORM_BROWSER_STATEMENT
*Statement
202 EFI_EVENT RefreshEvent
;
203 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
206 // If question has refresh guid, create the notify function.
208 Status
= gBS
->CreateEventEx (
211 RefreshEventNotifyForStatement
,
213 &Statement
->RefreshGuid
,
215 ASSERT_EFI_ERROR (Status
);
217 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
218 ASSERT (EventNode
!= NULL
);
219 EventNode
->RefreshEvent
= RefreshEvent
;
220 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
224 Create refresh hook event for form which has refresh event or interval.
226 @param Form The form need to check.
230 CreateRefreshEventForForm (
231 IN FORM_BROWSER_FORM
*Form
235 EFI_EVENT RefreshEvent
;
236 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
239 // If question has refresh guid, create the notify function.
241 Status
= gBS
->CreateEventEx (
244 RefreshEventNotifyForForm
,
248 ASSERT_EFI_ERROR (Status
);
250 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
251 ASSERT (EventNode
!= NULL
);
252 EventNode
->RefreshEvent
= RefreshEvent
;
253 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
258 Initialize the Display statement structure data.
260 @param DisplayStatement Pointer to the display Statement data strucure.
261 @param Statement The statement need to check.
264 InitializeDisplayStatement (
265 IN OUT FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
,
266 IN FORM_BROWSER_STATEMENT
*Statement
270 QUESTION_OPTION
*Option
;
271 DISPLAY_QUESTION_OPTION
*DisplayOption
;
272 FORM_DISPLAY_ENGINE_STATEMENT
*ParentStatement
;
274 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
275 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
276 DisplayStatement
->OpCode
= Statement
->OpCode
;
277 InitializeListHead (&DisplayStatement
->NestStatementList
);
278 InitializeListHead (&DisplayStatement
->OptionListHead
);
280 if ((EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) == ExpressGrayOut
) || Statement
->Locked
) {
281 DisplayStatement
->Attribute
|= HII_DISPLAY_GRAYOUT
;
283 if ((Statement
->ValueExpression
!= NULL
) || ((Statement
->QuestionFlags
& EFI_IFR_FLAG_READ_ONLY
) != 0)) {
284 DisplayStatement
->Attribute
|= HII_DISPLAY_READONLY
;
288 // Initilize the option list in statement.
290 Link
= GetFirstNode (&Statement
->OptionListHead
);
291 while (!IsNull (&Statement
->OptionListHead
, Link
)) {
292 Option
= QUESTION_OPTION_FROM_LINK (Link
);
293 Link
= GetNextNode (&Statement
->OptionListHead
, Link
);
294 if ((Option
->SuppressExpression
!= NULL
) &&
295 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
299 DisplayOption
= AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION
));
300 ASSERT (DisplayOption
!= NULL
);
302 DisplayOption
->ImageId
= Option
->ImageId
;
303 DisplayOption
->Signature
= DISPLAY_QUESTION_OPTION_SIGNATURE
;
304 DisplayOption
->OptionOpCode
= Option
->OpCode
;
305 InsertTailList(&DisplayStatement
->OptionListHead
, &DisplayOption
->Link
);
308 CopyMem (&DisplayStatement
->CurrentValue
, &Statement
->HiiValue
, sizeof (EFI_HII_VALUE
));
311 // Some special op code need an extra buffer to save the data.
312 // Such as string, password, orderedlist...
314 if (Statement
->BufferValue
!= NULL
) {
316 // Ordered list opcode may not initilized, get default value here.
318 if (Statement
->OpCode
->OpCode
== EFI_IFR_ORDERED_LIST_OP
&& GetArrayData (Statement
->BufferValue
, Statement
->ValueType
, 0) == 0) {
319 GetQuestionDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, 0);
322 DisplayStatement
->CurrentValue
.Buffer
= AllocateCopyPool(Statement
->StorageWidth
,Statement
->BufferValue
);
323 DisplayStatement
->CurrentValue
.BufferLen
= Statement
->StorageWidth
;
326 DisplayStatement
->SettingChangedFlag
= Statement
->ValueChanged
;
329 // Get the highlight statement for current form.
331 if (((gCurrentSelection
->QuestionId
!= 0) && (Statement
->QuestionId
== gCurrentSelection
->QuestionId
)) ||
332 ((mCurFakeQestId
!= 0) && (Statement
->FakeQuestionId
== mCurFakeQestId
))) {
333 gDisplayFormData
.HighLightedStatement
= DisplayStatement
;
337 // Create the refresh event process function.
339 if (!IsZeroGuid (&Statement
->RefreshGuid
)) {
340 CreateRefreshEventForStatement (Statement
);
344 // For RTC type of date/time, set default refresh interval to be 1 second.
346 if ((Statement
->Operand
== EFI_IFR_DATE_OP
|| Statement
->Operand
== EFI_IFR_TIME_OP
) && Statement
->Storage
== NULL
) {
347 Statement
->RefreshInterval
= 1;
351 // Create the refresh guid hook event.
352 // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
354 if ((!IsZeroGuid (&Statement
->RefreshGuid
)) || (Statement
->RefreshInterval
!= 0)) {
355 gDisplayFormData
.FormRefreshEvent
= mValueChangedEvent
;
359 // Save the password check function for later use.
361 if (Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
362 DisplayStatement
->PasswordCheck
= PasswordCheck
;
366 // If this statement is nest in the subtitle, insert to the host statement.
367 // else insert to the form it belongs to.
369 if (Statement
->ParentStatement
!= NULL
) {
370 ParentStatement
= GetDisplayStatement(Statement
->ParentStatement
->OpCode
);
371 ASSERT (ParentStatement
!= NULL
);
372 InsertTailList(&ParentStatement
->NestStatementList
, &DisplayStatement
->DisplayLink
);
374 InsertTailList(&gDisplayFormData
.StatementListHead
, &DisplayStatement
->DisplayLink
);
379 Process for the refresh interval statement.
381 @param Event The Event need to be process
382 @param Context The context of the event.
387 RefreshIntervalProcess (
392 FORM_BROWSER_STATEMENT
*Statement
;
395 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
396 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
397 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
398 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
400 if (Statement
->RefreshInterval
== 0) {
404 UpdateStatement(Statement
);
407 gBS
->SignalEvent (mValueChangedEvent
);
412 Make a copy of the global hotkey info.
420 BROWSER_HOT_KEY
*HotKey
;
421 BROWSER_HOT_KEY
*CopyKey
;
424 Link
= GetFirstNode (&gBrowserHotKeyList
);
425 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
426 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
428 CopyKey
= AllocateCopyPool(sizeof (BROWSER_HOT_KEY
), HotKey
);
429 ASSERT (CopyKey
!= NULL
);
430 CopyKey
->KeyData
= AllocateCopyPool(sizeof (EFI_INPUT_KEY
), HotKey
->KeyData
);
431 ASSERT (CopyKey
->KeyData
!= NULL
);
432 CopyKey
->HelpString
= AllocateCopyPool(StrSize (HotKey
->HelpString
), HotKey
->HelpString
);
433 ASSERT (CopyKey
->HelpString
!= NULL
);
435 InsertTailList(&gDisplayFormData
.HotKeyListHead
, &CopyKey
->Link
);
437 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
443 Get the extra question attribute from override question list.
445 @param QuestionId The question id for this request question.
447 @retval The attribute for this question or NULL if not found this
448 question in the list.
452 ProcessQuestionExtraAttr (
453 IN EFI_QUESTION_ID QuestionId
457 QUESTION_ATTRIBUTE_OVERRIDE
*QuestionDesc
;
460 // Return HII_DISPLAY_NONE if input a invalid question id.
462 if (QuestionId
== 0) {
463 return HII_DISPLAY_NONE
;
466 Link
= GetFirstNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
);
467 while (!IsNull (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
)) {
468 QuestionDesc
= FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link
);
469 Link
= GetNextNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
);
471 if ((QuestionDesc
->QuestionId
== QuestionId
) &&
472 (QuestionDesc
->FormId
== gCurrentSelection
->FormId
) &&
473 (QuestionDesc
->HiiHandle
== gCurrentSelection
->Handle
) &&
474 CompareGuid (&QuestionDesc
->FormSetGuid
, &gCurrentSelection
->FormSetGuid
)) {
475 return QuestionDesc
->Attribute
;
479 return HII_DISPLAY_NONE
;
484 Enum all statement in current form, find all the statement can be display and
485 add to the display form.
489 AddStatementToDisplayForm (
495 FORM_BROWSER_STATEMENT
*Statement
;
496 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
497 UINT8 MinRefreshInterval
;
498 EFI_EVENT RefreshIntervalEvent
;
499 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
500 BOOLEAN FormEditable
;
501 UINT32 ExtraAttribute
;
503 MinRefreshInterval
= 0;
504 FormEditable
= FALSE
;
507 // Process the statement outside the form, these statements are not recognized
510 Link
= GetFirstNode (&gCurrentSelection
->FormSet
->StatementListOSF
);
511 while (!IsNull (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
)) {
512 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
513 Link
= GetNextNode (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
);
515 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
516 ASSERT (DisplayStatement
!= NULL
);
517 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
518 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
519 DisplayStatement
->OpCode
= Statement
->OpCode
;
521 InitializeListHead (&DisplayStatement
->NestStatementList
);
522 InitializeListHead (&DisplayStatement
->OptionListHead
);
524 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
528 // treat formset as statement outside the form,get its opcode.
530 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
531 ASSERT (DisplayStatement
!= NULL
);
533 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
534 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
535 DisplayStatement
->OpCode
= gCurrentSelection
->FormSet
->OpCode
;
537 InitializeListHead (&DisplayStatement
->NestStatementList
);
538 InitializeListHead (&DisplayStatement
->OptionListHead
);
540 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
543 // Process the statement in this form.
545 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
546 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
547 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
548 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
551 // This statement can't be show, skip it.
553 if (EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) > ExpressGrayOut
) {
558 // Check the extra attribute.
560 ExtraAttribute
= ProcessQuestionExtraAttr (Statement
->QuestionId
);
561 if ((ExtraAttribute
& HII_DISPLAY_SUPPRESS
) != 0) {
565 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
566 ASSERT (DisplayStatement
!= NULL
);
569 // Initialize this statement and add it to the display form.
571 InitializeDisplayStatement(DisplayStatement
, Statement
);
574 // Set the extra attribute.
576 DisplayStatement
->Attribute
|= ExtraAttribute
;
578 if (Statement
->Storage
!= NULL
) {
583 // Get the minimal refresh interval value for later use.
585 if ((Statement
->RefreshInterval
!= 0) &&
586 (MinRefreshInterval
== 0 || Statement
->RefreshInterval
< MinRefreshInterval
)) {
587 MinRefreshInterval
= Statement
->RefreshInterval
;
592 // Create the periodic timer for refresh interval statement.
594 if (MinRefreshInterval
!= 0) {
595 Status
= gBS
->CreateEvent (EVT_TIMER
| EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, RefreshIntervalProcess
, NULL
, &RefreshIntervalEvent
);
596 ASSERT_EFI_ERROR (Status
);
597 Status
= gBS
->SetTimer (RefreshIntervalEvent
, TimerPeriodic
, MinRefreshInterval
* ONE_SECOND
);
598 ASSERT_EFI_ERROR (Status
);
600 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
601 ASSERT (EventNode
!= NULL
);
602 EventNode
->RefreshEvent
= RefreshIntervalEvent
;
603 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
607 // Create the refresh event process function for Form.
609 if (!IsZeroGuid (&gCurrentSelection
->Form
->RefreshGuid
)) {
610 CreateRefreshEventForForm (gCurrentSelection
->Form
);
611 if (gDisplayFormData
.FormRefreshEvent
== NULL
) {
612 gDisplayFormData
.FormRefreshEvent
= mValueChangedEvent
;
617 // Update hotkey list field.
619 if (gBrowserSettingScope
== SystemLevel
|| FormEditable
) {
626 Initialize the SettingChangedFlag variable in the display form.
630 UpdateDataChangedFlag (
635 FORM_BROWSER_FORMSET
*LocalFormSet
;
637 gDisplayFormData
.SettingChangedFlag
= FALSE
;
639 if (IsNvUpdateRequiredForForm (gCurrentSelection
->Form
)) {
640 gDisplayFormData
.SettingChangedFlag
= TRUE
;
645 // Base on the system level to check whether need to show the NV flag.
647 switch (gBrowserSettingScope
) {
650 // Check the maintain list to see whether there is any change.
652 Link
= GetFirstNode (&gBrowserFormSetList
);
653 while (!IsNull (&gBrowserFormSetList
, Link
)) {
654 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
655 if (IsNvUpdateRequiredForFormSet(LocalFormSet
)) {
656 gDisplayFormData
.SettingChangedFlag
= TRUE
;
659 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
664 if (IsNvUpdateRequiredForFormSet(gCurrentSelection
->FormSet
)) {
665 gDisplayFormData
.SettingChangedFlag
= TRUE
;
677 Initialize the Display form structure data.
681 InitializeDisplayFormData (
687 gDisplayFormData
.Signature
= FORM_DISPLAY_ENGINE_FORM_SIGNATURE
;
688 gDisplayFormData
.Version
= FORM_DISPLAY_ENGINE_VERSION_1
;
689 gDisplayFormData
.ImageId
= 0;
690 gDisplayFormData
.AnimationId
= 0;
692 InitializeListHead (&gDisplayFormData
.StatementListHead
);
693 InitializeListHead (&gDisplayFormData
.StatementListOSF
);
694 InitializeListHead (&gDisplayFormData
.HotKeyListHead
);
696 Status
= gBS
->CreateEvent (
699 EfiEventEmptyFunction
,
703 ASSERT_EFI_ERROR (Status
);
708 Free the kotkey info saved in form data.
716 BROWSER_HOT_KEY
*HotKey
;
719 while (!IsListEmpty (&gDisplayFormData
.HotKeyListHead
)) {
720 Link
= GetFirstNode (&gDisplayFormData
.HotKeyListHead
);
721 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
723 RemoveEntryList (&HotKey
->Link
);
725 FreePool (HotKey
->KeyData
);
726 FreePool (HotKey
->HelpString
);
733 Update the Display form structure data.
737 UpdateDisplayFormData (
741 gDisplayFormData
.FormTitle
= gCurrentSelection
->Form
->FormTitle
;
742 gDisplayFormData
.FormId
= gCurrentSelection
->FormId
;
743 gDisplayFormData
.HiiHandle
= gCurrentSelection
->Handle
;
744 CopyGuid (&gDisplayFormData
.FormSetGuid
, &gCurrentSelection
->FormSetGuid
);
746 gDisplayFormData
.Attribute
= 0;
747 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->ModalForm
? HII_DISPLAY_MODAL
: 0;
748 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->Locked
? HII_DISPLAY_LOCK
: 0;
750 gDisplayFormData
.FormRefreshEvent
= NULL
;
751 gDisplayFormData
.HighLightedStatement
= NULL
;
753 UpdateDataChangedFlag ();
755 AddStatementToDisplayForm ();
760 Free the Display Statement structure data.
762 @param StatementList Point to the statement list which need to be free.
767 LIST_ENTRY
*StatementList
771 LIST_ENTRY
*OptionLink
;
772 FORM_DISPLAY_ENGINE_STATEMENT
*Statement
;
773 DISPLAY_QUESTION_OPTION
*Option
;
776 // Free Statements/Questions
778 while (!IsListEmpty (StatementList
)) {
779 Link
= GetFirstNode (StatementList
);
780 Statement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
785 while (!IsListEmpty (&Statement
->OptionListHead
)) {
786 OptionLink
= GetFirstNode (&Statement
->OptionListHead
);
787 Option
= DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink
);
788 RemoveEntryList (&Option
->Link
);
793 // Free nest statement List
795 if (!IsListEmpty (&Statement
->NestStatementList
)) {
796 FreeStatementData(&Statement
->NestStatementList
);
799 RemoveEntryList (&Statement
->DisplayLink
);
800 FreePool (Statement
);
806 Free the Display form structure data.
810 FreeDisplayFormData (
814 FreeStatementData (&gDisplayFormData
.StatementListHead
);
815 FreeStatementData (&gDisplayFormData
.StatementListOSF
);
824 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
826 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
828 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
831 FORM_BROWSER_STATEMENT
*
832 GetBrowserStatement (
833 IN FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
836 FORM_BROWSER_STATEMENT
*Statement
;
839 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
840 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
841 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
843 if (Statement
->OpCode
== DisplayStatement
->OpCode
) {
847 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
854 Update the ValueChanged status for questions in this form.
856 @param FormSet FormSet data structure.
857 @param Form Form data structure.
861 UpdateStatementStatusForForm (
862 IN FORM_BROWSER_FORMSET
*FormSet
,
863 IN FORM_BROWSER_FORM
*Form
867 FORM_BROWSER_STATEMENT
*Question
;
869 Link
= GetFirstNode (&Form
->StatementListHead
);
870 while (!IsNull (&Form
->StatementListHead
, Link
)) {
871 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
872 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
875 // For password opcode, not set the the value changed flag.
877 if (Question
->Operand
== EFI_IFR_PASSWORD_OP
) {
881 IsQuestionValueChanged(FormSet
, Form
, Question
, GetSetValueWithBuffer
);
886 Update the ValueChanged status for questions in this formset.
888 @param FormSet FormSet data structure.
892 UpdateStatementStatusForFormSet (
893 IN FORM_BROWSER_FORMSET
*FormSet
897 FORM_BROWSER_FORM
*Form
;
899 Link
= GetFirstNode (&FormSet
->FormListHead
);
900 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
901 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
902 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
904 UpdateStatementStatusForForm (FormSet
, Form
);
909 Update the ValueChanged status for questions.
911 @param FormSet FormSet data structure.
912 @param Form Form data structure.
913 @param SettingScope Setting Scope for Default action.
917 UpdateStatementStatus (
918 IN FORM_BROWSER_FORMSET
*FormSet
,
919 IN FORM_BROWSER_FORM
*Form
,
920 IN BROWSER_SETTING_SCOPE SettingScope
924 FORM_BROWSER_FORMSET
*LocalFormSet
;
926 switch (SettingScope
) {
928 Link
= GetFirstNode (&gBrowserFormSetList
);
929 while (!IsNull (&gBrowserFormSetList
, Link
)) {
930 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
931 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
932 if (!ValidateFormSet(LocalFormSet
)) {
936 UpdateStatementStatusForFormSet (LocalFormSet
);
941 UpdateStatementStatusForFormSet (FormSet
);
945 UpdateStatementStatusForForm (FormSet
, Form
);
955 Process the action request in user input.
957 @param Action The user input action request info.
958 @param DefaultId The user input default Id info.
960 @retval EFI_SUCESSS This function always return successfully for now.
970 // This is caused by use press ESC, and it should not combine with other action type.
972 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
973 FindNextMenu (gCurrentSelection
, FormLevel
);
978 // Below is normal hotkey trigged action, these action maybe combine with each other.
980 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
981 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
984 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
985 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
, FALSE
);
986 UpdateStatementStatus (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
989 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
990 SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
993 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
994 gResetRequiredFormLevel
= TRUE
;
995 gResetRequiredSystemLevel
= TRUE
;
998 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
1000 // Form Exit without saving, Similar to ESC Key.
1001 // FormSet Exit without saving, Exit SendForm.
1002 // System Exit without saving, CallExitHandler and Exit SendForm.
1004 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
1005 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
1006 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
1007 } else if (gBrowserSettingScope
== SystemLevel
) {
1008 if (ExitHandlerFunction
!= NULL
) {
1009 ExitHandlerFunction ();
1011 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
1019 Check whether the formset guid is in this Hii package list.
1021 @param HiiHandle The HiiHandle for this HII package list.
1022 @param FormSetGuid The formset guid for the request formset.
1024 @retval TRUE Find the formset guid.
1025 @retval FALSE Not found the formset guid.
1029 GetFormsetGuidFromHiiHandle (
1030 IN EFI_HII_HANDLE HiiHandle
,
1031 IN EFI_GUID
*FormSetGuid
1034 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
1038 UINT32 PackageListLength
;
1039 EFI_HII_PACKAGE_HEADER PackageHeader
;
1046 HiiPackageList
= NULL
;
1049 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
1050 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1051 HiiPackageList
= AllocatePool (BufferSize
);
1052 ASSERT (HiiPackageList
!= NULL
);
1054 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
1056 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1061 // Get Form package from this HII package List
1063 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1065 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1067 while (Offset
< PackageListLength
) {
1068 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1069 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1070 Offset
+= PackageHeader
.Length
;
1072 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1074 // Search FormSet in this Form Package
1076 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1077 while (Offset2
< PackageHeader
.Length
) {
1078 OpCodeData
= Package
+ Offset2
;
1080 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1081 if (CompareGuid (FormSetGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))){
1087 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1095 FreePool (HiiPackageList
);
1101 Find HII Handle in the HII database associated with given Device Path.
1103 If DevicePath is NULL, then ASSERT.
1105 @param DevicePath Device Path associated with the HII package list
1107 @param FormsetGuid The formset guid for this formset.
1109 @retval Handle HII package list Handle associated with the Device
1111 @retval NULL Hii Package list handle is not found.
1115 DevicePathToHiiHandle (
1116 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1117 IN EFI_GUID
*FormsetGuid
1121 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1124 EFI_HANDLE DriverHandle
;
1125 EFI_HII_HANDLE
*HiiHandles
;
1126 EFI_HII_HANDLE HiiHandle
;
1128 ASSERT (DevicePath
!= NULL
);
1130 TmpDevicePath
= DevicePath
;
1132 // Locate Device Path Protocol handle buffer
1134 Status
= gBS
->LocateDevicePath (
1135 &gEfiDevicePathProtocolGuid
,
1139 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
1144 // Retrieve all HII Handles from HII database
1146 HiiHandles
= HiiGetHiiHandles (NULL
);
1147 if (HiiHandles
== NULL
) {
1152 // Search Hii Handle by Driver Handle
1155 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1156 Status
= mHiiDatabase
->GetPackageListHandle (
1161 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1162 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], FormsetGuid
)) {
1163 HiiHandle
= HiiHandles
[Index
];
1167 if (HiiHandle
!= NULL
) {
1173 FreePool (HiiHandles
);
1178 Find HII Handle in the HII database associated with given form set guid.
1180 If FormSetGuid is NULL, then ASSERT.
1182 @param ComparingGuid FormSet Guid associated with the HII package list
1185 @retval Handle HII package list Handle associated with the Device
1187 @retval NULL Hii Package list handle is not found.
1191 FormSetGuidToHiiHandle (
1192 EFI_GUID
*ComparingGuid
1195 EFI_HII_HANDLE
*HiiHandles
;
1196 EFI_HII_HANDLE HiiHandle
;
1199 ASSERT (ComparingGuid
!= NULL
);
1203 // Get all the Hii handles
1205 HiiHandles
= HiiGetHiiHandles (NULL
);
1206 ASSERT (HiiHandles
!= NULL
);
1209 // Search for formset of each class type
1211 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1212 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], ComparingGuid
)) {
1213 HiiHandle
= HiiHandles
[Index
];
1217 if (HiiHandle
!= NULL
) {
1222 FreePool (HiiHandles
);
1228 check how to process the changed data in current form or form set.
1230 @param Selection On input, Selection tell setup browser the information
1231 about the Selection, form and formset to be displayed.
1232 On output, Selection return the screen item that is selected
1235 @param Scope Data save or discard scope, form or formset.
1237 @retval TRUE Success process the changed data, will return to the parent form.
1238 @retval FALSE Reject to process the changed data, will stay at current form.
1241 ProcessChangedData (
1242 IN OUT UI_MENU_SELECTION
*Selection
,
1243 IN BROWSER_SETTING_SCOPE Scope
1250 switch (mFormDisplay
->ConfirmDataChange()) {
1251 case BROWSER_ACTION_DISCARD
:
1252 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1255 case BROWSER_ACTION_SUBMIT
:
1256 Status
= SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1257 if (EFI_ERROR (Status
)) {
1262 case BROWSER_ACTION_NONE
:
1268 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1278 Find parent formset menu(the first menu which has different formset) for current menu.
1279 If not find, just return to the first menu.
1281 @param Selection The selection info.
1286 IN OUT UI_MENU_SELECTION
*Selection
1289 FORM_ENTRY_INFO
*CurrentMenu
;
1290 FORM_ENTRY_INFO
*ParentMenu
;
1292 CurrentMenu
= Selection
->CurrentMenu
;
1293 ParentMenu
= UiFindParentMenu(CurrentMenu
, FormSetLevel
);
1295 if (ParentMenu
!= NULL
) {
1296 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1297 Selection
->Handle
= ParentMenu
->HiiHandle
;
1298 Selection
->FormId
= ParentMenu
->FormId
;
1299 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1301 Selection
->FormId
= CurrentMenu
->FormId
;
1302 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1305 Selection
->Statement
= NULL
;
1309 Process the goto op code, update the info in the selection structure.
1311 @param Statement The statement belong to goto op code.
1312 @param Selection The selection info.
1314 @retval EFI_SUCCESS The menu process successfully.
1315 @return Other value if the process failed.
1319 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1320 IN OUT UI_MENU_SELECTION
*Selection
1324 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1325 FORM_BROWSER_FORM
*RefForm
;
1327 EFI_HII_HANDLE HiiHandle
;
1329 Status
= EFI_SUCCESS
;
1334 // Prepare the device path check, get the device path info first.
1336 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1337 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1341 // Check whether the device path string is a valid string.
1343 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
&& StringPtr
[0] != L
'\0') {
1344 if (Selection
->Form
->ModalForm
) {
1349 // Goto another Hii Package list
1351 if (mPathFromText
!= NULL
) {
1352 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1353 if (DevicePath
!= NULL
) {
1354 HiiHandle
= DevicePathToHiiHandle (DevicePath
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1355 FreePool (DevicePath
);
1357 FreePool (StringPtr
);
1360 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1362 PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND
, NULL
, NULL
, NULL
);
1363 FreePool (StringPtr
);
1367 if (HiiHandle
!= Selection
->Handle
) {
1369 // Goto another Formset, check for uncommitted data
1371 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1372 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1373 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1379 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1380 Selection
->Handle
= HiiHandle
;
1381 if (Selection
->Handle
== NULL
) {
1383 // If target Hii Handle not found, exit current formset.
1385 FindParentFormSet(Selection
);
1389 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1390 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1391 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1392 } else if (!IsZeroGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
)) {
1393 if (Selection
->Form
->ModalForm
) {
1396 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1398 // Goto another Formset, check for uncommitted data
1400 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1401 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1402 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1408 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1409 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1410 if (Selection
->Handle
== NULL
) {
1412 // If target Hii Handle not found, exit current formset.
1414 FindParentFormSet(Selection
);
1418 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1419 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1420 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1421 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1423 // Goto another Form, check for uncommitted data
1425 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1426 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1427 if (!ProcessChangedData (Selection
, FormLevel
)) {
1433 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1434 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1435 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1437 // Form is suppressed.
1439 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
, NULL
);
1444 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1445 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1446 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1447 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1455 Process Question Config.
1457 @param Selection The UI menu selection.
1458 @param Question The Question to be peocessed.
1460 @retval EFI_SUCCESS Question Config process success.
1461 @retval Other Question Config process fail.
1465 ProcessQuestionConfig (
1466 IN UI_MENU_SELECTION
*Selection
,
1467 IN FORM_BROWSER_STATEMENT
*Question
1474 if (Question
->QuestionConfig
== 0) {
1481 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1482 if (ConfigResp
== NULL
) {
1483 return EFI_NOT_FOUND
;
1484 } else if (ConfigResp
[0] == L
'\0') {
1489 // Send config to Configuration Driver
1491 Status
= mHiiConfigRouting
->RouteConfig (
1502 Process the user input data.
1504 @param UserInput The user input data.
1506 @retval EFI_SUCESSS This function always return successfully for now.
1511 IN USER_INPUT
*UserInput
1515 FORM_BROWSER_STATEMENT
*Statement
;
1517 Status
= EFI_SUCCESS
;
1521 // When Exit from FormDisplay function, one of the below two cases must be true.
1523 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1526 // Remove the last highligh question id, this id will update when show next form.
1528 gCurrentSelection
->QuestionId
= 0;
1529 if (UserInput
->SelectedStatement
!= NULL
){
1530 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1531 ASSERT (Statement
!= NULL
);
1534 // This question is the current user select one,record it and later
1535 // show it as the highlight question.
1537 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1539 // For statement like text, actio, it not has question id.
1540 // So use FakeQuestionId to save the question.
1542 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1543 mCurFakeQestId
= Statement
->FakeQuestionId
;
1550 // First process the Action field in USER_INPUT.
1552 if (UserInput
->Action
!= 0) {
1553 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1554 gCurrentSelection
->Statement
= NULL
;
1556 ASSERT (Statement
!= NULL
);
1557 gCurrentSelection
->Statement
= Statement
;
1558 switch (Statement
->Operand
) {
1559 case EFI_IFR_REF_OP
:
1560 Status
= ProcessGotoOpCode(Statement
, gCurrentSelection
);
1563 case EFI_IFR_ACTION_OP
:
1565 // Process the Config string <ConfigResp>
1567 Status
= ProcessQuestionConfig (gCurrentSelection
, Statement
);
1570 case EFI_IFR_RESET_BUTTON_OP
:
1572 // Reset Question to default value specified by DefaultId
1574 Status
= ExtractDefault (gCurrentSelection
->FormSet
, NULL
, Statement
->DefaultId
, FormSetLevel
, GetDefaultForAll
, NULL
, FALSE
, FALSE
);
1575 UpdateStatementStatus (gCurrentSelection
->FormSet
, NULL
, FormSetLevel
);
1579 switch (Statement
->Operand
) {
1580 case EFI_IFR_STRING_OP
:
1581 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1582 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1583 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1584 FreePool (UserInput
->InputValue
.Buffer
);
1587 case EFI_IFR_PASSWORD_OP
:
1588 if (UserInput
->InputValue
.Buffer
== NULL
) {
1590 // User not input new password, just return.
1595 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1596 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1597 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1598 ZeroMem (UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1599 FreePool (UserInput
->InputValue
.Buffer
);
1601 // Two password match, send it to Configuration Driver
1603 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1604 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1606 // Clean the value after saved it.
1608 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1609 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1611 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1615 case EFI_IFR_ORDERED_LIST_OP
:
1616 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1620 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1632 Display form and wait for user to select one menu option, then return it.
1634 @retval EFI_SUCESSS This function always return successfully for now.
1643 USER_INPUT UserInput
;
1644 FORM_ENTRY_INFO
*CurrentMenu
;
1646 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1649 // Update the menu history data.
1651 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1652 if (CurrentMenu
== NULL
) {
1654 // Current menu not found, add it to the menu tree
1656 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1657 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1658 ASSERT (CurrentMenu
!= NULL
);
1662 // Back up the form view history data for this form.
1664 UiCopyMenuList(&gCurrentSelection
->Form
->FormViewListHead
, &mPrivateData
.FormBrowserEx2
.FormViewHistoryHead
);
1666 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1668 if (gCurrentSelection
->QuestionId
== 0) {
1670 // Highlight not specified, fetch it from cached menu
1672 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1675 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1676 if (EFI_ERROR (Status
)) {
1680 UpdateDisplayFormData ();
1682 ASSERT (gDisplayFormData
.BrowserStatus
== BROWSER_SUCCESS
);
1683 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1684 if (EFI_ERROR (Status
)) {
1685 FreeDisplayFormData();
1689 Status
= ProcessUserInput (&UserInput
);
1690 FreeDisplayFormData();
1695 Functions which are registered to receive notification of
1696 database events have this prototype. The actual event is encoded
1697 in NotifyType. The following table describes how PackageType,
1698 PackageGuid, Handle, and Package are used for each of the
1701 @param PackageType Package type of the notification.
1703 @param PackageGuid If PackageType is
1704 EFI_HII_PACKAGE_TYPE_GUID, then this is
1705 the pointer to the GUID from the Guid
1706 field of EFI_HII_PACKAGE_GUID_HEADER.
1707 Otherwise, it must be NULL.
1709 @param Package Points to the package referred to by the
1710 notification Handle The handle of the package
1711 list which contains the specified package.
1713 @param Handle The HII handle.
1715 @param NotifyType The type of change concerning the
1717 EFI_HII_DATABASE_NOTIFY_TYPE.
1723 IN UINT8 PackageType
,
1724 IN CONST EFI_GUID
*PackageGuid
,
1725 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1726 IN EFI_HII_HANDLE Handle
,
1727 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1730 mHiiPackageListUpdated
= TRUE
;
1736 Update the NV flag info for this form set.
1738 @param FormSet FormSet data structure.
1742 IsNvUpdateRequiredForFormSet (
1743 IN FORM_BROWSER_FORMSET
*FormSet
1747 FORM_BROWSER_FORM
*Form
;
1751 // Not finished question initialization, return FALSE.
1753 if (!FormSet
->QuestionInited
) {
1759 Link
= GetFirstNode (&FormSet
->FormListHead
);
1760 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1761 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1763 RetVal
= IsNvUpdateRequiredForForm(Form
);
1768 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1775 Update the NvUpdateRequired flag for a form.
1777 @param Form Form data structure.
1781 IsNvUpdateRequiredForForm (
1782 IN FORM_BROWSER_FORM
*Form
1786 FORM_BROWSER_STATEMENT
*Statement
;
1788 Link
= GetFirstNode (&Form
->StatementListHead
);
1789 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1790 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1792 if (Statement
->ValueChanged
) {
1796 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1803 Find menu which will show next time.
1805 @param Selection On input, Selection tell setup browser the information
1806 about the Selection, form and formset to be displayed.
1807 On output, Selection return the screen item that is selected
1809 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1810 else, we need to exit current formset.
1812 @retval TRUE Exit current form.
1813 @retval FALSE User press ESC and keep in current form.
1817 IN OUT UI_MENU_SELECTION
*Selection
,
1818 IN BROWSER_SETTING_SCOPE SettingLevel
1821 FORM_ENTRY_INFO
*CurrentMenu
;
1822 FORM_ENTRY_INFO
*ParentMenu
;
1823 BROWSER_SETTING_SCOPE Scope
;
1825 CurrentMenu
= Selection
->CurrentMenu
;
1826 Scope
= FormSetLevel
;
1828 ParentMenu
= UiFindParentMenu(CurrentMenu
, SettingLevel
);
1829 while (ParentMenu
!= NULL
&& !ValidateHiiHandle(ParentMenu
->HiiHandle
)) {
1830 ParentMenu
= UiFindParentMenu(ParentMenu
, SettingLevel
);
1833 if (ParentMenu
!= NULL
) {
1834 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1837 Scope
= FormSetLevel
;
1842 // Form Level Check whether the data is changed.
1844 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1845 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1846 if (!ProcessChangedData(Selection
, gBrowserSettingScope
)) {
1851 if (ParentMenu
!= NULL
) {
1853 // ParentMenu is found. Then, go to it.
1855 if (Scope
== FormLevel
) {
1856 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1858 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1859 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1860 Selection
->Handle
= ParentMenu
->HiiHandle
;
1863 Selection
->Statement
= NULL
;
1865 Selection
->FormId
= ParentMenu
->FormId
;
1866 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1869 // Clear highlight record for this menu
1871 CurrentMenu
->QuestionId
= 0;
1876 // Current in root page, exit the SendForm
1878 Selection
->Action
= UI_ACTION_EXIT
;
1884 Reconnect the controller.
1886 @param DriverHandle The controller handle which need to be reconnect.
1888 @retval TRUE do the reconnect behavior success.
1889 @retval FALSE do the reconnect behavior failed.
1893 ReconnectController (
1894 IN EFI_HANDLE DriverHandle
1899 Status
= gBS
->DisconnectController(DriverHandle
, NULL
, NULL
);
1900 if (!EFI_ERROR (Status
)) {
1901 Status
= gBS
->ConnectController(DriverHandle
, NULL
, NULL
, TRUE
);
1904 return Status
== EFI_SUCCESS
;
1908 Call the call back function for the question and process the return action.
1910 @param Selection On input, Selection tell setup browser the information
1911 about the Selection, form and formset to be displayed.
1912 On output, Selection return the screen item that is selected
1914 @param FormSet The formset this question belong to.
1915 @param Form The form this question belong to.
1916 @param Question The Question which need to call.
1917 @param Action The action request.
1918 @param SkipSaveOrDiscard Whether skip save or discard action.
1920 @retval EFI_SUCCESS The call back function executes successfully.
1921 @return Other value if the call back function failed to execute.
1924 ProcessCallBackFunction (
1925 IN OUT UI_MENU_SELECTION
*Selection
,
1926 IN FORM_BROWSER_FORMSET
*FormSet
,
1927 IN FORM_BROWSER_FORM
*Form
,
1928 IN FORM_BROWSER_STATEMENT
*Question
,
1929 IN EFI_BROWSER_ACTION Action
,
1930 IN BOOLEAN SkipSaveOrDiscard
1934 EFI_STATUS InternalStatus
;
1935 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1936 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1937 EFI_HII_VALUE
*HiiValue
;
1938 EFI_IFR_TYPE_VALUE
*TypeValue
;
1939 FORM_BROWSER_STATEMENT
*Statement
;
1940 BOOLEAN SubmitFormIsRequired
;
1941 BOOLEAN DiscardFormIsRequired
;
1944 BROWSER_SETTING_SCOPE SettingLevel
;
1945 EFI_IFR_TYPE_VALUE BackUpValue
;
1946 UINT8
*BackUpBuffer
;
1949 ConfigAccess
= FormSet
->ConfigAccess
;
1950 SubmitFormIsRequired
= FALSE
;
1951 SettingLevel
= FormSetLevel
;
1952 DiscardFormIsRequired
= FALSE
;
1954 Status
= EFI_SUCCESS
;
1955 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1956 BackUpBuffer
= NULL
;
1958 if (ConfigAccess
== NULL
) {
1962 Link
= GetFirstNode (&Form
->StatementListHead
);
1963 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1964 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1965 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1968 // if Question != NULL, only process the question. Else, process all question in this form.
1970 if ((Question
!= NULL
) && (Statement
!= Question
)) {
1974 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
1979 // Check whether Statement is disabled.
1981 if (Statement
->Expression
!= NULL
) {
1982 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, FormSet
, Form
) == ExpressDisable
) {
1987 HiiValue
= &Statement
->HiiValue
;
1988 TypeValue
= &HiiValue
->Value
;
1989 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1991 // For OrderedList, passing in the value buffer to Callback()
1993 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
1997 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
1999 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
2000 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2001 BackUpBuffer
= AllocateCopyPool(Statement
->StorageWidth
, Statement
->BufferValue
);
2002 ASSERT (BackUpBuffer
!= NULL
);
2004 CopyMem (&BackUpValue
, &HiiValue
->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
2008 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2009 Status
= ConfigAccess
->Callback (
2012 Statement
->QuestionId
,
2017 if (!EFI_ERROR (Status
)) {
2019 // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue
2021 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2022 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2023 ASSERT (NewString
!= NULL
);
2025 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2026 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2027 ZeroMem (Statement
->BufferValue
, Statement
->StorageWidth
);
2028 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2030 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2032 FreePool (NewString
);
2036 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2039 case EFI_BROWSER_ACTION_CHANGED
:
2040 switch (ActionRequest
) {
2041 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2042 DiscardFormIsRequired
= TRUE
;
2043 gResetRequiredFormLevel
= TRUE
;
2044 gResetRequiredSystemLevel
= TRUE
;
2048 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2049 SubmitFormIsRequired
= TRUE
;
2053 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2054 DiscardFormIsRequired
= TRUE
;
2058 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2059 SubmitFormIsRequired
= TRUE
;
2060 SettingLevel
= FormLevel
;
2064 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2065 DiscardFormIsRequired
= TRUE
;
2066 SettingLevel
= FormLevel
;
2070 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2071 SubmitFormIsRequired
= TRUE
;
2072 SettingLevel
= FormLevel
;
2075 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2076 DiscardFormIsRequired
= TRUE
;
2077 SettingLevel
= FormLevel
;
2080 case EFI_BROWSER_ACTION_REQUEST_RECONNECT
:
2081 gCallbackReconnect
= TRUE
;
2089 case EFI_BROWSER_ACTION_CHANGING
:
2091 // Do the question validation.
2093 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2094 if (!EFI_ERROR (Status
)) {
2096 //check whether the question value changed compared with edit buffer before updating edit buffer
2097 // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function
2099 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2101 // According the spec, return value from call back of "changing" and
2102 // "retrieve" should update to the question's temp buffer.
2104 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2108 case EFI_BROWSER_ACTION_RETRIEVE
:
2110 // According the spec, return value from call back of "changing" and
2111 // "retrieve" should update to the question's temp buffer.
2113 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2121 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
2122 // then the browser will use the value passed to Callback() and ignore the
2123 // value returned by Callback().
2125 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
== EFI_UNSUPPORTED
) {
2126 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2127 CopyMem (Statement
->BufferValue
, BackUpBuffer
, Statement
->StorageWidth
);
2129 CopyMem (&HiiValue
->Value
, &BackUpValue
, sizeof (EFI_IFR_TYPE_VALUE
));
2133 // Do the question validation.
2135 InternalStatus
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2136 if (!EFI_ERROR (InternalStatus
)) {
2138 //check whether the question value changed compared with edit buffer before updating edit buffer
2139 // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function
2141 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2142 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2147 // According the spec, return fail from call back of "changing" and
2148 // "retrieve", should restore the question's value.
2150 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
!= EFI_UNSUPPORTED
) {
2151 if (Statement
->Storage
!= NULL
) {
2152 GetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2153 } else if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
2154 ProcessCallBackFunction (Selection
, FormSet
, Form
, Question
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
2158 if (Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2159 GetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2162 if (Status
== EFI_UNSUPPORTED
) {
2164 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2166 Status
= EFI_SUCCESS
;
2170 if (BackUpBuffer
!= NULL
) {
2171 FreePool (BackUpBuffer
);
2175 // If Question != NULL, means just process one question
2176 // and if code reach here means this question has finished
2177 // processing, so just break.
2179 if (Question
!= NULL
) {
2184 if (gCallbackReconnect
&& (EFI_BROWSER_ACTION_CHANGED
== Action
)) {
2186 // Confirm changes with user first.
2188 if (IsNvUpdateRequiredForFormSet(FormSet
)) {
2189 if (BROWSER_ACTION_DISCARD
== PopupErrorMessage(BROWSER_RECONNECT_SAVE_CHANGES
, NULL
, NULL
, NULL
)) {
2190 gCallbackReconnect
= FALSE
;
2191 DiscardFormIsRequired
= TRUE
;
2193 SubmitFormIsRequired
= TRUE
;
2196 PopupErrorMessage(BROWSER_RECONNECT_REQUIRED
, NULL
, NULL
, NULL
);
2200 // Exit current formset before do the reconnect.
2203 SettingLevel
= FormSetLevel
;
2206 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2207 SubmitForm (FormSet
, Form
, SettingLevel
);
2210 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2211 DiscardForm (FormSet
, Form
, SettingLevel
);
2215 FindNextMenu (Selection
, SettingLevel
);
2222 Call the retrieve type call back function for one question to get the initialize data.
2224 This function only used when in the initialize stage, because in this stage, the
2225 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2227 @param ConfigAccess The config access protocol produced by the hii driver.
2228 @param Statement The Question which need to call.
2229 @param FormSet The formset this question belong to.
2231 @retval EFI_SUCCESS The call back function executes successfully.
2232 @return Other value if the call back function failed to execute.
2235 ProcessRetrieveForQuestion (
2236 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2237 IN FORM_BROWSER_STATEMENT
*Statement
,
2238 IN FORM_BROWSER_FORMSET
*FormSet
2242 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2243 EFI_HII_VALUE
*HiiValue
;
2244 EFI_IFR_TYPE_VALUE
*TypeValue
;
2247 Status
= EFI_SUCCESS
;
2248 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2250 if (((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) || ConfigAccess
== NULL
) {
2251 return EFI_UNSUPPORTED
;
2254 HiiValue
= &Statement
->HiiValue
;
2255 TypeValue
= &HiiValue
->Value
;
2256 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2258 // For OrderedList, passing in the value buffer to Callback()
2260 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2263 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2264 Status
= ConfigAccess
->Callback (
2266 EFI_BROWSER_ACTION_RETRIEVE
,
2267 Statement
->QuestionId
,
2272 if (!EFI_ERROR (Status
) && HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2273 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2274 ASSERT (NewString
!= NULL
);
2276 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2277 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2278 ZeroMem (Statement
->BufferValue
, Statement
->StorageWidth
);
2279 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2281 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2283 FreePool (NewString
);
2290 The worker function that send the displays to the screen. On output,
2291 the selection made by user is returned.
2293 @param Selection On input, Selection tell setup browser the information
2294 about the Selection, form and formset to be displayed.
2295 On output, Selection return the screen item that is selected
2298 @retval EFI_SUCCESS The page is displayed successfully.
2299 @return Other value if the page failed to be diplayed.
2304 IN OUT UI_MENU_SELECTION
*Selection
2309 EFI_HANDLE NotifyHandle
;
2310 FORM_BROWSER_STATEMENT
*Statement
;
2311 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2313 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2316 // Register notify for Form package update
2318 Status
= mHiiDatabase
->RegisterPackageNotify (
2320 EFI_HII_PACKAGE_FORMS
,
2323 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2326 if (EFI_ERROR (Status
)) {
2331 // Initialize current settings of Questions in this FormSet
2333 InitializeCurrentSetting (Selection
->FormSet
);
2336 // Initilize Action field.
2338 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2341 // Clean the mCurFakeQestId value is formset refreshed.
2348 // Reset Status to prevent the next break from returning incorrect error status.
2350 Status
= EFI_SUCCESS
;
2353 // IFR is updated, force to reparse the IFR binary
2354 // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and
2355 // EFI_BROWSER_ACTION_RETRIEVE, so code place here.
2357 if (mHiiPackageListUpdated
) {
2358 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2359 mHiiPackageListUpdated
= FALSE
;
2364 // Initialize Selection->Form
2366 if (Selection
->FormId
== 0) {
2368 // Zero FormId indicates display the first Form in a FormSet
2370 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2372 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2373 Selection
->FormId
= Selection
->Form
->FormId
;
2375 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2378 if (Selection
->Form
== NULL
) {
2380 // No Form to display
2382 Status
= EFI_NOT_FOUND
;
2387 // Check Form is suppressed.
2389 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2390 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2392 // Form is suppressed.
2394 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
, NULL
);
2395 Status
= EFI_NOT_FOUND
;
2401 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2402 // for each question with callback flag.
2403 // New form may be the first form, or the different form after another form close.
2405 if (((Selection
->Handle
!= mCurrentHiiHandle
) ||
2406 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2407 (Selection
->FormId
!= mCurrentFormId
))) {
2409 // Update Retrieve flag.
2411 mFinishRetrieveCall
= FALSE
;
2414 // Keep current form information
2416 mCurrentHiiHandle
= Selection
->Handle
;
2417 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2418 mCurrentFormId
= Selection
->FormId
;
2420 if (ConfigAccess
!= NULL
) {
2421 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2422 if (EFI_ERROR (Status
)) {
2427 // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, force to reparse the IFR binary
2429 if (mHiiPackageListUpdated
) {
2430 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2431 mHiiPackageListUpdated
= FALSE
;
2438 // Load Questions' Value for display
2440 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2441 if (EFI_ERROR (Status
)) {
2445 if (!mFinishRetrieveCall
) {
2447 // Finish call RETRIEVE callback for this form.
2449 mFinishRetrieveCall
= TRUE
;
2451 if (ConfigAccess
!= NULL
) {
2452 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
2453 if (EFI_ERROR (Status
)) {
2458 // IFR is updated during callback of open form, force to reparse the IFR binary
2460 if (mHiiPackageListUpdated
) {
2461 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2462 mHiiPackageListUpdated
= FALSE
;
2471 Status
= DisplayForm ();
2472 if (EFI_ERROR (Status
)) {
2477 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2479 Statement
= Selection
->Statement
;
2480 if (Statement
!= NULL
) {
2481 if ((ConfigAccess
!= NULL
) &&
2482 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2483 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2484 Status
= ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2485 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2487 // Process dynamic update ref opcode.
2489 if (!EFI_ERROR (Status
)) {
2490 Status
= ProcessGotoOpCode(Statement
, Selection
);
2494 // Callback return error status or status return from process goto opcode.
2496 if (EFI_ERROR (Status
)) {
2498 // Cross reference will not be taken, restore all essential field
2500 Selection
->Handle
= mCurrentHiiHandle
;
2501 CopyMem (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
, sizeof (EFI_GUID
));
2502 Selection
->FormId
= mCurrentFormId
;
2503 Selection
->QuestionId
= 0;
2504 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2509 if (!EFI_ERROR (Status
) &&
2510 (Statement
->Operand
!= EFI_IFR_REF_OP
) &&
2511 ((Statement
->Storage
== NULL
) || (Statement
->Storage
!= NULL
&& Statement
->ValueChanged
))) {
2513 // Only question value has been changed, browser will trig CHANGED callback.
2515 ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2517 //check whether the question value changed compared with buffer value
2518 //if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen
2520 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2524 // Do the question validation.
2526 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2527 if (!EFI_ERROR (Status
) && (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2528 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2530 // Verify whether question value has checked, update the ValueChanged flag in Question.
2532 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2537 // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage
2538 // and process question success till here, trig the gResetFlag/gFlagReconnect.
2540 if ((Status
== EFI_SUCCESS
) &&
2541 (Statement
->Storage
== NULL
)) {
2542 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RESET_REQUIRED
) != 0) {
2543 gResetRequiredFormLevel
= TRUE
;
2544 gResetRequiredSystemLevel
= TRUE
;
2547 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RECONNECT_REQUIRED
) != 0) {
2548 gFlagReconnect
= TRUE
;
2554 // Check whether Exit flag is TRUE.
2556 if (gExitRequired
) {
2557 switch (gBrowserSettingScope
) {
2559 Selection
->Action
= UI_ACTION_EXIT
;
2564 FindNextMenu (Selection
, gBrowserSettingScope
);
2571 gExitRequired
= FALSE
;
2575 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2576 // for each question with callback flag.
2578 if ((ConfigAccess
!= NULL
) &&
2579 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2580 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2581 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2582 (Selection
->FormId
!= mCurrentFormId
))) {
2584 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2585 if (EFI_ERROR (Status
)) {
2589 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2593 // Reset current form information to the initial setting when error happens or form exit.
2595 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2596 mCurrentHiiHandle
= NULL
;
2597 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2602 // Unregister notify for Form package update
2604 mHiiDatabase
->UnregisterPackageNotify (