2 Utility functions for UI presentation.
4 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 BOOLEAN mHiiPackageListUpdated
;
18 UI_MENU_SELECTION
*gCurrentSelection
;
19 EFI_HII_HANDLE mCurrentHiiHandle
= NULL
;
20 EFI_GUID mCurrentFormSetGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
21 UINT16 mCurrentFormId
= 0;
22 EFI_EVENT mValueChangedEvent
= NULL
;
23 LIST_ENTRY mRefreshEventList
= INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList
);
24 UINT32 gBrowserStatus
= BROWSER_SUCCESS
;
26 UINT16 mCurFakeQestId
;
27 FORM_DISPLAY_ENGINE_FORM gDisplayFormData
;
30 Evaluate all expressions in a Form.
32 @param FormSet FormSet this Form belongs to.
35 @retval EFI_SUCCESS The expression evaluated successfuly
39 EvaluateFormExpressions (
40 IN FORM_BROWSER_FORMSET
*FormSet
,
41 IN FORM_BROWSER_FORM
*Form
46 FORM_EXPRESSION
*Expression
;
48 Link
= GetFirstNode (&Form
->ExpressionListHead
);
49 while (!IsNull (&Form
->ExpressionListHead
, Link
)) {
50 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
51 Link
= GetNextNode (&Form
->ExpressionListHead
, Link
);
53 if (Expression
->Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
||
54 Expression
->Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
||
55 Expression
->Type
== EFI_HII_EXPRESSION_WARNING_IF
||
56 Expression
->Type
== EFI_HII_EXPRESSION_WRITE
||
57 (Expression
->Type
== EFI_HII_EXPRESSION_READ
&& Form
->FormType
!= STANDARD_MAP_FORM_TYPE
)) {
59 // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
64 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
65 if (EFI_ERROR (Status
)) {
74 Add empty function for event process function.
76 @param Event The Event need to be process
77 @param Context The context of the event.
82 SetupBrowserEmptyFunction (
90 Base on the opcode buffer info to get the display statement.
92 @param OpCode The input opcode buffer for this statement.
94 @retval Statement The statement use this opcode buffer.
97 FORM_DISPLAY_ENGINE_STATEMENT
*
99 IN EFI_IFR_OP_HEADER
*OpCode
102 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
105 Link
= GetFirstNode (&gDisplayFormData
.StatementListHead
);
106 while (!IsNull (&gDisplayFormData
.StatementListHead
, Link
)) {
107 DisplayStatement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
109 if (DisplayStatement
->OpCode
== OpCode
) {
110 return DisplayStatement
;
112 Link
= GetNextNode (&gDisplayFormData
.StatementListHead
, Link
);
119 Free the refresh event list.
128 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
130 while (!IsListEmpty (&mRefreshEventList
)) {
131 Link
= GetFirstNode (&mRefreshEventList
);
132 EventNode
= FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link
);
133 RemoveEntryList (&EventNode
->Link
);
135 gBS
->CloseEvent (EventNode
->RefreshEvent
);
137 FreePool (EventNode
);
142 Check whether this statement value is changed. If yes, update the statement value and return TRUE;
145 @param Statement The statement need to check.
150 IN OUT FORM_BROWSER_STATEMENT
*Statement
153 GetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
156 // Reset FormPackage update flag
158 mHiiPackageListUpdated
= FALSE
;
161 // Question value may be changed, need invoke its Callback()
163 ProcessCallBackFunction (gCurrentSelection
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
165 if (mHiiPackageListUpdated
) {
167 // Package list is updated, force to reparse IFR binary of target Formset
169 mHiiPackageListUpdated
= FALSE
;
170 gCurrentSelection
->Action
= UI_ACTION_REFRESH_FORMSET
;
175 Refresh the question which has refresh guid event attribute.
177 @param Event The event which has this function related.
178 @param Context The input context info related to this event or the status code return to the caller.
187 FORM_BROWSER_STATEMENT
*Statement
;
189 Statement
= (FORM_BROWSER_STATEMENT
*)Context
;
190 UpdateStatement(Statement
);
191 gBS
->SignalEvent (mValueChangedEvent
);
196 Create refresh hook event for statement which has refresh event or interval.
198 @param Statement The statement need to check.
203 IN FORM_BROWSER_STATEMENT
*Statement
207 EFI_EVENT RefreshEvent
;
208 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
211 // If question has refresh guid, create the notify function.
213 Status
= gBS
->CreateEventEx (
218 &Statement
->RefreshGuid
,
220 ASSERT_EFI_ERROR (Status
);
222 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
223 ASSERT (EventNode
!= NULL
);
224 EventNode
->RefreshEvent
= RefreshEvent
;
225 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
229 Perform value check for a question.
231 @param Question The question need to do check.
232 @param Type Condition type need to check.
233 @param ErrorInfo Return info about the error.
235 @retval The check result.
239 IN FORM_BROWSER_STATEMENT
*Question
,
241 OUT STATEMENT_ERROR_INFO
*ErrorInfo
246 FORM_EXPRESSION
*Expression
;
247 LIST_ENTRY
*ListHead
;
250 RetVal
= STATEMENT_VALID
;
254 case EFI_HII_EXPRESSION_INCONSISTENT_IF
:
255 ListHead
= &Question
->InconsistentListHead
;
258 case EFI_HII_EXPRESSION_WARNING_IF
:
259 ListHead
= &Question
->WarningListHead
;
267 ASSERT (ListHead
!= NULL
);
268 Link
= GetFirstNode (ListHead
);
269 while (!IsNull (ListHead
, Link
)) {
270 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
271 Link
= GetNextNode (ListHead
, Link
);
274 // Evaluate the expression
276 Status
= EvaluateExpression (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Expression
);
277 if (EFI_ERROR (Status
)) {
281 if ((Expression
->Result
.Type
== EFI_IFR_TYPE_BOOLEAN
) && Expression
->Result
.Value
.b
) {
282 ErrorInfo
->StringId
= Expression
->Error
;
284 case EFI_HII_EXPRESSION_INCONSISTENT_IF
:
285 ErrorInfo
->TimeOut
= 0;
286 RetVal
= INCOSISTENT_IF_TRUE
;
289 case EFI_HII_EXPRESSION_WARNING_IF
:
290 ErrorInfo
->TimeOut
= Expression
->TimeOut
;
291 RetVal
= WARNING_IF_TRUE
;
306 Perform value check for a question.
308 @param Form Form where Statement is in.
309 @param Statement Value will check for it.
310 @param InputValue New value will be checked.
311 @param ErrorInfo Return the error info for this check.
313 @retval TRUE Input Value is valid.
314 @retval FALSE Input Value is invalid.
319 IN FORM_DISPLAY_ENGINE_FORM
*Form
,
320 IN FORM_DISPLAY_ENGINE_STATEMENT
*Statement
,
321 IN EFI_HII_VALUE
*InputValue
,
322 OUT STATEMENT_ERROR_INFO
*ErrorInfo
325 FORM_BROWSER_STATEMENT
*Question
;
326 EFI_HII_VALUE BackUpValue
;
331 RetVal
= STATEMENT_VALID
;
333 ASSERT (Form
!= NULL
&& Statement
!= NULL
&& InputValue
!= NULL
&& ErrorInfo
!= NULL
);
335 Question
= GetBrowserStatement(Statement
);
336 ASSERT (Question
!= NULL
);
339 // Back up the quesion value.
341 switch (Question
->Operand
) {
342 case EFI_IFR_ORDERED_LIST_OP
:
343 BackUpBuffer
= AllocateCopyPool (Question
->StorageWidth
, Question
->BufferValue
);
344 ASSERT (BackUpBuffer
!= NULL
);
345 CopyMem (Question
->BufferValue
, InputValue
->Buffer
, Question
->StorageWidth
);
349 CopyMem (&BackUpValue
, &Question
->HiiValue
, sizeof (EFI_HII_VALUE
));
350 CopyMem (&Question
->HiiValue
, InputValue
, sizeof (EFI_HII_VALUE
));
355 // Do the inconsistentif check.
357 if (!IsListEmpty (&Question
->InconsistentListHead
)) {
358 RetVal
= ConditionCheck(Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
, ErrorInfo
);
362 // Do the warningif check.
364 if (RetVal
== STATEMENT_VALID
&& !IsListEmpty (&Question
->WarningListHead
)) {
365 RetVal
= ConditionCheck(Question
, EFI_HII_EXPRESSION_WARNING_IF
, ErrorInfo
);
369 // Restore the quesion value.
371 switch (Question
->Operand
) {
372 case EFI_IFR_ORDERED_LIST_OP
:
373 CopyMem (Question
->BufferValue
, BackUpBuffer
, Question
->StorageWidth
);
377 CopyMem (&Question
->HiiValue
, &BackUpValue
, sizeof (EFI_HII_VALUE
));
386 Initialize the Display statement structure data.
388 @param DisplayStatement Pointer to the display Statement data strucure.
389 @param Statement The statement need to check.
390 @param HostDisplayStatement Pointer to the display Statement data strucure which is an host statement.
393 InitializeDisplayStatement (
394 IN OUT FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
,
395 IN FORM_BROWSER_STATEMENT
*Statement
,
396 IN FORM_DISPLAY_ENGINE_STATEMENT
*HostDisplayStatement
400 QUESTION_OPTION
*Option
;
401 DISPLAY_QUESTION_OPTION
*DisplayOption
;
403 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
404 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
405 DisplayStatement
->OpCode
= Statement
->OpCode
;
406 InitializeListHead (&DisplayStatement
->NestStatementList
);
407 InitializeListHead (&DisplayStatement
->OptionListHead
);
409 if ((EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) == ExpressGrayOut
) || Statement
->Locked
) {
410 DisplayStatement
->Attribute
|= HII_DISPLAY_GRAYOUT
;
412 if ((Statement
->ValueExpression
!= NULL
) || ((Statement
->QuestionFlags
& EFI_IFR_FLAG_READ_ONLY
) != 0)) {
413 DisplayStatement
->Attribute
|= HII_DISPLAY_READONLY
;
417 // Initilize the option list in statement.
419 Link
= GetFirstNode (&Statement
->OptionListHead
);
420 while (!IsNull (&Statement
->OptionListHead
, Link
)) {
421 Option
= QUESTION_OPTION_FROM_LINK (Link
);
422 Link
= GetNextNode (&Statement
->OptionListHead
, Link
);
423 if ((Option
->SuppressExpression
!= NULL
) &&
424 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
428 DisplayOption
= AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION
));
429 ASSERT (DisplayOption
!= NULL
);
431 DisplayOption
->ImageId
= Option
->ImageId
;
432 DisplayOption
->Signature
= DISPLAY_QUESTION_OPTION_SIGNATURE
;
433 DisplayOption
->OptionOpCode
= Option
->OpCode
;
434 InsertTailList(&DisplayStatement
->OptionListHead
, &DisplayOption
->Link
);
437 CopyMem (&DisplayStatement
->CurrentValue
, &Statement
->HiiValue
, sizeof (EFI_HII_VALUE
));
440 // Some special op code need an extra buffer to save the data.
441 // Such as string, password, orderedlist...
443 if (Statement
->BufferValue
!= NULL
) {
445 // Ordered list opcode may not initilized, get default value here.
447 if (Statement
->OpCode
->OpCode
== EFI_IFR_ORDERED_LIST_OP
&& GetArrayData (Statement
->BufferValue
, Statement
->ValueType
, 0) == 0) {
448 GetQuestionDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, 0);
451 DisplayStatement
->CurrentValue
.Buffer
= AllocateCopyPool(Statement
->StorageWidth
,Statement
->BufferValue
);
452 DisplayStatement
->CurrentValue
.BufferLen
= Statement
->StorageWidth
;
455 DisplayStatement
->SettingChangedFlag
= Statement
->ValueChanged
;
458 // Get the highlight statement for current form.
460 if (((gCurrentSelection
->QuestionId
!= 0) && (Statement
->QuestionId
== gCurrentSelection
->QuestionId
)) ||
461 ((mCurFakeQestId
!= 0) && (Statement
->FakeQuestionId
== mCurFakeQestId
))) {
462 gDisplayFormData
.HighLightedStatement
= DisplayStatement
;
466 // Create the refresh event process function.
468 if (!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) {
469 CreateRefreshEvent (Statement
);
473 // For RTC type of date/time, set default refresh interval to be 1 second.
475 if ((Statement
->Operand
== EFI_IFR_DATE_OP
|| Statement
->Operand
== EFI_IFR_TIME_OP
) && Statement
->Storage
== NULL
) {
476 Statement
->RefreshInterval
= 1;
480 // Create the refresh guid hook event.
481 // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
483 if ((!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) || (Statement
->RefreshInterval
!= 0)) {
484 gDisplayFormData
.FormRefreshEvent
= mValueChangedEvent
;
488 // Save the password check function for later use.
490 if (Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
491 DisplayStatement
->PasswordCheck
= PasswordCheck
;
495 // Save the validate check question for later use.
497 if (!IsListEmpty (&Statement
->InconsistentListHead
) || !IsListEmpty (&Statement
->WarningListHead
)) {
498 DisplayStatement
->ValidateQuestion
= QuestionCheck
;
502 // If this statement is nest in the subtitle, insert to the host statement.
503 // else insert to the form it belongs to.
505 if (Statement
->InSubtitle
) {
506 InsertTailList(&HostDisplayStatement
->NestStatementList
, &DisplayStatement
->DisplayLink
);
508 InsertTailList(&gDisplayFormData
.StatementListHead
, &DisplayStatement
->DisplayLink
);
513 Process for the refresh interval statement.
515 @param Event The Event need to be process
516 @param Context The context of the event.
521 RefreshIntervalProcess (
526 FORM_BROWSER_STATEMENT
*Statement
;
529 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
530 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
531 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
532 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
534 if (Statement
->RefreshInterval
== 0) {
538 UpdateStatement(Statement
);
541 gBS
->SignalEvent (mValueChangedEvent
);
546 Make a copy of the global hotkey info.
554 BROWSER_HOT_KEY
*HotKey
;
555 BROWSER_HOT_KEY
*CopyKey
;
558 Link
= GetFirstNode (&gBrowserHotKeyList
);
559 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
560 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
562 CopyKey
= AllocateCopyPool(sizeof (BROWSER_HOT_KEY
), HotKey
);
563 CopyKey
->KeyData
= AllocateCopyPool(sizeof (EFI_INPUT_KEY
), HotKey
->KeyData
);
564 CopyKey
->HelpString
= AllocateCopyPool(StrSize (HotKey
->HelpString
), HotKey
->HelpString
);
566 InsertTailList(&gDisplayFormData
.HotKeyListHead
, &CopyKey
->Link
);
568 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
574 Enum all statement in current form, find all the statement can be display and
575 add to the display form.
579 AddStatementToDisplayForm (
585 FORM_BROWSER_STATEMENT
*Statement
;
586 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
587 FORM_DISPLAY_ENGINE_STATEMENT
*HostDisplayStatement
;
588 UINT8 MinRefreshInterval
;
589 EFI_EVENT RefreshIntervalEvent
;
590 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
591 BOOLEAN FormEditable
;
593 HostDisplayStatement
= NULL
;
594 MinRefreshInterval
= 0;
595 FormEditable
= FALSE
;
598 // Process the statement outside the form, these statements are not recognized
601 Link
= GetFirstNode (&gCurrentSelection
->FormSet
->StatementListOSF
);
602 while (!IsNull (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
)) {
603 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
604 Link
= GetNextNode (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
);
606 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
607 ASSERT (DisplayStatement
!= NULL
);
608 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
609 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
610 DisplayStatement
->OpCode
= Statement
->OpCode
;
612 InitializeListHead (&DisplayStatement
->NestStatementList
);
613 InitializeListHead (&DisplayStatement
->OptionListHead
);
615 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
619 // Process the statement in this form.
621 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
622 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
623 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
624 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
627 // This statement can't be show, skip it.
629 if (EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) > ExpressGrayOut
) {
633 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
634 ASSERT (DisplayStatement
!= NULL
);
637 // Initialize this statement and add it to the display form.
639 InitializeDisplayStatement(DisplayStatement
, Statement
, HostDisplayStatement
);
642 // Save the Host statement info.
643 // Host statement may has nest statement follow it.
645 if (!Statement
->InSubtitle
) {
646 HostDisplayStatement
= DisplayStatement
;
649 if (Statement
->Storage
!= NULL
) {
654 // Get the minimal refresh interval value for later use.
656 if ((Statement
->RefreshInterval
!= 0) &&
657 (MinRefreshInterval
== 0 || Statement
->RefreshInterval
< MinRefreshInterval
)) {
658 MinRefreshInterval
= Statement
->RefreshInterval
;
663 // Create the periodic timer for refresh interval statement.
665 if (MinRefreshInterval
!= 0) {
666 Status
= gBS
->CreateEvent (EVT_TIMER
| EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, RefreshIntervalProcess
, NULL
, &RefreshIntervalEvent
);
667 ASSERT_EFI_ERROR (Status
);
668 Status
= gBS
->SetTimer (RefreshIntervalEvent
, TimerPeriodic
, MinRefreshInterval
* ONE_SECOND
);
669 ASSERT_EFI_ERROR (Status
);
671 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
672 ASSERT (EventNode
!= NULL
);
673 EventNode
->RefreshEvent
= RefreshIntervalEvent
;
674 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
678 // Update hotkey list field.
680 if (gBrowserSettingScope
== SystemLevel
|| FormEditable
) {
687 Initialize the SettingChangedFlag variable in the display form.
691 UpdateDataChangedFlag (
696 FORM_BROWSER_FORMSET
*LocalFormSet
;
698 gDisplayFormData
.SettingChangedFlag
= FALSE
;
700 if (IsNvUpdateRequiredForForm (gCurrentSelection
->Form
)) {
701 gDisplayFormData
.SettingChangedFlag
= TRUE
;
706 // Base on the system level to check whether need to show the NV flag.
708 switch (gBrowserSettingScope
) {
711 // Check the maintain list to see whether there is any change.
713 Link
= GetFirstNode (&gBrowserFormSetList
);
714 while (!IsNull (&gBrowserFormSetList
, Link
)) {
715 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
716 if (IsNvUpdateRequiredForFormSet(LocalFormSet
)) {
717 gDisplayFormData
.SettingChangedFlag
= TRUE
;
720 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
725 if (IsNvUpdateRequiredForFormSet(gCurrentSelection
->FormSet
)) {
726 gDisplayFormData
.SettingChangedFlag
= TRUE
;
738 Initialize the Display form structure data.
742 InitializeDisplayFormData (
748 gDisplayFormData
.Signature
= FORM_DISPLAY_ENGINE_FORM_SIGNATURE
;
749 gDisplayFormData
.Version
= FORM_DISPLAY_ENGINE_VERSION_1
;
750 gDisplayFormData
.ImageId
= 0;
751 gDisplayFormData
.AnimationId
= 0;
753 InitializeListHead (&gDisplayFormData
.StatementListHead
);
754 InitializeListHead (&gDisplayFormData
.StatementListOSF
);
755 InitializeListHead (&gDisplayFormData
.HotKeyListHead
);
757 Status
= gBS
->CreateEvent (
760 SetupBrowserEmptyFunction
,
764 ASSERT_EFI_ERROR (Status
);
769 Free the kotkey info saved in form data.
777 BROWSER_HOT_KEY
*HotKey
;
780 while (!IsListEmpty (&gDisplayFormData
.HotKeyListHead
)) {
781 Link
= GetFirstNode (&gDisplayFormData
.HotKeyListHead
);
782 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
784 RemoveEntryList (&HotKey
->Link
);
786 FreePool (HotKey
->KeyData
);
787 FreePool (HotKey
->HelpString
);
794 Update the Display form structure data.
798 UpdateDisplayFormData (
802 gDisplayFormData
.FormTitle
= gCurrentSelection
->Form
->FormTitle
;
803 gDisplayFormData
.FormId
= gCurrentSelection
->FormId
;
804 gDisplayFormData
.HiiHandle
= gCurrentSelection
->Handle
;
805 CopyGuid (&gDisplayFormData
.FormSetGuid
, &gCurrentSelection
->FormSetGuid
);
807 gDisplayFormData
.Attribute
= 0;
808 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->ModalForm
? HII_DISPLAY_MODAL
: 0;
809 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->Locked
? HII_DISPLAY_LOCK
: 0;
811 gDisplayFormData
.FormRefreshEvent
= NULL
;
812 gDisplayFormData
.HighLightedStatement
= NULL
;
814 gDisplayFormData
.BrowserStatus
= gBrowserStatus
;
815 gDisplayFormData
.ErrorString
= gErrorInfo
;
817 gBrowserStatus
= BROWSER_SUCCESS
;
820 UpdateDataChangedFlag ();
822 AddStatementToDisplayForm ();
827 Free the Display Statement structure data.
829 @param StatementList Point to the statement list which need to be free.
834 LIST_ENTRY
*StatementList
838 LIST_ENTRY
*OptionLink
;
839 FORM_DISPLAY_ENGINE_STATEMENT
*Statement
;
840 DISPLAY_QUESTION_OPTION
*Option
;
843 // Free Statements/Questions
845 while (!IsListEmpty (StatementList
)) {
846 Link
= GetFirstNode (StatementList
);
847 Statement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
852 while (!IsListEmpty (&Statement
->OptionListHead
)) {
853 OptionLink
= GetFirstNode (&Statement
->OptionListHead
);
854 Option
= DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink
);
855 RemoveEntryList (&Option
->Link
);
860 // Free nest statement List
862 if (!IsListEmpty (&Statement
->NestStatementList
)) {
863 FreeStatementData(&Statement
->NestStatementList
);
866 RemoveEntryList (&Statement
->DisplayLink
);
867 FreePool (Statement
);
873 Free the Display form structure data.
877 FreeDisplayFormData (
881 FreeStatementData (&gDisplayFormData
.StatementListHead
);
882 FreeStatementData (&gDisplayFormData
.StatementListOSF
);
891 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
893 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
895 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
898 FORM_BROWSER_STATEMENT
*
899 GetBrowserStatement (
900 IN FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
903 FORM_BROWSER_STATEMENT
*Statement
;
906 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
907 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
908 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
910 if (Statement
->OpCode
== DisplayStatement
->OpCode
) {
914 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
922 Process the action request in user input.
924 @param Action The user input action request info.
925 @param DefaultId The user input default Id info.
927 @retval EFI_SUCESSS This function always return successfully for now.
939 // This is caused by use press ESC, and it should not combine with other action type.
941 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
942 FindNextMenu (gCurrentSelection
, FormLevel
);
947 // Below is normal hotkey trigged action, these action maybe combine with each other.
949 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
950 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
953 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
954 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
);
957 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
958 Status
= SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
959 if (EFI_ERROR (Status
)) {
960 gBrowserStatus
= BROWSER_SUBMIT_FAIL
;
964 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
965 gResetRequired
= TRUE
;
968 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
970 // Form Exit without saving, Similar to ESC Key.
971 // FormSet Exit without saving, Exit SendForm.
972 // System Exit without saving, CallExitHandler and Exit SendForm.
974 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
975 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
976 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
977 } else if (gBrowserSettingScope
== SystemLevel
) {
978 if (ExitHandlerFunction
!= NULL
) {
979 ExitHandlerFunction ();
981 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
990 Find HII Handle in the HII database associated with given Device Path.
992 If DevicePath is NULL, then ASSERT.
994 @param DevicePath Device Path associated with the HII package list
997 @retval Handle HII package list Handle associated with the Device
999 @retval NULL Hii Package list handle is not found.
1004 DevicePathToHiiHandle (
1005 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1009 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1014 EFI_HANDLE DriverHandle
;
1015 EFI_HII_HANDLE
*HiiHandles
;
1016 EFI_HII_HANDLE HiiHandle
;
1018 ASSERT (DevicePath
!= NULL
);
1020 TmpDevicePath
= DevicePath
;
1022 // Locate Device Path Protocol handle buffer
1024 Status
= gBS
->LocateDevicePath (
1025 &gEfiDevicePathProtocolGuid
,
1029 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
1034 // Retrieve all HII Handles from HII database
1036 BufferSize
= 0x1000;
1037 HiiHandles
= AllocatePool (BufferSize
);
1038 ASSERT (HiiHandles
!= NULL
);
1039 Status
= mHiiDatabase
->ListPackageLists (
1041 EFI_HII_PACKAGE_TYPE_ALL
,
1046 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1047 FreePool (HiiHandles
);
1048 HiiHandles
= AllocatePool (BufferSize
);
1049 ASSERT (HiiHandles
!= NULL
);
1051 Status
= mHiiDatabase
->ListPackageLists (
1053 EFI_HII_PACKAGE_TYPE_ALL
,
1060 if (EFI_ERROR (Status
)) {
1061 FreePool (HiiHandles
);
1066 // Search Hii Handle by Driver Handle
1069 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
1070 for (Index
= 0; Index
< HandleCount
; Index
++) {
1071 Status
= mHiiDatabase
->GetPackageListHandle (
1076 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1077 HiiHandle
= HiiHandles
[Index
];
1082 FreePool (HiiHandles
);
1087 Find HII Handle in the HII database associated with given form set guid.
1089 If FormSetGuid is NULL, then ASSERT.
1091 @param ComparingGuid FormSet Guid associated with the HII package list
1094 @retval Handle HII package list Handle associated with the Device
1096 @retval NULL Hii Package list handle is not found.
1100 FormSetGuidToHiiHandle (
1101 EFI_GUID
*ComparingGuid
1104 EFI_HII_HANDLE
*HiiHandles
;
1106 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
1110 UINT32 PackageListLength
;
1111 EFI_HII_PACKAGE_HEADER PackageHeader
;
1115 EFI_HII_HANDLE HiiHandle
;
1117 ASSERT (ComparingGuid
!= NULL
);
1121 // Get all the Hii handles
1123 HiiHandles
= HiiGetHiiHandles (NULL
);
1124 ASSERT (HiiHandles
!= NULL
);
1127 // Search for formset of each class type
1129 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1131 HiiPackageList
= NULL
;
1132 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandles
[Index
], &BufferSize
, HiiPackageList
);
1133 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1134 HiiPackageList
= AllocatePool (BufferSize
);
1135 ASSERT (HiiPackageList
!= NULL
);
1137 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandles
[Index
], &BufferSize
, HiiPackageList
);
1139 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1144 // Get Form package from this HII package List
1146 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1148 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1150 while (Offset
< PackageListLength
) {
1151 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1152 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1154 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1156 // Search FormSet in this Form Package
1158 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1159 while (Offset2
< PackageHeader
.Length
) {
1160 OpCodeData
= Package
+ Offset2
;
1162 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1164 // Try to compare against formset GUID
1166 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1167 HiiHandle
= HiiHandles
[Index
];
1172 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1175 if (HiiHandle
!= NULL
) {
1178 Offset
+= PackageHeader
.Length
;
1181 FreePool (HiiPackageList
);
1182 if (HiiHandle
!= NULL
) {
1187 FreePool (HiiHandles
);
1193 check how to process the changed data in current form or form set.
1195 @param Selection On input, Selection tell setup browser the information
1196 about the Selection, form and formset to be displayed.
1197 On output, Selection return the screen item that is selected
1200 @param Scope Data save or discard scope, form or formset.
1202 @retval TRUE Success process the changed data, will return to the parent form.
1203 @retval FALSE Reject to process the changed data, will stay at current form.
1206 ProcessChangedData (
1207 IN OUT UI_MENU_SELECTION
*Selection
,
1208 IN BROWSER_SETTING_SCOPE Scope
1214 switch (mFormDisplay
->ConfirmDataChange()) {
1215 case BROWSER_ACTION_DISCARD
:
1216 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1219 case BROWSER_ACTION_SUBMIT
:
1220 SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1223 case BROWSER_ACTION_NONE
:
1229 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1239 Find parent formset menu(the first menu which has different formset) for current menu.
1240 If not find, just return to the first menu.
1242 @param Selection The selection info.
1247 IN OUT UI_MENU_SELECTION
*Selection
1250 FORM_ENTRY_INFO
*CurrentMenu
;
1251 FORM_ENTRY_INFO
*ParentMenu
;
1253 CurrentMenu
= Selection
->CurrentMenu
;
1254 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1257 // Find a menu which has different formset guid with current.
1259 while (ParentMenu
!= NULL
&& CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1260 CurrentMenu
= ParentMenu
;
1261 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1264 if (ParentMenu
!= NULL
) {
1265 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1266 Selection
->Handle
= ParentMenu
->HiiHandle
;
1267 Selection
->FormId
= ParentMenu
->FormId
;
1268 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1270 Selection
->FormId
= CurrentMenu
->FormId
;
1271 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1274 Selection
->Statement
= NULL
;
1278 Process the goto op code, update the info in the selection structure.
1280 @param Statement The statement belong to goto op code.
1281 @param Selection The selection info.
1283 @retval EFI_SUCCESS The menu process successfully.
1284 @return Other value if the process failed.
1288 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1289 IN OUT UI_MENU_SELECTION
*Selection
1293 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1294 FORM_BROWSER_FORM
*RefForm
;
1296 EFI_HII_HANDLE HiiHandle
;
1298 Status
= EFI_SUCCESS
;
1303 // Prepare the device path check, get the device path info first.
1305 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1306 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1310 // Check whether the device path string is a valid string.
1312 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
) {
1313 if (Selection
->Form
->ModalForm
) {
1318 // Goto another Hii Package list
1320 if (mPathFromText
!= NULL
) {
1321 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1322 if (DevicePath
!= NULL
) {
1323 HiiHandle
= DevicePathToHiiHandle (DevicePath
);
1324 FreePool (DevicePath
);
1326 FreePool (StringPtr
);
1329 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1331 gBrowserStatus
= BROWSER_PROTOCOL_NOT_FOUND
;
1332 FreePool (StringPtr
);
1336 if (HiiHandle
!= Selection
->Handle
) {
1338 // Goto another Formset, check for uncommitted data
1340 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1341 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1342 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1348 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1349 Selection
->Handle
= HiiHandle
;
1350 if (Selection
->Handle
== NULL
) {
1352 // If target Hii Handle not found, exit current formset.
1354 FindParentFormSet(Selection
);
1358 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1359 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1360 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1361 } else if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &gZeroGuid
)) {
1362 if (Selection
->Form
->ModalForm
) {
1365 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1367 // Goto another Formset, check for uncommitted data
1369 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1370 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1371 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1377 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1378 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1379 if (Selection
->Handle
== NULL
) {
1381 // If target Hii Handle not found, exit current formset.
1383 FindParentFormSet(Selection
);
1387 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1388 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1389 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1390 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1392 // Goto another Form, check for uncommitted data
1394 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1395 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1396 if (!ProcessChangedData (Selection
, FormLevel
)) {
1402 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1403 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1404 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1406 // Form is suppressed.
1408 gBrowserStatus
= BROWSER_FORM_SUPPRESS
;
1413 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1414 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1415 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1416 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1424 Process Question Config.
1426 @param Selection The UI menu selection.
1427 @param Question The Question to be peocessed.
1429 @retval EFI_SUCCESS Question Config process success.
1430 @retval Other Question Config process fail.
1434 ProcessQuestionConfig (
1435 IN UI_MENU_SELECTION
*Selection
,
1436 IN FORM_BROWSER_STATEMENT
*Question
1442 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1444 if (Question
->QuestionConfig
== 0) {
1451 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1452 if (ConfigResp
== NULL
) {
1453 return EFI_NOT_FOUND
;
1457 // Send config to Configuration Driver
1459 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
1460 if (ConfigAccess
== NULL
) {
1461 return EFI_UNSUPPORTED
;
1463 Status
= ConfigAccess
->RouteConfig (
1474 Process the user input data.
1476 @param UserInput The user input data.
1477 @param ChangeHighlight Whether need to change the highlight statement.
1479 @retval EFI_SUCESSS This function always return successfully for now.
1484 IN USER_INPUT
*UserInput
,
1485 IN BOOLEAN ChangeHighlight
1489 FORM_BROWSER_STATEMENT
*Statement
;
1491 Status
= EFI_SUCCESS
;
1494 // When Exit from FormDisplay function, one of the below two cases must be true.
1496 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1499 // Remove the last highligh question id, this id will update when show next form.
1501 gCurrentSelection
->QuestionId
= 0;
1504 // First process the Action field in USER_INPUT.
1506 if (UserInput
->Action
!= 0) {
1507 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1508 if (EFI_ERROR (Status
)) {
1513 // Clear the highlight info.
1515 gCurrentSelection
->Statement
= NULL
;
1517 if (UserInput
->SelectedStatement
!= NULL
) {
1518 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1519 ASSERT (Statement
!= NULL
);
1521 // Save the current highlight menu in the menu history data.
1522 // which will be used when later browse back to this form.
1524 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1526 // For statement like text, actio, it not has question id.
1527 // So use FakeQuestionId to save the question.
1529 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1530 mCurFakeQestId
= Statement
->FakeQuestionId
;
1536 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1537 ASSERT (Statement
!= NULL
);
1539 gCurrentSelection
->Statement
= Statement
;
1541 if (ChangeHighlight
) {
1543 // This question is the current user select one,record it and later
1544 // show it as the highlight question.
1546 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1548 // For statement like text, actio, it not has question id.
1549 // So use FakeQuestionId to save the question.
1551 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1552 mCurFakeQestId
= Statement
->FakeQuestionId
;
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
);
1578 switch (Statement
->Operand
) {
1579 case EFI_IFR_STRING_OP
:
1580 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1581 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1582 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1583 FreePool (UserInput
->InputValue
.Buffer
);
1586 case EFI_IFR_PASSWORD_OP
:
1587 if (UserInput
->InputValue
.Buffer
== NULL
) {
1589 // User not input new password, just return.
1594 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1595 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1596 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1597 FreePool (UserInput
->InputValue
.Buffer
);
1599 // Two password match, send it to Configuration Driver
1601 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1602 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1604 // Clean the value after saved it.
1606 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1607 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1609 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1613 case EFI_IFR_ORDERED_LIST_OP
:
1614 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1618 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1630 Display form and wait for user to select one menu option, then return it.
1632 @retval EFI_SUCESSS This function always return successfully for now.
1641 USER_INPUT UserInput
;
1642 FORM_ENTRY_INFO
*CurrentMenu
;
1643 BOOLEAN ChangeHighlight
;
1645 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1648 // Update the menu history data.
1650 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1651 if (CurrentMenu
== NULL
) {
1653 // Current menu not found, add it to the menu tree
1655 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1656 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1657 ASSERT (CurrentMenu
!= NULL
);
1659 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1662 // Find currrent highlight statement.
1664 if (gCurrentSelection
->QuestionId
== 0) {
1666 // Highlight not specified, fetch it from cached menu
1668 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1672 // Evaluate all the Expressions in this Form
1674 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1675 if (EFI_ERROR (Status
)) {
1679 UpdateDisplayFormData ();
1682 // Three possible status maybe return.
1684 // EFI_INVALID_PARAMETER: The input dimension info is not valid.
1685 // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
1686 // and an valid value has return.
1687 // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
1689 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1690 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
1691 FreeDisplayFormData();
1696 // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
1697 // in this case, browser need to change the highlight menu.
1698 // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
1699 // opcode and new valid value has return, browser core need to adjust
1700 // value for this opcode and shows this form again.
1702 ChangeHighlight
= (Status
== EFI_SUCCESS
? TRUE
:FALSE
);
1704 Status
= ProcessUserInput (&UserInput
, ChangeHighlight
);
1706 FreeDisplayFormData();
1712 Functions which are registered to receive notification of
1713 database events have this prototype. The actual event is encoded
1714 in NotifyType. The following table describes how PackageType,
1715 PackageGuid, Handle, and Package are used for each of the
1718 @param PackageType Package type of the notification.
1720 @param PackageGuid If PackageType is
1721 EFI_HII_PACKAGE_TYPE_GUID, then this is
1722 the pointer to the GUID from the Guid
1723 field of EFI_HII_PACKAGE_GUID_HEADER.
1724 Otherwise, it must be NULL.
1726 @param Package Points to the package referred to by the
1727 notification Handle The handle of the package
1728 list which contains the specified package.
1730 @param Handle The HII handle.
1732 @param NotifyType The type of change concerning the
1734 EFI_HII_DATABASE_NOTIFY_TYPE.
1740 IN UINT8 PackageType
,
1741 IN CONST EFI_GUID
*PackageGuid
,
1742 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1743 IN EFI_HII_HANDLE Handle
,
1744 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1747 mHiiPackageListUpdated
= TRUE
;
1753 Update the NV flag info for this form set.
1755 @param FormSet FormSet data structure.
1759 IsNvUpdateRequiredForFormSet (
1760 IN FORM_BROWSER_FORMSET
*FormSet
1764 FORM_BROWSER_FORM
*Form
;
1768 // Not finished question initialization, return FALSE.
1770 if (!FormSet
->QuestionInited
) {
1776 Link
= GetFirstNode (&FormSet
->FormListHead
);
1777 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1778 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1780 RetVal
= IsNvUpdateRequiredForForm(Form
);
1785 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1792 Update the NvUpdateRequired flag for a form.
1794 @param Form Form data structure.
1798 IsNvUpdateRequiredForForm (
1799 IN FORM_BROWSER_FORM
*Form
1803 FORM_BROWSER_STATEMENT
*Statement
;
1805 Link
= GetFirstNode (&Form
->StatementListHead
);
1806 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1807 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1809 if (Statement
->ValueChanged
) {
1813 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1820 Check whether the storage data for current form set is changed.
1822 @param FormSet FormSet data structure.
1824 @retval TRUE Data is changed.
1825 @retval FALSE Data is not changed.
1828 IsStorageDataChangedForFormSet (
1829 IN FORM_BROWSER_FORMSET
*FormSet
1833 FORMSET_STORAGE
*Storage
;
1834 BROWSER_STORAGE
*BrowserStorage
;
1835 CHAR16
*ConfigRespNew
;
1836 CHAR16
*ConfigRespOld
;
1840 ConfigRespNew
= NULL
;
1841 ConfigRespOld
= NULL
;
1844 // Request current settings from Configuration Driver
1846 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1847 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1848 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1849 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1851 BrowserStorage
= Storage
->BrowserStorage
;
1853 if (BrowserStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1857 if (Storage
->ElementCount
== 0) {
1861 StorageToConfigResp (BrowserStorage
, &ConfigRespNew
, Storage
->ConfigRequest
, TRUE
);
1862 StorageToConfigResp (BrowserStorage
, &ConfigRespOld
, Storage
->ConfigRequest
, FALSE
);
1863 ASSERT (ConfigRespNew
!= NULL
&& ConfigRespOld
!= NULL
);
1865 if (StrCmp (ConfigRespNew
, ConfigRespOld
) != 0) {
1869 FreePool (ConfigRespNew
);
1870 ConfigRespNew
= NULL
;
1872 FreePool (ConfigRespOld
);
1873 ConfigRespOld
= NULL
;
1884 Find menu which will show next time.
1886 @param Selection On input, Selection tell setup browser the information
1887 about the Selection, form and formset to be displayed.
1888 On output, Selection return the screen item that is selected
1890 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1891 else, we need to exit current formset.
1893 @retval TRUE Exit current form.
1894 @retval FALSE User press ESC and keep in current form.
1898 IN OUT UI_MENU_SELECTION
*Selection
,
1899 IN BROWSER_SETTING_SCOPE SettingLevel
1902 FORM_ENTRY_INFO
*CurrentMenu
;
1903 FORM_ENTRY_INFO
*ParentMenu
;
1904 BROWSER_SETTING_SCOPE Scope
;
1906 CurrentMenu
= Selection
->CurrentMenu
;
1908 Scope
= FormSetLevel
;
1910 if (CurrentMenu
!= NULL
&& (ParentMenu
= UiFindParentMenu(CurrentMenu
)) != NULL
) {
1912 // we have a parent, so go to the parent menu
1914 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1915 if (SettingLevel
== FormSetLevel
) {
1917 // Find a menu which has different formset guid with current.
1919 while (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1920 CurrentMenu
= ParentMenu
;
1921 if ((ParentMenu
= UiFindParentMenu(CurrentMenu
)) == NULL
) {
1926 if (ParentMenu
!= NULL
) {
1927 Scope
= FormSetLevel
;
1933 Scope
= FormSetLevel
;
1938 // Form Level Check whether the data is changed.
1940 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1941 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1942 if (!ProcessChangedData(Selection
, Scope
)) {
1947 if (ParentMenu
!= NULL
) {
1949 // ParentMenu is found. Then, go to it.
1951 if (Scope
== FormLevel
) {
1952 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1954 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1955 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1956 Selection
->Handle
= ParentMenu
->HiiHandle
;
1959 Selection
->Statement
= NULL
;
1961 Selection
->FormId
= ParentMenu
->FormId
;
1962 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1965 // Clear highlight record for this menu
1967 CurrentMenu
->QuestionId
= 0;
1972 // Current in root page, exit the SendForm
1974 Selection
->Action
= UI_ACTION_EXIT
;
1980 Call the call back function for the question and process the return action.
1982 @param Selection On input, Selection tell setup browser the information
1983 about the Selection, form and formset to be displayed.
1984 On output, Selection return the screen item that is selected
1986 @param Question The Question which need to call.
1987 @param Action The action request.
1988 @param SkipSaveOrDiscard Whether skip save or discard action.
1990 @retval EFI_SUCCESS The call back function excutes successfully.
1991 @return Other value if the call back function failed to excute.
1994 ProcessCallBackFunction (
1995 IN OUT UI_MENU_SELECTION
*Selection
,
1996 IN FORM_BROWSER_STATEMENT
*Question
,
1997 IN EFI_BROWSER_ACTION Action
,
1998 IN BOOLEAN SkipSaveOrDiscard
2002 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2003 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2004 EFI_HII_VALUE
*HiiValue
;
2005 EFI_IFR_TYPE_VALUE
*TypeValue
;
2006 FORM_BROWSER_STATEMENT
*Statement
;
2007 BOOLEAN SubmitFormIsRequired
;
2008 BOOLEAN DiscardFormIsRequired
;
2011 BROWSER_SETTING_SCOPE SettingLevel
;
2012 EFI_IFR_TYPE_VALUE BackUpValue
;
2013 UINT8
*BackUpBuffer
;
2015 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2016 SubmitFormIsRequired
= FALSE
;
2017 SettingLevel
= FormSetLevel
;
2018 DiscardFormIsRequired
= FALSE
;
2020 Status
= EFI_SUCCESS
;
2021 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2022 BackUpBuffer
= NULL
;
2024 if (ConfigAccess
== NULL
) {
2028 Link
= GetFirstNode (&Selection
->Form
->StatementListHead
);
2029 while (!IsNull (&Selection
->Form
->StatementListHead
, Link
)) {
2030 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2031 Link
= GetNextNode (&Selection
->Form
->StatementListHead
, Link
);
2034 // if Question != NULL, only process the question. Else, process all question in this form.
2036 if ((Question
!= NULL
) && (Statement
!= Question
)) {
2040 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
2045 // Check whether Statement is disabled.
2047 if (Statement
->Expression
!= NULL
) {
2048 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressDisable
) {
2053 HiiValue
= &Statement
->HiiValue
;
2054 TypeValue
= &HiiValue
->Value
;
2055 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2057 // For OrderedList, passing in the value buffer to Callback()
2059 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2063 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
2065 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
2066 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2067 BackUpBuffer
= AllocateCopyPool(Statement
->StorageWidth
+ sizeof(CHAR16
), Statement
->BufferValue
);
2069 CopyMem (&BackUpValue
, &HiiValue
->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
2073 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2074 Status
= ConfigAccess
->Callback (
2077 Statement
->QuestionId
,
2082 if (!EFI_ERROR (Status
)) {
2084 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2086 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
2087 switch (ActionRequest
) {
2088 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2089 DiscardFormIsRequired
= TRUE
;
2090 gResetRequired
= TRUE
;
2094 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2095 SubmitFormIsRequired
= TRUE
;
2099 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2100 DiscardFormIsRequired
= TRUE
;
2104 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2105 SubmitFormIsRequired
= TRUE
;
2106 SettingLevel
= FormLevel
;
2110 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2111 DiscardFormIsRequired
= TRUE
;
2112 SettingLevel
= FormLevel
;
2116 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2117 SubmitFormIsRequired
= TRUE
;
2118 SettingLevel
= FormLevel
;
2121 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2122 DiscardFormIsRequired
= TRUE
;
2123 SettingLevel
= FormLevel
;
2132 // According the spec, return value from call back of "changing" and
2133 // "retrieve" should update to the question's temp buffer.
2135 if (Action
== EFI_BROWSER_ACTION_CHANGING
|| Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2136 SetQuestionValue(Selection
->FormSet
, Selection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2140 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
2141 // then the browser will use the value passed to Callback() and ignore the
2142 // value returned by Callback().
2144 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
== EFI_UNSUPPORTED
) {
2145 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2146 CopyMem (Statement
->BufferValue
, BackUpBuffer
, Statement
->StorageWidth
+ sizeof(CHAR16
));
2148 CopyMem (&HiiValue
->Value
, &BackUpValue
, sizeof (EFI_IFR_TYPE_VALUE
));
2151 SetQuestionValue(Selection
->FormSet
, Selection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2155 // According the spec, return fail from call back of "changing" and
2156 // "retrieve", should restore the question's value.
2158 if ((Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
!= EFI_UNSUPPORTED
) ||
2159 Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2160 GetQuestionValue(Selection
->FormSet
, Selection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2163 if (Status
== EFI_UNSUPPORTED
) {
2165 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2167 Status
= EFI_SUCCESS
;
2171 if (BackUpBuffer
!= NULL
) {
2172 FreePool (BackUpBuffer
);
2176 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2177 SubmitForm (Selection
->FormSet
, Selection
->Form
, SettingLevel
);
2180 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2181 DiscardForm (Selection
->FormSet
, Selection
->Form
, SettingLevel
);
2185 FindNextMenu (Selection
, SettingLevel
);
2192 Call the retrieve type call back function for one question to get the initialize data.
2194 This function only used when in the initialize stage, because in this stage, the
2195 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2197 @param ConfigAccess The config access protocol produced by the hii driver.
2198 @param Statement The Question which need to call.
2200 @retval EFI_SUCCESS The call back function excutes successfully.
2201 @return Other value if the call back function failed to excute.
2204 ProcessRetrieveForQuestion (
2205 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2206 IN FORM_BROWSER_STATEMENT
*Statement
2210 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2211 EFI_HII_VALUE
*HiiValue
;
2212 EFI_IFR_TYPE_VALUE
*TypeValue
;
2214 Status
= EFI_SUCCESS
;
2215 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2217 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
2218 return EFI_UNSUPPORTED
;
2221 HiiValue
= &Statement
->HiiValue
;
2222 TypeValue
= &HiiValue
->Value
;
2223 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2225 // For OrderedList, passing in the value buffer to Callback()
2227 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2230 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2231 Status
= ConfigAccess
->Callback (
2233 EFI_BROWSER_ACTION_RETRIEVE
,
2234 Statement
->QuestionId
,
2243 The worker function that send the displays to the screen. On output,
2244 the selection made by user is returned.
2246 @param Selection On input, Selection tell setup browser the information
2247 about the Selection, form and formset to be displayed.
2248 On output, Selection return the screen item that is selected
2251 @retval EFI_SUCCESS The page is displayed successfully.
2252 @return Other value if the page failed to be diplayed.
2257 IN OUT UI_MENU_SELECTION
*Selection
2262 EFI_HANDLE NotifyHandle
;
2263 FORM_BROWSER_STATEMENT
*Statement
;
2264 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2266 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2269 // Register notify for Form package update
2271 Status
= mHiiDatabase
->RegisterPackageNotify (
2273 EFI_HII_PACKAGE_FORMS
,
2276 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2279 if (EFI_ERROR (Status
)) {
2284 // Initialize current settings of Questions in this FormSet
2286 InitializeCurrentSetting (Selection
->FormSet
);
2289 // Initilize Action field.
2291 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2294 // Clean the mCurFakeQestId value is formset refreshed.
2300 // IFR is updated, force to reparse the IFR binary
2302 if (mHiiPackageListUpdated
) {
2303 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2304 mHiiPackageListUpdated
= FALSE
;
2309 // Initialize Selection->Form
2311 if (Selection
->FormId
== 0) {
2313 // Zero FormId indicates display the first Form in a FormSet
2315 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2317 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2318 Selection
->FormId
= Selection
->Form
->FormId
;
2320 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2323 if (Selection
->Form
== NULL
) {
2325 // No Form to display
2327 Status
= EFI_NOT_FOUND
;
2332 // Check Form is suppressed.
2334 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2335 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2337 // Form is suppressed.
2339 gBrowserStatus
= BROWSER_FORM_SUPPRESS
;
2340 Status
= EFI_NOT_FOUND
;
2346 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2347 // for each question with callback flag.
2348 // New form may be the first form, or the different form after another form close.
2350 if ((ConfigAccess
!= NULL
) &&
2351 ((Selection
->Handle
!= mCurrentHiiHandle
) ||
2352 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2353 (Selection
->FormId
!= mCurrentFormId
))) {
2355 // Keep current form information
2357 mCurrentHiiHandle
= Selection
->Handle
;
2358 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2359 mCurrentFormId
= Selection
->FormId
;
2361 Status
= ProcessCallBackFunction (Selection
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2362 if (EFI_ERROR (Status
)) {
2367 // IFR is updated during callback of open form, force to reparse the IFR binary
2369 if (mHiiPackageListUpdated
) {
2370 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2371 mHiiPackageListUpdated
= FALSE
;
2377 // Load Questions' Value for display
2379 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2380 if (EFI_ERROR (Status
)) {
2385 // IFR is updated during callback of read value, force to reparse the IFR binary
2387 if (mHiiPackageListUpdated
) {
2388 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2389 mHiiPackageListUpdated
= FALSE
;
2396 Status
= DisplayForm ();
2397 if (EFI_ERROR (Status
)) {
2402 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2404 Statement
= Selection
->Statement
;
2405 if (Statement
!= NULL
) {
2406 if ((ConfigAccess
!= NULL
) &&
2407 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2408 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2409 Status
= ProcessCallBackFunction(Selection
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2410 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2412 // Process dynamic update ref opcode.
2414 if (!EFI_ERROR (Status
)) {
2415 Status
= ProcessGotoOpCode(Statement
, Selection
);
2419 // Callback return error status or status return from process goto opcode.
2421 if (EFI_ERROR (Status
)) {
2423 // Cross reference will not be taken
2425 Selection
->FormId
= Selection
->Form
->FormId
;
2426 Selection
->QuestionId
= 0;
2430 if (!EFI_ERROR (Status
) && Statement
->Operand
!= EFI_IFR_REF_OP
) {
2431 ProcessCallBackFunction(Selection
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2433 } else if (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
) {
2434 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2439 // Check whether Exit flag is TRUE.
2441 if (gExitRequired
) {
2442 switch (gBrowserSettingScope
) {
2444 Selection
->Action
= UI_ACTION_EXIT
;
2449 FindNextMenu (Selection
, gBrowserSettingScope
);
2456 gExitRequired
= FALSE
;
2460 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2461 // for each question with callback flag.
2463 if ((ConfigAccess
!= NULL
) &&
2464 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2465 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2466 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2467 (Selection
->FormId
!= mCurrentFormId
))) {
2469 Status
= ProcessCallBackFunction (Selection
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2470 if (EFI_ERROR (Status
)) {
2474 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2478 // Reset current form information to the initial setting when error happens or form exit.
2480 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2481 mCurrentHiiHandle
= NULL
;
2482 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2487 // Unregister notify for Form package update
2489 mHiiDatabase
->UnregisterPackageNotify (