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_WRITE
||
56 (Expression
->Type
== EFI_HII_EXPRESSION_READ
&& Form
->FormType
!= STANDARD_MAP_FORM_TYPE
)) {
58 // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
63 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
64 if (EFI_ERROR (Status
)) {
73 Add empty function for event process function.
75 @param Event The Event need to be process
76 @param Context The context of the event.
81 SetupBrowserEmptyFunction (
89 Base on the opcode buffer info to get the display statement.
91 @param OpCode The input opcode buffer for this statement.
93 @retval Statement The statement use this opcode buffer.
96 FORM_DISPLAY_ENGINE_STATEMENT
*
98 IN EFI_IFR_OP_HEADER
*OpCode
101 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
104 Link
= GetFirstNode (&gDisplayFormData
.StatementListHead
);
105 while (!IsNull (&gDisplayFormData
.StatementListHead
, Link
)) {
106 DisplayStatement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
108 if (DisplayStatement
->OpCode
== OpCode
) {
109 return DisplayStatement
;
111 Link
= GetNextNode (&gDisplayFormData
.StatementListHead
, Link
);
118 Free the refresh event list.
127 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
129 while (!IsListEmpty (&mRefreshEventList
)) {
130 Link
= GetFirstNode (&mRefreshEventList
);
131 EventNode
= FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link
);
132 RemoveEntryList (&EventNode
->Link
);
134 gBS
->CloseEvent (EventNode
->RefreshEvent
);
136 FreePool (EventNode
);
141 Check whether this statement value is changed. If yes, update the statement value and return TRUE;
144 @param Statement The statement need to check.
149 IN OUT FORM_BROWSER_STATEMENT
*Statement
152 GetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
155 // Reset FormPackage update flag
157 mHiiPackageListUpdated
= FALSE
;
160 // Question value may be changed, need invoke its Callback()
162 ProcessCallBackFunction (gCurrentSelection
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
164 if (mHiiPackageListUpdated
) {
166 // Package list is updated, force to reparse IFR binary of target Formset
168 mHiiPackageListUpdated
= FALSE
;
169 gCurrentSelection
->Action
= UI_ACTION_REFRESH_FORMSET
;
174 Refresh the question which has refresh guid event attribute.
176 @param Event The event which has this function related.
177 @param Context The input context info related to this event or the status code return to the caller.
186 FORM_BROWSER_STATEMENT
*Statement
;
188 Statement
= (FORM_BROWSER_STATEMENT
*)Context
;
189 UpdateStatement(Statement
);
190 gBS
->SignalEvent (mValueChangedEvent
);
195 Create refresh hook event for statement which has refresh event or interval.
197 @param Statement The statement need to check.
202 IN FORM_BROWSER_STATEMENT
*Statement
206 EFI_EVENT RefreshEvent
;
207 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
210 // If question has refresh guid, create the notify function.
212 Status
= gBS
->CreateEventEx (
217 &Statement
->RefreshGuid
,
219 ASSERT_EFI_ERROR (Status
);
221 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
222 ASSERT (EventNode
!= NULL
);
223 EventNode
->RefreshEvent
= RefreshEvent
;
224 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
228 Perform value check for a question.
230 @param Question The question need to do check.
231 @param ErrorInfo Return info about the error.
233 @retval The check result.
236 InConsistentIfCheck (
237 IN FORM_BROWSER_STATEMENT
*Question
,
238 OUT STATEMENT_ERROR_INFO
*ErrorInfo
243 FORM_EXPRESSION
*Expression
;
244 LIST_ENTRY
*ListHead
;
247 RetVal
= STATEMENT_VALID
;
248 ListHead
= &Question
->InconsistentListHead
;
250 Link
= GetFirstNode (ListHead
);
251 while (!IsNull (ListHead
, Link
)) {
252 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
253 Link
= GetNextNode (ListHead
, Link
);
256 // Evaluate the expression
258 Status
= EvaluateExpression (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Expression
);
259 if (EFI_ERROR (Status
)) {
263 if ((Expression
->Result
.Type
== EFI_IFR_TYPE_BOOLEAN
) && Expression
->Result
.Value
.b
) {
264 ErrorInfo
->StringId
= Expression
->Error
;
265 ErrorInfo
->TimeOut
= 0;
266 RetVal
= INCOSISTENT_IF_TRUE
;
275 Perform value check for a question.
277 @param Form Form where Statement is in.
278 @param Statement Value will check for it.
279 @param InputValue New value will be checked.
280 @param ErrorInfo Return the error info for this check.
282 @retval TRUE Input Value is valid.
283 @retval FALSE Input Value is invalid.
288 IN FORM_DISPLAY_ENGINE_FORM
*Form
,
289 IN FORM_DISPLAY_ENGINE_STATEMENT
*Statement
,
290 IN EFI_HII_VALUE
*InputValue
,
291 OUT STATEMENT_ERROR_INFO
*ErrorInfo
294 FORM_BROWSER_STATEMENT
*Question
;
295 EFI_HII_VALUE BackUpValue
;
300 RetVal
= STATEMENT_VALID
;
302 ASSERT (Form
!= NULL
&& Statement
!= NULL
&& InputValue
!= NULL
&& ErrorInfo
!= NULL
);
304 Question
= GetBrowserStatement(Statement
);
305 ASSERT (Question
!= NULL
);
308 // Back up the quesion value.
310 switch (Question
->Operand
) {
311 case EFI_IFR_ORDERED_LIST_OP
:
312 BackUpBuffer
= AllocateCopyPool (Question
->StorageWidth
, Question
->BufferValue
);
313 ASSERT (BackUpBuffer
!= NULL
);
314 CopyMem (Question
->BufferValue
, InputValue
->Buffer
, Question
->StorageWidth
);
318 CopyMem (&BackUpValue
, &Question
->HiiValue
, sizeof (EFI_HII_VALUE
));
319 CopyMem (&Question
->HiiValue
, InputValue
, sizeof (EFI_HII_VALUE
));
324 // Do the inconsistentif check.
326 if (!IsListEmpty (&Question
->InconsistentListHead
)) {
327 RetVal
= InConsistentIfCheck(Question
, ErrorInfo
);
331 // Restore the quesion value.
333 switch (Question
->Operand
) {
334 case EFI_IFR_ORDERED_LIST_OP
:
335 CopyMem (Question
->BufferValue
, BackUpBuffer
, Question
->StorageWidth
);
339 CopyMem (&Question
->HiiValue
, &BackUpValue
, sizeof (EFI_HII_VALUE
));
348 Initialize the Display statement structure data.
350 @param DisplayStatement Pointer to the display Statement data strucure.
351 @param Statement The statement need to check.
352 @param HostDisplayStatement Pointer to the display Statement data strucure which is an host statement.
355 InitializeDisplayStatement (
356 IN OUT FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
,
357 IN FORM_BROWSER_STATEMENT
*Statement
,
358 IN FORM_DISPLAY_ENGINE_STATEMENT
*HostDisplayStatement
362 QUESTION_OPTION
*Option
;
363 DISPLAY_QUESTION_OPTION
*DisplayOption
;
365 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
366 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
367 DisplayStatement
->OpCode
= Statement
->OpCode
;
368 InitializeListHead (&DisplayStatement
->NestStatementList
);
369 InitializeListHead (&DisplayStatement
->OptionListHead
);
371 if ((EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) == ExpressGrayOut
) || Statement
->Locked
) {
372 DisplayStatement
->Attribute
|= HII_DISPLAY_GRAYOUT
;
374 if ((Statement
->ValueExpression
!= NULL
) || ((Statement
->QuestionFlags
& EFI_IFR_FLAG_READ_ONLY
) != 0)) {
375 DisplayStatement
->Attribute
|= HII_DISPLAY_READONLY
;
379 // Initilize the option list in statement.
381 Link
= GetFirstNode (&Statement
->OptionListHead
);
382 while (!IsNull (&Statement
->OptionListHead
, Link
)) {
383 Option
= QUESTION_OPTION_FROM_LINK (Link
);
384 Link
= GetNextNode (&Statement
->OptionListHead
, Link
);
385 if ((Option
->SuppressExpression
!= NULL
) &&
386 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
390 DisplayOption
= AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION
));
391 ASSERT (DisplayOption
!= NULL
);
393 DisplayOption
->ImageId
= Option
->ImageId
;
394 DisplayOption
->Signature
= DISPLAY_QUESTION_OPTION_SIGNATURE
;
395 DisplayOption
->OptionOpCode
= Option
->OpCode
;
396 InsertTailList(&DisplayStatement
->OptionListHead
, &DisplayOption
->Link
);
399 CopyMem (&DisplayStatement
->CurrentValue
, &Statement
->HiiValue
, sizeof (EFI_HII_VALUE
));
402 // Some special op code need an extra buffer to save the data.
403 // Such as string, password, orderedlist...
405 if (Statement
->BufferValue
!= NULL
) {
407 // Ordered list opcode may not initilized, get default value here.
409 if (Statement
->OpCode
->OpCode
== EFI_IFR_ORDERED_LIST_OP
&& GetArrayData (Statement
->BufferValue
, Statement
->ValueType
, 0) == 0) {
410 GetQuestionDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, 0);
413 DisplayStatement
->CurrentValue
.Buffer
= AllocateCopyPool(Statement
->StorageWidth
,Statement
->BufferValue
);
414 DisplayStatement
->CurrentValue
.BufferLen
= Statement
->StorageWidth
;
417 DisplayStatement
->SettingChangedFlag
= Statement
->ValueChanged
;
420 // Get the highlight statement for current form.
422 if (((gCurrentSelection
->QuestionId
!= 0) && (Statement
->QuestionId
== gCurrentSelection
->QuestionId
)) ||
423 ((mCurFakeQestId
!= 0) && (Statement
->FakeQuestionId
== mCurFakeQestId
))) {
424 gDisplayFormData
.HighLightedStatement
= DisplayStatement
;
428 // Create the refresh event process function.
430 if (!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) {
431 CreateRefreshEvent (Statement
);
435 // For RTC type of date/time, set default refresh interval to be 1 second.
437 if ((Statement
->Operand
== EFI_IFR_DATE_OP
|| Statement
->Operand
== EFI_IFR_TIME_OP
) && Statement
->Storage
== NULL
) {
438 Statement
->RefreshInterval
= 1;
442 // Create the refresh guid hook event.
443 // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
445 if ((!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) || (Statement
->RefreshInterval
!= 0)) {
446 gDisplayFormData
.FormRefreshEvent
= mValueChangedEvent
;
450 // Save the password check function for later use.
452 if (Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
453 DisplayStatement
->PasswordCheck
= PasswordCheck
;
457 // Save the validate check question for later use.
459 if (!IsListEmpty (&Statement
->InconsistentListHead
)) {
460 DisplayStatement
->ValidateQuestion
= QuestionCheck
;
464 // If this statement is nest in the subtitle, insert to the host statement.
465 // else insert to the form it belongs to.
467 if (Statement
->InSubtitle
) {
468 InsertTailList(&HostDisplayStatement
->NestStatementList
, &DisplayStatement
->DisplayLink
);
470 InsertTailList(&gDisplayFormData
.StatementListHead
, &DisplayStatement
->DisplayLink
);
475 Process for the refresh interval statement.
477 @param Event The Event need to be process
478 @param Context The context of the event.
483 RefreshIntervalProcess (
488 FORM_BROWSER_STATEMENT
*Statement
;
491 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
492 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
493 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
494 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
496 if (Statement
->RefreshInterval
== 0) {
500 UpdateStatement(Statement
);
503 gBS
->SignalEvent (mValueChangedEvent
);
508 Make a copy of the global hotkey info.
516 BROWSER_HOT_KEY
*HotKey
;
517 BROWSER_HOT_KEY
*CopyKey
;
520 Link
= GetFirstNode (&gBrowserHotKeyList
);
521 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
522 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
524 CopyKey
= AllocateCopyPool(sizeof (BROWSER_HOT_KEY
), HotKey
);
525 CopyKey
->KeyData
= AllocateCopyPool(sizeof (EFI_INPUT_KEY
), HotKey
->KeyData
);
526 CopyKey
->HelpString
= AllocateCopyPool(StrSize (HotKey
->HelpString
), HotKey
->HelpString
);
528 InsertTailList(&gDisplayFormData
.HotKeyListHead
, &CopyKey
->Link
);
530 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
536 Enum all statement in current form, find all the statement can be display and
537 add to the display form.
541 AddStatementToDisplayForm (
547 FORM_BROWSER_STATEMENT
*Statement
;
548 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
549 FORM_DISPLAY_ENGINE_STATEMENT
*HostDisplayStatement
;
550 UINT8 MinRefreshInterval
;
551 EFI_EVENT RefreshIntervalEvent
;
552 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
553 BOOLEAN FormEditable
;
555 HostDisplayStatement
= NULL
;
556 MinRefreshInterval
= 0;
557 FormEditable
= FALSE
;
560 // Process the statement outside the form, these statements are not recognized
563 Link
= GetFirstNode (&gCurrentSelection
->FormSet
->StatementListOSF
);
564 while (!IsNull (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
)) {
565 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
566 Link
= GetNextNode (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
);
568 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
569 ASSERT (DisplayStatement
!= NULL
);
570 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
571 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
572 DisplayStatement
->OpCode
= Statement
->OpCode
;
574 InitializeListHead (&DisplayStatement
->NestStatementList
);
575 InitializeListHead (&DisplayStatement
->OptionListHead
);
577 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
581 // Process the statement in this form.
583 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
584 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
585 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
586 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
589 // This statement can't be show, skip it.
591 if (EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) > ExpressGrayOut
) {
595 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
596 ASSERT (DisplayStatement
!= NULL
);
599 // Initialize this statement and add it to the display form.
601 InitializeDisplayStatement(DisplayStatement
, Statement
, HostDisplayStatement
);
604 // Save the Host statement info.
605 // Host statement may has nest statement follow it.
607 if (!Statement
->InSubtitle
) {
608 HostDisplayStatement
= DisplayStatement
;
611 if (Statement
->Storage
!= NULL
) {
616 // Get the minimal refresh interval value for later use.
618 if ((Statement
->RefreshInterval
!= 0) &&
619 (MinRefreshInterval
== 0 || Statement
->RefreshInterval
< MinRefreshInterval
)) {
620 MinRefreshInterval
= Statement
->RefreshInterval
;
625 // Create the periodic timer for refresh interval statement.
627 if (MinRefreshInterval
!= 0) {
628 Status
= gBS
->CreateEvent (EVT_TIMER
| EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, RefreshIntervalProcess
, NULL
, &RefreshIntervalEvent
);
629 ASSERT_EFI_ERROR (Status
);
630 Status
= gBS
->SetTimer (RefreshIntervalEvent
, TimerPeriodic
, MinRefreshInterval
* ONE_SECOND
);
631 ASSERT_EFI_ERROR (Status
);
633 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
634 ASSERT (EventNode
!= NULL
);
635 EventNode
->RefreshEvent
= RefreshIntervalEvent
;
636 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
640 // Update hotkey list field.
642 if (gBrowserSettingScope
== SystemLevel
|| FormEditable
) {
649 Initialize the SettingChangedFlag variable in the display form.
653 UpdateDataChangedFlag (
658 FORM_BROWSER_FORMSET
*LocalFormSet
;
660 gDisplayFormData
.SettingChangedFlag
= FALSE
;
662 if (IsNvUpdateRequiredForForm (gCurrentSelection
->Form
)) {
663 gDisplayFormData
.SettingChangedFlag
= TRUE
;
668 // Base on the system level to check whether need to show the NV flag.
670 switch (gBrowserSettingScope
) {
673 // Check the maintain list to see whether there is any change.
675 Link
= GetFirstNode (&gBrowserFormSetList
);
676 while (!IsNull (&gBrowserFormSetList
, Link
)) {
677 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
678 if (IsNvUpdateRequiredForFormSet(LocalFormSet
)) {
679 gDisplayFormData
.SettingChangedFlag
= TRUE
;
682 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
687 if (IsNvUpdateRequiredForFormSet(gCurrentSelection
->FormSet
)) {
688 gDisplayFormData
.SettingChangedFlag
= TRUE
;
700 Initialize the Display form structure data.
704 InitializeDisplayFormData (
710 gDisplayFormData
.Signature
= FORM_DISPLAY_ENGINE_FORM_SIGNATURE
;
711 gDisplayFormData
.Version
= FORM_DISPLAY_ENGINE_VERSION_1
;
712 gDisplayFormData
.ImageId
= 0;
713 gDisplayFormData
.AnimationId
= 0;
715 InitializeListHead (&gDisplayFormData
.StatementListHead
);
716 InitializeListHead (&gDisplayFormData
.StatementListOSF
);
717 InitializeListHead (&gDisplayFormData
.HotKeyListHead
);
719 Status
= gBS
->CreateEvent (
722 SetupBrowserEmptyFunction
,
726 ASSERT_EFI_ERROR (Status
);
731 Free the kotkey info saved in form data.
739 BROWSER_HOT_KEY
*HotKey
;
742 while (!IsListEmpty (&gDisplayFormData
.HotKeyListHead
)) {
743 Link
= GetFirstNode (&gDisplayFormData
.HotKeyListHead
);
744 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
746 RemoveEntryList (&HotKey
->Link
);
748 FreePool (HotKey
->KeyData
);
749 FreePool (HotKey
->HelpString
);
756 Update the Display form structure data.
760 UpdateDisplayFormData (
764 gDisplayFormData
.FormTitle
= gCurrentSelection
->Form
->FormTitle
;
765 gDisplayFormData
.FormId
= gCurrentSelection
->FormId
;
766 gDisplayFormData
.HiiHandle
= gCurrentSelection
->Handle
;
767 CopyGuid (&gDisplayFormData
.FormSetGuid
, &gCurrentSelection
->FormSetGuid
);
769 gDisplayFormData
.Attribute
= 0;
770 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->ModalForm
? HII_DISPLAY_MODAL
: 0;
771 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->Locked
? HII_DISPLAY_LOCK
: 0;
773 gDisplayFormData
.FormRefreshEvent
= NULL
;
774 gDisplayFormData
.HighLightedStatement
= NULL
;
776 gDisplayFormData
.BrowserStatus
= gBrowserStatus
;
777 gDisplayFormData
.ErrorString
= gErrorInfo
;
779 gBrowserStatus
= BROWSER_SUCCESS
;
782 UpdateDataChangedFlag ();
784 AddStatementToDisplayForm ();
789 Free the Display Statement structure data.
791 @param StatementList Point to the statement list which need to be free.
796 LIST_ENTRY
*StatementList
800 LIST_ENTRY
*OptionLink
;
801 FORM_DISPLAY_ENGINE_STATEMENT
*Statement
;
802 DISPLAY_QUESTION_OPTION
*Option
;
805 // Free Statements/Questions
807 while (!IsListEmpty (StatementList
)) {
808 Link
= GetFirstNode (StatementList
);
809 Statement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
814 while (!IsListEmpty (&Statement
->OptionListHead
)) {
815 OptionLink
= GetFirstNode (&Statement
->OptionListHead
);
816 Option
= DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink
);
817 RemoveEntryList (&Option
->Link
);
822 // Free nest statement List
824 if (!IsListEmpty (&Statement
->NestStatementList
)) {
825 FreeStatementData(&Statement
->NestStatementList
);
828 RemoveEntryList (&Statement
->DisplayLink
);
829 FreePool (Statement
);
835 Free the Display form structure data.
839 FreeDisplayFormData (
843 FreeStatementData (&gDisplayFormData
.StatementListHead
);
844 FreeStatementData (&gDisplayFormData
.StatementListOSF
);
853 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
855 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
857 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
860 FORM_BROWSER_STATEMENT
*
861 GetBrowserStatement (
862 IN FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
865 FORM_BROWSER_STATEMENT
*Statement
;
868 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
869 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
870 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
872 if (Statement
->OpCode
== DisplayStatement
->OpCode
) {
876 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
884 Process the action request in user input.
886 @param Action The user input action request info.
887 @param DefaultId The user input default Id info.
889 @retval EFI_SUCESSS This function always return successfully for now.
901 // This is caused by use press ESC, and it should not combine with other action type.
903 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
904 FindNextMenu (gCurrentSelection
, FormLevel
);
909 // Below is normal hotkey trigged action, these action maybe combine with each other.
911 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
912 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
915 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
916 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
);
919 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
920 Status
= SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
921 if (EFI_ERROR (Status
)) {
922 gBrowserStatus
= BROWSER_SUBMIT_FAIL
;
926 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
927 gResetRequired
= TRUE
;
930 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
932 // Form Exit without saving, Similar to ESC Key.
933 // FormSet Exit without saving, Exit SendForm.
934 // System Exit without saving, CallExitHandler and Exit SendForm.
936 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
937 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
938 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
939 } else if (gBrowserSettingScope
== SystemLevel
) {
940 if (ExitHandlerFunction
!= NULL
) {
941 ExitHandlerFunction ();
943 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
952 Find HII Handle in the HII database associated with given Device Path.
954 If DevicePath is NULL, then ASSERT.
956 @param DevicePath Device Path associated with the HII package list
959 @retval Handle HII package list Handle associated with the Device
961 @retval NULL Hii Package list handle is not found.
966 DevicePathToHiiHandle (
967 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
971 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
976 EFI_HANDLE DriverHandle
;
977 EFI_HII_HANDLE
*HiiHandles
;
978 EFI_HII_HANDLE HiiHandle
;
980 ASSERT (DevicePath
!= NULL
);
982 TmpDevicePath
= DevicePath
;
984 // Locate Device Path Protocol handle buffer
986 Status
= gBS
->LocateDevicePath (
987 &gEfiDevicePathProtocolGuid
,
991 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
996 // Retrieve all HII Handles from HII database
999 HiiHandles
= AllocatePool (BufferSize
);
1000 ASSERT (HiiHandles
!= NULL
);
1001 Status
= mHiiDatabase
->ListPackageLists (
1003 EFI_HII_PACKAGE_TYPE_ALL
,
1008 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1009 FreePool (HiiHandles
);
1010 HiiHandles
= AllocatePool (BufferSize
);
1011 ASSERT (HiiHandles
!= NULL
);
1013 Status
= mHiiDatabase
->ListPackageLists (
1015 EFI_HII_PACKAGE_TYPE_ALL
,
1022 if (EFI_ERROR (Status
)) {
1023 FreePool (HiiHandles
);
1028 // Search Hii Handle by Driver Handle
1031 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
1032 for (Index
= 0; Index
< HandleCount
; Index
++) {
1033 Status
= mHiiDatabase
->GetPackageListHandle (
1038 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1039 HiiHandle
= HiiHandles
[Index
];
1044 FreePool (HiiHandles
);
1049 Find HII Handle in the HII database associated with given form set guid.
1051 If FormSetGuid is NULL, then ASSERT.
1053 @param ComparingGuid FormSet Guid associated with the HII package list
1056 @retval Handle HII package list Handle associated with the Device
1058 @retval NULL Hii Package list handle is not found.
1062 FormSetGuidToHiiHandle (
1063 EFI_GUID
*ComparingGuid
1066 EFI_HII_HANDLE
*HiiHandles
;
1068 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
1072 UINT32 PackageListLength
;
1073 EFI_HII_PACKAGE_HEADER PackageHeader
;
1077 EFI_HII_HANDLE HiiHandle
;
1079 ASSERT (ComparingGuid
!= NULL
);
1083 // Get all the Hii handles
1085 HiiHandles
= HiiGetHiiHandles (NULL
);
1086 ASSERT (HiiHandles
!= NULL
);
1089 // Search for formset of each class type
1091 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1093 HiiPackageList
= NULL
;
1094 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandles
[Index
], &BufferSize
, HiiPackageList
);
1095 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1096 HiiPackageList
= AllocatePool (BufferSize
);
1097 ASSERT (HiiPackageList
!= NULL
);
1099 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandles
[Index
], &BufferSize
, HiiPackageList
);
1101 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1106 // Get Form package from this HII package List
1108 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1110 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1112 while (Offset
< PackageListLength
) {
1113 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1114 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1116 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1118 // Search FormSet in this Form Package
1120 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1121 while (Offset2
< PackageHeader
.Length
) {
1122 OpCodeData
= Package
+ Offset2
;
1124 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1126 // Try to compare against formset GUID
1128 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1129 HiiHandle
= HiiHandles
[Index
];
1134 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1137 if (HiiHandle
!= NULL
) {
1140 Offset
+= PackageHeader
.Length
;
1143 FreePool (HiiPackageList
);
1144 if (HiiHandle
!= NULL
) {
1149 FreePool (HiiHandles
);
1155 check how to process the changed data in current form or form set.
1157 @param Selection On input, Selection tell setup browser the information
1158 about the Selection, form and formset to be displayed.
1159 On output, Selection return the screen item that is selected
1162 @param Scope Data save or discard scope, form or formset.
1164 @retval TRUE Success process the changed data, will return to the parent form.
1165 @retval FALSE Reject to process the changed data, will stay at current form.
1168 ProcessChangedData (
1169 IN OUT UI_MENU_SELECTION
*Selection
,
1170 IN BROWSER_SETTING_SCOPE Scope
1176 switch (mFormDisplay
->ConfirmDataChange()) {
1177 case BROWSER_ACTION_DISCARD
:
1178 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1181 case BROWSER_ACTION_SUBMIT
:
1182 SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1185 case BROWSER_ACTION_NONE
:
1191 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1201 Find parent formset menu(the first menu which has different formset) for current menu.
1202 If not find, just return to the first menu.
1204 @param Selection The selection info.
1209 IN OUT UI_MENU_SELECTION
*Selection
1212 FORM_ENTRY_INFO
*CurrentMenu
;
1213 FORM_ENTRY_INFO
*ParentMenu
;
1215 CurrentMenu
= Selection
->CurrentMenu
;
1216 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1219 // Find a menu which has different formset guid with current.
1221 while (ParentMenu
!= NULL
&& CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1222 CurrentMenu
= ParentMenu
;
1223 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1226 if (ParentMenu
!= NULL
) {
1227 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1228 Selection
->Handle
= ParentMenu
->HiiHandle
;
1229 Selection
->FormId
= ParentMenu
->FormId
;
1230 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1232 Selection
->FormId
= CurrentMenu
->FormId
;
1233 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1236 Selection
->Statement
= NULL
;
1240 Process the goto op code, update the info in the selection structure.
1242 @param Statement The statement belong to goto op code.
1243 @param Selection The selection info.
1245 @retval EFI_SUCCESS The menu process successfully.
1246 @return Other value if the process failed.
1250 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1251 IN OUT UI_MENU_SELECTION
*Selection
1255 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1256 FORM_BROWSER_FORM
*RefForm
;
1258 EFI_HII_HANDLE HiiHandle
;
1260 Status
= EFI_SUCCESS
;
1265 // Prepare the device path check, get the device path info first.
1267 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1268 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1272 // Check whether the device path string is a valid string.
1274 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
) {
1275 if (Selection
->Form
->ModalForm
) {
1280 // Goto another Hii Package list
1282 if (mPathFromText
!= NULL
) {
1283 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1284 if (DevicePath
!= NULL
) {
1285 HiiHandle
= DevicePathToHiiHandle (DevicePath
);
1286 FreePool (DevicePath
);
1288 FreePool (StringPtr
);
1291 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1293 gBrowserStatus
= BROWSER_PROTOCOL_NOT_FOUND
;
1294 FreePool (StringPtr
);
1298 if (HiiHandle
!= Selection
->Handle
) {
1300 // Goto another Formset, check for uncommitted data
1302 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1303 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1304 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1310 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1311 Selection
->Handle
= HiiHandle
;
1312 if (Selection
->Handle
== NULL
) {
1314 // If target Hii Handle not found, exit current formset.
1316 FindParentFormSet(Selection
);
1320 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1321 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1322 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1323 } else if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &gZeroGuid
)) {
1324 if (Selection
->Form
->ModalForm
) {
1327 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1329 // Goto another Formset, check for uncommitted data
1331 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1332 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1333 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1339 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1340 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1341 if (Selection
->Handle
== NULL
) {
1343 // If target Hii Handle not found, exit current formset.
1345 FindParentFormSet(Selection
);
1349 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1350 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1351 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1352 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1354 // Goto another Form, check for uncommitted data
1356 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1357 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1358 if (!ProcessChangedData (Selection
, FormLevel
)) {
1364 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1365 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1366 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1368 // Form is suppressed.
1370 gBrowserStatus
= BROWSER_FORM_SUPPRESS
;
1375 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1376 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1377 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1378 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1386 Process Question Config.
1388 @param Selection The UI menu selection.
1389 @param Question The Question to be peocessed.
1391 @retval EFI_SUCCESS Question Config process success.
1392 @retval Other Question Config process fail.
1396 ProcessQuestionConfig (
1397 IN UI_MENU_SELECTION
*Selection
,
1398 IN FORM_BROWSER_STATEMENT
*Question
1404 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1406 if (Question
->QuestionConfig
== 0) {
1413 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1414 if (ConfigResp
== NULL
) {
1415 return EFI_NOT_FOUND
;
1419 // Send config to Configuration Driver
1421 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
1422 if (ConfigAccess
== NULL
) {
1423 return EFI_UNSUPPORTED
;
1425 Status
= ConfigAccess
->RouteConfig (
1436 Process the user input data.
1438 @param UserInput The user input data.
1439 @param ChangeHighlight Whether need to change the highlight statement.
1441 @retval EFI_SUCESSS This function always return successfully for now.
1446 IN USER_INPUT
*UserInput
,
1447 IN BOOLEAN ChangeHighlight
1451 FORM_BROWSER_STATEMENT
*Statement
;
1453 Status
= EFI_SUCCESS
;
1456 // When Exit from FormDisplay function, one of the below two cases must be true.
1458 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1461 // Remove the last highligh question id, this id will update when show next form.
1463 gCurrentSelection
->QuestionId
= 0;
1466 // First process the Action field in USER_INPUT.
1468 if (UserInput
->Action
!= 0) {
1469 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1470 if (EFI_ERROR (Status
)) {
1475 // Clear the highlight info.
1477 gCurrentSelection
->Statement
= NULL
;
1479 if (UserInput
->SelectedStatement
!= NULL
) {
1480 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1481 ASSERT (Statement
!= NULL
);
1483 // Save the current highlight menu in the menu history data.
1484 // which will be used when later browse back to this form.
1486 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1488 // For statement like text, actio, it not has question id.
1489 // So use FakeQuestionId to save the question.
1491 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1492 mCurFakeQestId
= Statement
->FakeQuestionId
;
1498 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1499 ASSERT (Statement
!= NULL
);
1501 gCurrentSelection
->Statement
= Statement
;
1503 if (ChangeHighlight
) {
1505 // This question is the current user select one,record it and later
1506 // show it as the highlight question.
1508 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1510 // For statement like text, actio, it not has question id.
1511 // So use FakeQuestionId to save the question.
1513 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1514 mCurFakeQestId
= Statement
->FakeQuestionId
;
1520 switch (Statement
->Operand
) {
1521 case EFI_IFR_REF_OP
:
1522 Status
= ProcessGotoOpCode(Statement
, gCurrentSelection
);
1525 case EFI_IFR_ACTION_OP
:
1527 // Process the Config string <ConfigResp>
1529 Status
= ProcessQuestionConfig (gCurrentSelection
, Statement
);
1532 case EFI_IFR_RESET_BUTTON_OP
:
1534 // Reset Question to default value specified by DefaultId
1536 Status
= ExtractDefault (gCurrentSelection
->FormSet
, NULL
, Statement
->DefaultId
, FormSetLevel
, GetDefaultForAll
, NULL
, FALSE
);
1540 switch (Statement
->Operand
) {
1541 case EFI_IFR_STRING_OP
:
1542 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1543 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1544 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1545 FreePool (UserInput
->InputValue
.Buffer
);
1548 case EFI_IFR_PASSWORD_OP
:
1549 if (UserInput
->InputValue
.Buffer
== NULL
) {
1551 // User not input new password, just return.
1556 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1557 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1558 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1559 FreePool (UserInput
->InputValue
.Buffer
);
1561 // Two password match, send it to Configuration Driver
1563 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1564 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1566 // Clean the value after saved it.
1568 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1569 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1571 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1575 case EFI_IFR_ORDERED_LIST_OP
:
1576 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1580 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1583 if (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
) {
1584 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
1595 Display form and wait for user to select one menu option, then return it.
1597 @retval EFI_SUCESSS This function always return successfully for now.
1606 USER_INPUT UserInput
;
1607 FORM_ENTRY_INFO
*CurrentMenu
;
1608 BOOLEAN ChangeHighlight
;
1610 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1613 // Update the menu history data.
1615 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1616 if (CurrentMenu
== NULL
) {
1618 // Current menu not found, add it to the menu tree
1620 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1621 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1622 ASSERT (CurrentMenu
!= NULL
);
1624 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1627 // Find currrent highlight statement.
1629 if (gCurrentSelection
->QuestionId
== 0) {
1631 // Highlight not specified, fetch it from cached menu
1633 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1637 // Evaluate all the Expressions in this Form
1639 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1640 if (EFI_ERROR (Status
)) {
1644 UpdateDisplayFormData ();
1647 // Three possible status maybe return.
1649 // EFI_INVALID_PARAMETER: The input dimension info is not valid.
1650 // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
1651 // and an valid value has return.
1652 // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
1654 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1655 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
1656 FreeDisplayFormData();
1661 // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
1662 // in this case, browser need to change the highlight menu.
1663 // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
1664 // opcode and new valid value has return, browser core need to adjust
1665 // value for this opcode and shows this form again.
1667 ChangeHighlight
= (Status
== EFI_SUCCESS
? TRUE
:FALSE
);
1669 Status
= ProcessUserInput (&UserInput
, ChangeHighlight
);
1671 FreeDisplayFormData();
1677 Functions which are registered to receive notification of
1678 database events have this prototype. The actual event is encoded
1679 in NotifyType. The following table describes how PackageType,
1680 PackageGuid, Handle, and Package are used for each of the
1683 @param PackageType Package type of the notification.
1685 @param PackageGuid If PackageType is
1686 EFI_HII_PACKAGE_TYPE_GUID, then this is
1687 the pointer to the GUID from the Guid
1688 field of EFI_HII_PACKAGE_GUID_HEADER.
1689 Otherwise, it must be NULL.
1691 @param Package Points to the package referred to by the
1692 notification Handle The handle of the package
1693 list which contains the specified package.
1695 @param Handle The HII handle.
1697 @param NotifyType The type of change concerning the
1699 EFI_HII_DATABASE_NOTIFY_TYPE.
1705 IN UINT8 PackageType
,
1706 IN CONST EFI_GUID
*PackageGuid
,
1707 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1708 IN EFI_HII_HANDLE Handle
,
1709 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1712 mHiiPackageListUpdated
= TRUE
;
1718 Update the NV flag info for this form set.
1720 @param FormSet FormSet data structure.
1724 IsNvUpdateRequiredForFormSet (
1725 IN FORM_BROWSER_FORMSET
*FormSet
1729 FORM_BROWSER_FORM
*Form
;
1733 // Not finished question initialization, return FALSE.
1735 if (!FormSet
->QuestionInited
) {
1741 Link
= GetFirstNode (&FormSet
->FormListHead
);
1742 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1743 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1745 RetVal
= IsNvUpdateRequiredForForm(Form
);
1750 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1757 Update the NvUpdateRequired flag for a form.
1759 @param Form Form data structure.
1763 IsNvUpdateRequiredForForm (
1764 IN FORM_BROWSER_FORM
*Form
1768 FORM_BROWSER_STATEMENT
*Statement
;
1770 Link
= GetFirstNode (&Form
->StatementListHead
);
1771 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1772 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1774 if (Statement
->ValueChanged
) {
1778 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1785 Check whether the storage data for current form set is changed.
1787 @param FormSet FormSet data structure.
1789 @retval TRUE Data is changed.
1790 @retval FALSE Data is not changed.
1793 IsStorageDataChangedForFormSet (
1794 IN FORM_BROWSER_FORMSET
*FormSet
1798 FORMSET_STORAGE
*Storage
;
1799 BROWSER_STORAGE
*BrowserStorage
;
1800 CHAR16
*ConfigRespNew
;
1801 CHAR16
*ConfigRespOld
;
1805 ConfigRespNew
= NULL
;
1806 ConfigRespOld
= NULL
;
1809 // Request current settings from Configuration Driver
1811 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1812 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1813 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1814 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1816 BrowserStorage
= Storage
->BrowserStorage
;
1818 if (BrowserStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1822 if (Storage
->ElementCount
== 0) {
1826 StorageToConfigResp (BrowserStorage
, &ConfigRespNew
, Storage
->ConfigRequest
, TRUE
);
1827 StorageToConfigResp (BrowserStorage
, &ConfigRespOld
, Storage
->ConfigRequest
, FALSE
);
1828 ASSERT (ConfigRespNew
!= NULL
&& ConfigRespOld
!= NULL
);
1830 if (StrCmp (ConfigRespNew
, ConfigRespOld
) != 0) {
1834 FreePool (ConfigRespNew
);
1835 ConfigRespNew
= NULL
;
1837 FreePool (ConfigRespOld
);
1838 ConfigRespOld
= NULL
;
1849 Find menu which will show next time.
1851 @param Selection On input, Selection tell setup browser the information
1852 about the Selection, form and formset to be displayed.
1853 On output, Selection return the screen item that is selected
1855 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1856 else, we need to exit current formset.
1858 @retval TRUE Exit current form.
1859 @retval FALSE User press ESC and keep in current form.
1863 IN OUT UI_MENU_SELECTION
*Selection
,
1864 IN BROWSER_SETTING_SCOPE SettingLevel
1867 FORM_ENTRY_INFO
*CurrentMenu
;
1868 FORM_ENTRY_INFO
*ParentMenu
;
1869 BROWSER_SETTING_SCOPE Scope
;
1871 CurrentMenu
= Selection
->CurrentMenu
;
1873 Scope
= FormSetLevel
;
1875 if (CurrentMenu
!= NULL
&& (ParentMenu
= UiFindParentMenu(CurrentMenu
)) != NULL
) {
1877 // we have a parent, so go to the parent menu
1879 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1880 if (SettingLevel
== FormSetLevel
) {
1882 // Find a menu which has different formset guid with current.
1884 while (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1885 CurrentMenu
= ParentMenu
;
1886 if ((ParentMenu
= UiFindParentMenu(CurrentMenu
)) == NULL
) {
1891 if (ParentMenu
!= NULL
) {
1892 Scope
= FormSetLevel
;
1898 Scope
= FormSetLevel
;
1903 // Form Level Check whether the data is changed.
1905 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1906 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1907 if (!ProcessChangedData(Selection
, Scope
)) {
1912 if (ParentMenu
!= NULL
) {
1914 // ParentMenu is found. Then, go to it.
1916 if (Scope
== FormLevel
) {
1917 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1919 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1920 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1921 Selection
->Handle
= ParentMenu
->HiiHandle
;
1924 Selection
->Statement
= NULL
;
1926 Selection
->FormId
= ParentMenu
->FormId
;
1927 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1930 // Clear highlight record for this menu
1932 CurrentMenu
->QuestionId
= 0;
1937 // Current in root page, exit the SendForm
1939 Selection
->Action
= UI_ACTION_EXIT
;
1945 Call the call back function for the question and process the return action.
1947 @param Selection On input, Selection tell setup browser the information
1948 about the Selection, form and formset to be displayed.
1949 On output, Selection return the screen item that is selected
1951 @param Question The Question which need to call.
1952 @param Action The action request.
1953 @param SkipSaveOrDiscard Whether skip save or discard action.
1955 @retval EFI_SUCCESS The call back function excutes successfully.
1956 @return Other value if the call back function failed to excute.
1959 ProcessCallBackFunction (
1960 IN OUT UI_MENU_SELECTION
*Selection
,
1961 IN FORM_BROWSER_STATEMENT
*Question
,
1962 IN EFI_BROWSER_ACTION Action
,
1963 IN BOOLEAN SkipSaveOrDiscard
1967 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1968 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1969 EFI_HII_VALUE
*HiiValue
;
1970 EFI_IFR_TYPE_VALUE
*TypeValue
;
1971 FORM_BROWSER_STATEMENT
*Statement
;
1972 BOOLEAN SubmitFormIsRequired
;
1973 BOOLEAN DiscardFormIsRequired
;
1976 BROWSER_SETTING_SCOPE SettingLevel
;
1978 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
1979 SubmitFormIsRequired
= FALSE
;
1980 SettingLevel
= FormSetLevel
;
1981 DiscardFormIsRequired
= FALSE
;
1983 Status
= EFI_SUCCESS
;
1984 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1986 if (ConfigAccess
== NULL
) {
1990 Link
= GetFirstNode (&Selection
->Form
->StatementListHead
);
1991 while (!IsNull (&Selection
->Form
->StatementListHead
, Link
)) {
1992 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1993 Link
= GetNextNode (&Selection
->Form
->StatementListHead
, Link
);
1996 // if Question != NULL, only process the question. Else, process all question in this form.
1998 if ((Question
!= NULL
) && (Statement
!= Question
)) {
2002 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
2007 // Check whether Statement is disabled.
2009 if (Statement
->Expression
!= NULL
) {
2010 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressDisable
) {
2015 HiiValue
= &Statement
->HiiValue
;
2016 TypeValue
= &HiiValue
->Value
;
2017 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2019 // For OrderedList, passing in the value buffer to Callback()
2021 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2024 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2025 Status
= ConfigAccess
->Callback (
2028 Statement
->QuestionId
,
2033 if (!EFI_ERROR (Status
)) {
2035 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2037 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
2038 switch (ActionRequest
) {
2039 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2040 DiscardFormIsRequired
= TRUE
;
2041 gResetRequired
= TRUE
;
2045 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2046 SubmitFormIsRequired
= TRUE
;
2050 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2051 DiscardFormIsRequired
= TRUE
;
2055 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2056 SubmitFormIsRequired
= TRUE
;
2057 SettingLevel
= FormLevel
;
2061 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2062 DiscardFormIsRequired
= TRUE
;
2063 SettingLevel
= FormLevel
;
2067 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2068 SubmitFormIsRequired
= TRUE
;
2069 SettingLevel
= FormLevel
;
2072 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2073 DiscardFormIsRequired
= TRUE
;
2074 SettingLevel
= FormLevel
;
2083 // According the spec, return value from call back of "changing" and
2084 // "retrieve" should update to the question's temp buffer.
2086 if (Action
== EFI_BROWSER_ACTION_CHANGING
|| Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2087 SetQuestionValue(Selection
->FormSet
, Selection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2091 // According the spec, return fail from call back of "changing" and
2092 // "retrieve", should restore the question's value.
2094 if (Action
== EFI_BROWSER_ACTION_CHANGING
|| Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2095 GetQuestionValue(Selection
->FormSet
, Selection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2098 if (Status
== EFI_UNSUPPORTED
) {
2100 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2102 Status
= EFI_SUCCESS
;
2107 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2108 SubmitForm (Selection
->FormSet
, Selection
->Form
, SettingLevel
);
2111 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2112 DiscardForm (Selection
->FormSet
, Selection
->Form
, SettingLevel
);
2116 FindNextMenu (Selection
, SettingLevel
);
2123 Call the retrieve type call back function for one question to get the initialize data.
2125 This function only used when in the initialize stage, because in this stage, the
2126 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2128 @param ConfigAccess The config access protocol produced by the hii driver.
2129 @param Statement The Question which need to call.
2131 @retval EFI_SUCCESS The call back function excutes successfully.
2132 @return Other value if the call back function failed to excute.
2135 ProcessRetrieveForQuestion (
2136 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2137 IN FORM_BROWSER_STATEMENT
*Statement
2141 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2142 EFI_HII_VALUE
*HiiValue
;
2143 EFI_IFR_TYPE_VALUE
*TypeValue
;
2145 Status
= EFI_SUCCESS
;
2146 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2148 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
2149 return EFI_UNSUPPORTED
;
2152 HiiValue
= &Statement
->HiiValue
;
2153 TypeValue
= &HiiValue
->Value
;
2154 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2156 // For OrderedList, passing in the value buffer to Callback()
2158 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2161 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2162 Status
= ConfigAccess
->Callback (
2164 EFI_BROWSER_ACTION_RETRIEVE
,
2165 Statement
->QuestionId
,
2174 The worker function that send the displays to the screen. On output,
2175 the selection made by user is returned.
2177 @param Selection On input, Selection tell setup browser the information
2178 about the Selection, form and formset to be displayed.
2179 On output, Selection return the screen item that is selected
2182 @retval EFI_SUCCESS The page is displayed successfully.
2183 @return Other value if the page failed to be diplayed.
2188 IN OUT UI_MENU_SELECTION
*Selection
2193 EFI_HANDLE NotifyHandle
;
2194 FORM_BROWSER_STATEMENT
*Statement
;
2195 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2197 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2200 // Register notify for Form package update
2202 Status
= mHiiDatabase
->RegisterPackageNotify (
2204 EFI_HII_PACKAGE_FORMS
,
2207 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2210 if (EFI_ERROR (Status
)) {
2215 // Initialize current settings of Questions in this FormSet
2217 InitializeCurrentSetting (Selection
->FormSet
);
2220 // Initilize Action field.
2222 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2225 // Clean the mCurFakeQestId value is formset refreshed.
2231 // IFR is updated, force to reparse the IFR binary
2233 if (mHiiPackageListUpdated
) {
2234 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2235 mHiiPackageListUpdated
= FALSE
;
2240 // Initialize Selection->Form
2242 if (Selection
->FormId
== 0) {
2244 // Zero FormId indicates display the first Form in a FormSet
2246 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2248 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2249 Selection
->FormId
= Selection
->Form
->FormId
;
2251 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2254 if (Selection
->Form
== NULL
) {
2256 // No Form to display
2258 Status
= EFI_NOT_FOUND
;
2263 // Check Form is suppressed.
2265 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2266 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2268 // Form is suppressed.
2270 gBrowserStatus
= BROWSER_FORM_SUPPRESS
;
2271 Status
= EFI_NOT_FOUND
;
2277 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2278 // for each question with callback flag.
2279 // New form may be the first form, or the different form after another form close.
2281 if ((ConfigAccess
!= NULL
) &&
2282 ((Selection
->Handle
!= mCurrentHiiHandle
) ||
2283 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2284 (Selection
->FormId
!= mCurrentFormId
))) {
2286 // Keep current form information
2288 mCurrentHiiHandle
= Selection
->Handle
;
2289 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2290 mCurrentFormId
= Selection
->FormId
;
2292 Status
= ProcessCallBackFunction (Selection
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2293 if (EFI_ERROR (Status
)) {
2298 // IFR is updated during callback of open form, force to reparse the IFR binary
2300 if (mHiiPackageListUpdated
) {
2301 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2302 mHiiPackageListUpdated
= FALSE
;
2308 // Load Questions' Value for display
2310 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2311 if (EFI_ERROR (Status
)) {
2316 // IFR is updated during callback of read value, force to reparse the IFR binary
2318 if (mHiiPackageListUpdated
) {
2319 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2320 mHiiPackageListUpdated
= FALSE
;
2327 Status
= DisplayForm ();
2328 if (EFI_ERROR (Status
)) {
2333 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2335 Statement
= Selection
->Statement
;
2336 if (Statement
!= NULL
) {
2337 if ((ConfigAccess
!= NULL
) &&
2338 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2339 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2340 Status
= ProcessCallBackFunction(Selection
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2341 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2343 // Process dynamic update ref opcode.
2345 if (!EFI_ERROR (Status
)) {
2346 Status
= ProcessGotoOpCode(Statement
, Selection
);
2350 // Callback return error status or status return from process goto opcode.
2352 if (EFI_ERROR (Status
)) {
2354 // Cross reference will not be taken
2356 Selection
->FormId
= Selection
->Form
->FormId
;
2357 Selection
->QuestionId
= 0;
2361 if (!EFI_ERROR (Status
) && Statement
->Operand
!= EFI_IFR_REF_OP
) {
2362 ProcessCallBackFunction(Selection
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2368 // Check whether Exit flag is TRUE.
2370 if (gExitRequired
) {
2371 switch (gBrowserSettingScope
) {
2373 Selection
->Action
= UI_ACTION_EXIT
;
2378 FindNextMenu (Selection
, gBrowserSettingScope
);
2385 gExitRequired
= FALSE
;
2389 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2390 // for each question with callback flag.
2392 if ((ConfigAccess
!= NULL
) &&
2393 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2394 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2395 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2396 (Selection
->FormId
!= mCurrentFormId
))) {
2398 Status
= ProcessCallBackFunction (Selection
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2399 if (EFI_ERROR (Status
)) {
2403 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2407 // Reset current form information to the initial setting when error happens or form exit.
2409 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2410 mCurrentHiiHandle
= NULL
;
2411 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2416 // Unregister notify for Form package update
2418 mHiiDatabase
->UnregisterPackageNotify (